插件
Parcel 开箱即用于许多项目,无需配置。但如果您想要更多控制,或需要扩展或覆盖 Parcel 的默认设置,可以通过在项目中创建 .parcelrc
文件来实现。
Parcel 的设计非常模块化。Parcel 核心本身几乎不特定于构建 JavaScript 或网页 – 所有行为都通过插件指定。对于构建的每个阶段都有特定的插件类型,因此您几乎可以自定义所有内容。
.parcelrc
#Parcel 配置在 .parcelrc
文件中指定。它使用 JSON5 编写,类似于 JSON,但支持注释、未引用的键、尾随逗号和其他功能。
扩展配置
#Parcel 的默认配置在 @parcel/config-default
中指定。大多数情况下,您希望在自己的 Parcel 配置中扩展它。要执行此操作,请在 .parcelrc
中使用 extends
字段。
{
"extends": "@parcel/config-default"
}
您还可以通过传递数组来扩展多个配置。配置按指定顺序合并。
{
"extends": ["@parcel/config-default", "@company/parcel-config"]
}
您还可以使用相对路径引用项目中的另一个配置。
{
"extends": "../.parcelrc"
}
扩展的配置也可以扩展其他配置,从而形成配置链。
Glob 映射
#.parcelrc
中的许多字段(如 transformers
或 packagers
)使用 glob 到插件名称的对象映射。这允许您按文件扩展名、文件路径甚至特定文件名配置 Parcel 的行为。Glob 相对于包含 .parcelrc
的目录进行匹配。
Glob 映射中字段的顺序定义了在测试文件名时的优先级。这允许您为项目中的特定文件(例如特定目录中的文件)配置不同的行为。
{
"transformers": {
"icons/*.svg": ["highest-priority"],
"*.svg": ["lowest-priority"]
}
}
在这里,如果我们要为文件 icons/home.svg
查找转换器,我们将逐步遍历 glob 直到找到匹配项,这将是 icons/*.svg
。我们永远不会到达 *.svg
。
检查完当前配置中的所有 glob 后,Parcel 会回退到任何扩展配置中定义的 glob。
管道线
#.parcelrc
中的许多字段(如 transformers
、optimizers
和 reporters
)接受按顺序运行的插件数组。这些称为管道线。
如果您想定义一个优先级更高的管道线,该管道线扩展了优先级较低的管道线而不是覆盖它,可以使用特殊的 "..."
语法来实现。在管道线中添加此项以将下一个优先级的管道线嵌入其中。您可以在开头、结尾甚至中间插入它,这使您可以完全控制管道线的扩展方式。
{
"transformers": {
"icons/*.svg": ["@company/parcel-transformer-svg-icons", "..."],
"*.svg": ["@parcel/transformer-svg"]
}
}
在上面的示例中,处理 icons/home.svg
时,我们首先运行 @company/parcel-transformer-svg-icons
,然后运行 @parcel/transformer-svg
。
这也适用于已扩展的配置。如果使用 "..."
,并且在当前配置中没有定义优先级较低的管道线,Parcel 将回退到扩展配置中定义的管道线。
由于 @parcel/transformer-svg
包含在默认配置中,上面的示例可以重写如下:
{
"extends": "@parcel/config-default",
"transformers": {
"icons/*.svg": ["@company/parcel-transformer-svg-icons", "..."]
}
}
命名管道线
#除了基于 glob 的管道线,Parcel 还支持命名管道线,这使您可以以多种方式导入同一个文件。命名管道线在 .parcelrc
中定义,就像普通管道线一样,但在 glob 开头包含 URL 方案。
例如,默认情况下,正常导入图像会返回外部文件的 URL,但您可以使用默认 Parcel 配置中定义的 data-url:
命名管道线将其内联为数据 URL。有关详细信息,请参见捆绑包内联。
.logo {
background: url(data-url:./logo.png);
}
您还可以定义自己的命名管道线。例如,您可以定义一个 arraybuffer:
命名管道线,允许您将文件作为 ArrayBuffer 导入。在此示例中,*
glob 匹配任何文件,但您也可以使用更具体的 glob。使用 "..."
语法允许 Parcel 按照通常的方式处理文件,然后再运行 parcel-transformer-arraybuffer
插件将其转换为 ArrayBuffer。
{
"extends": "@parcel/config-default",
"transformers": {
"arraybuffer:*": ["...", "parcel-transformer-arraybuffer"]
}
}
import buffer from "arraybuffer:./file.png";
命名管道线支持转换器和优化器管道线。对于转换器,管道线在引用资源的依赖项中指定。对于优化器,它继承自捆绑包的入口资源。
插件
#Parcel 支持许多不同类型的插件,这些插件在构建过程中执行特定任务。插件在 .parcelrc
中使用其 NPM 包名称引用。
转换器
#转换器插件转换单个资源,以编译它、发现依赖项或将其转换为不同的格式。它们在 .parcelrc
中使用 glob 映射配置。多个转换器可以按系列在同一资源上运行,并支持命名管道线,以允许在同一项目中以多种不同方式编译同一文件。可以使用 "..."
语法扩展文件的默认转换器。
{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["...", "@parcel/transformer-svg-jsx"]
}
}
编译资源时,其文件类型可能会更改。例如,编译 TypeScript 时,资源的类型从 ts
或 tsx
更改为 js
。发生这种情况时,Parcel 重新评估应如何进一步处理资源,并通过匹配 .js
文件的管道线运行它。
{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
}
}
一旦转换器将资源类型更改为不再匹配当前管道线,该资源将被放入不同的管道线。如果新资源类型没有匹配的管道线,则转换完成。当前管道线中稍后定义的转换器将不会运行。
解析器
#解析器插件负责将依赖说明符转换为将由转换器处理的完整文件路径。有关其工作原理的详细信息,请参见依赖项解析。解析器在 .parcelrc
中使用插件名称数组配置。解析过程遍历插件列表,直到其中一个返回结果。
可以使用 "..."
语法扩展默认解析器。这允许您覆盖某些依赖项的解析,同时对其他依赖项回退到默认值。通常,您希望在运行默认解析器之前添加自定义解析器。
{
"extends": "@parcel/config-default",
"resolvers": ["@company/parcel-resolver", "..."]
}
如果省略 "..."
,您的解析器必须能够处理所有依赖项,否则解析将失败。
捆绑器(实验性)
#捆绑器插件负责将资源分组到捆绑包中。可以通过在 .parcelrc
中指定插件名称来配置捆绑器。
{
"extends": "@parcel/config-default",
"bundler": "@company/parcel-bundler"
}
Note: Bundler plugins are experimental, and subject to change, even between minor updates.
Runtimes (experimental)
#Runtime plugins allow you to inject assets into bundles. They can be configured using an array of plugin names in .parcelrc
. All runtime plugins in this list are run over each bundle. The "..."
syntax can be used to extend the default runtimes.
{
"extends": "@parcel/config-default",
"runtimes": ["@company/parcel-runtime", "..."]
}
If "..."
is omitted, the default runtimes will not be run. This will probably break things, as many Parcel features rely on the default runtimes.
Note: Runtime plugins are experimental, and subject to change, even between minor updates.
Namers
#Namer plugins determine the output filename for a bundle. They are configured using an array of plugin names in .parcelrc
. Naming proceeds through the list of namers until one of them returns a result.
The "..."
syntax can be used to extend the default namers. This allows you to override naming of certain bundles, but fall back to the default for others. Generally, you'll want to add your custom namers before running the default ones.
{
"extends": "@parcel/config-default",
"namers": ["@company/parcel-namer", "..."]
}
If "..."
is omitted, your namer must be able to handle naming all bundles or the build will fail.
Packagers
#Packager plugins are responsible for combining all of the assets in a bundle together into an output file. They are configured using a glob map in .parcelrc
. Globs are matched against the output filename of a bundle. A single packager plugin may be configured to run per bundle.
{
"extends": "@parcel/config-default",
"packagers": {
"*.{jpg,png}": "@company/parcel-packager-image-sprite"
}
}
Optimizers
#Optimizer plugins are similar to transformers but they accept a bundle instead of a single asset. They are configured using a glob map in .parcelrc
. Multiple optimizers may run in series over the same bundle using pipelines, and named pipelines are supported to allow compiling the same bundle in multiple different ways within the same project. The "..."
syntax can be used to extend the default optimizers for a bundle.
{
"extends": "@parcel/config-default",
"optimizers": {
"*.js": ["@parcel/optimizer-esbuild"]
}
}
Compressors
#Compressor plugins are used when writing a final bundle to disk and may compress or encode it in some way (e.g. Gzip). They are configured using a glob map in .parcelrc
. Multiple compressors may run over the same bundle using pipelines. Each compressor plugin produces an additional file to be written in parallel, for example bundle.js
, bundle.js.gz
and bundle.js.br
. The "..."
syntax can be used to extend the default compressors for a bundle.
{
"extends": "@parcel/config-default",
"compressors": {
"*.{js,html,css}": [
"...",
"@parcel/compressor-gzip",
"@parcel/compressor-brotli"
]
}
}
Reporters
#Reporter plugins receive events from Parcel as they happen throughout the build process. For example, reporters may write status information to stdout, run a dev server, or generate a bundle analysis report at the end of a build. Reporters are configured using an array of package names in .parcelrc
. All reporters in this list are run for each build event. The "..."
syntax can be used to extend the default reporters.
{
"extends": "@parcel/config-default",
"reporters": ["...", "@parcel/reporter-bundle-analyzer"]
}
Reporters that you use infrequently may also be specified on the CLI using the --reporter
option, or via the API using the additionalReporters
option. Reporters specified in .parcelrc
always run.
本地插件
#大多数 Parcel 插件都是 NPM 包。这意味着它们有一个 package.json
,声明了它们兼容的 Parcel 版本,以及它们可能具有的任何依赖项。它们还必须遵循一个命名系统以确保清晰度。
通常,Parcel 插件会发布到 NPM 注册表,或内部公司注册表(例如 Artifactory)。这鼓励插件在社区中共享,或在公司内部的项目间共享,以避免重复。
然而,在开发插件时,直接在项目中运行它而不首先发布可能会很有用。有几种方法可以做到这一点。
相对文件路径
#插件可以作为相对路径从使用它们的 .parcelrc
配置文件引用。这些可以是 CommonJS 或 ESM 模块,通过 .mjs
或 .cjs
扩展名,或最近的 package.json 中的 "type": "module"
字段来确定(与 Node 加载模块的方式相同)。
{
"extends": "@parcel/config-default",
"transformers": {
"*.js": ["./my-local-plugin.mjs", "..."]
}
}
Yarn 和 NPM 工作空间
#使用本地插件的另一种方法是通过 Yarn 工作空间或 NPM 工作空间设置单一仓库。这允许您像依赖已发布的包一样依赖仓库内的其他包。要做到这一点,请设置如下项目结构:
project
├── .parcelrc
├── package.json
└── packages
├── app
│ └── package.json
└── parcel-transformer-foo
├── package.json
└── src
└── FooTransformer.js
在您的根 package.json
中,使用 workspaces
字段引用您的包。
{
"name": "my-project",
"private": true,
"workspaces": ["packages/*"]
}
然后,在您的 .parcelrc
中,您可以像引用已发布的包一样引用 parcel-transformer-foo
。每当您更新插件的代码时,Parcel 都会重新构建您的项目。
您还可以选择将应用程序保留在根目录(例如在 src
文件夹中),而不是在 packages/app
中。
link:
协议
#Yarn 支持使用 link:
协议定义依赖项,以引用本地目录作为包。例如,您可以设置如下项目结构:
project
├── .parcelrc
├── package.json
├── src
│ └── index.html
└── parcel-transformer-foo
├── package.json
└── src
└── FooTransformer.js
在您的根 package.json 中,您可以使用 link:
协议定义对 parcel-transformer-foo
包的依赖。
{
"name": "my-project",
"dependencies": {
"parcel": "^2.0.0",
"parcel-transformer-foo": "link:./parcel-transformer-foo"
}
}
然后,在您的 .parcelrc
中,您可以像引用已发布的包一样引用 parcel-transformer-foo
。每当您更新插件的代码时,Parcel 都会重新构建您的项目。