目标
Parcel 可以同时以多种不同的方式编译您的源代码。这些被称为 **目标**。例如,您可以拥有一个针对较新浏览器的“现代”目标和一个针对较旧浏览器的“传统”目标。
入口
#“入口”是 Parcel 在构建您的源代码时开始的第一个文件。它们可以在 CLI 上指定,也可以使用 package.json 中的 source
字段指定。
$ parcel <entries>
#一个或多个入口文件可以在 CLI 上指定为任何 Parcel 命令。
$ parcel src/a.html src/b.html
入口可以指定为通配符以一次匹配多个文件。请确保将通配符用单引号括起来,以确保通配符不会被您的 shell 解析并直接传递给 Parcel。这确保了 Parcel 可以自动拾取与通配符匹配的最新创建的文件,而无需重新启动。
$ parcel './src/*.html'
入口也可以是目录,在这种情况下,必须存在包含 source
字段的 package.json
文件。有关详细信息,请参见下文。
package.json#source
#package.json 中的 source
字段可以指定一个或多个入口文件。
{
"source": "src/index.html"
}
{
"source": ["src/a.html", "src/b.html"]
}
package.json#targets.*.source
#package.json 中声明的任何目标内的 source
字段可以指定特定于该目标的一个或多个入口文件。例如,您可以同时构建您的前端和后端,或构建您的桌面和移动应用程序。有关配置目标的详细信息,请参见下文。
{
"targets": {
"frontend": {
"source": "app/index.html"
},
"backend": {
"source": "api/index.js"
}
}
}
目标
#Parcel 遵循每个解析的入口中的依赖项来构建您的源代码以用于一个或多个目标。目标指定输出目录或文件路径,以及有关如何编译代码的信息。
默认情况下,Parcel 包含一个隐式目标,它输出到 dist
文件夹中。这可以使用 --dist-dir
CLI 选项覆盖。
$ parcel build src/index.html --dist-dir output
输出目录也可以使用 package.json 中的 targets
字段指定。这将覆盖 --dist-dir
CLI 选项。
{
"targets": {
"default": {
"distDir": "./output"
}
}
}
环境
#除了输出位置之外,目标还指定有关代码将在其中运行的“环境”的信息。它们告诉 Parcel 为哪种类型的环境构建(例如浏览器或 Node.js),以及支持的每个引擎的版本。这会影响 Parcel 如何编译代码,包括要转译的语法。
package.json#browserslist
#对于浏览器目标,package.json 中的 browserslist
字段可用于指定支持的浏览器。您可以通过使用统计数据或特定浏览器的版本范围来查询。有关更多信息,请参见 browserslist 文档。
{
"browserslist": "> 0.5%, last 2 versions, not dead"
}
package.json#engines
#对于 Node.js 和其他目标,package.json 中的 engines
字段可用于指定支持的版本。引擎使用 semver 范围指定。
{
"engines": {
"node": ">= 12"
}
}
隐式环境
#当一个文件依赖于另一个文件时,环境将从其父级继承。但是,您依赖于资产的方式可能会更改环境的某些属性。例如,当依赖于服务工作者时,环境会自动更改为服务工作者上下文,以便代码被适当地编译。
navigator.serviceWorker.register(new URL('service-worker.js', import.meta.url));
差异化捆绑
#“差异化捆绑”是指为不同目标提供代码的多个版本,并允许浏览器选择最优版本进行下载。当您在 HTML 文件中使用 <script type="module">
元素时,并且环境指定的某些浏览器不支持原生 ES 模块,Parcel 将自动生成 <script nomodule>
回退。
<script type="module" src="app.js"></script>
被编译为
<script type="module" src="app.c9a6fe.js"></script>
<script nomodule src="app.f7d631.js"></script>
这允许支持 ES 模块的现代浏览器下载更小的捆绑包,同时仍然使用回退支持传统浏览器。这可以通过避免转译现代 JavaScript 语法(如类、箭头函数、async/await 等)来显着减少捆绑包大小并提高加载时间。
这会根据您的浏览器目标自动发生,如 package.json 中的 "browserslist"
字段中所声明。如果未声明 browserslist
,或者所有浏览器目标都原生支持 ES 模块,则不会生成 nomodule
回退。
多个目标
#您可能有多个目标,以便同时为多个不同的环境构建您的源代码。例如,您可以为应用程序拥有“现代”和“传统”目标,或者为库拥有 ES 模块和 CommonJS 目标(参见下文)。
目标使用 package.json 中的 targets
字段配置。每个目标都有一个名称,作为 targets
字段下的键指定,以及一个关联的配置对象。例如,每个目标内的 engines
字段可用于自定义其编译到的环境。
{
"targets": {
"modern": {
"engines": {
"browsers": "Chrome 80"
}
},
"legacy": {
"engines": {
"browsers": "> 0.5%, last 2 versions, not dead"
}
}
}
}
当指定多个目标时,输出将默认写入 dist/${targetName}
(例如,在上面的示例中为 dist/modern
和 dist/legacy
)。这可以使用每个目标中的 distDir
字段自定义。或者,如果目标只有一个入口,则可以使用对应于目标名称的顶级 package.json 字段为输出指定一个确切的文件名。
{
"modern": "dist/modern.js",
"legacy": "dist/legacy.js",
"targets": {
"modern": {
"engines": {
"browsers": "Chrome 80"
}
},
"legacy": {
"engines": {
"browsers": "> 0.5%, last 2 versions, not dead"
}
}
}
}
库目标
#Parcel 包含一些用于构建库的内置目标。这些包括 main
、module
、browser
和 types
字段。
{
"name": "my-library",
"version": "1.0.0",
"source": "src/index.js",
"main": "dist/main.js",
"module": "dist/module.js",
"types": "dist/types.d.ts"
}
库目标默认情况下不会捆绑来自 node_modules
的依赖项。此外,库的最小化默认情况下处于禁用状态。这些可以使用 targets
字段中的相应选项覆盖(参见下文)。作用域提升不能为库目标禁用。
库目标会根据目标自动输出原生 ES 模块或 CommonJS。
main
– 默认情况下,输出 CommonJS。如果使用.mjs
扩展名,或者指定了"type": "module"
字段,则改为输出 ES 模块。module
– 输出 ES 模块。browser
–main
字段的浏览器特定覆盖。输出 CommonJS。
如果存在 browser
目标,或者如果指定了 engines.node
并且未指定浏览器目标,则 main
和 module
默认情况下会为 Node 环境编译。否则,它们默认情况下会为浏览器环境编译。这可以使用目标配置中的 context
选项覆盖(参见下文)。
要使 Parcel 忽略这些字段中的一个,请在 targets
字段中指定 false
。
{
"main": "unrelated.js",
"targets": {
"main": false
}
}
有关使用 Parcel 构建库的介绍,请参见 使用 Parcel 构建库。
目标选项
#context
#'node' | 'browser' | 'web-worker' | 'service-worker' | 'worklet' | 'electron-main' | 'electron-renderer'
context
属性定义要构建的哪种类型的环境。这告诉 Parcel 哪些环境特定的 API 可用,例如 DOM、Node 文件系统 API 等。
对于内置库目标(例如 main
和 module
),context
会自动推断。有关更多详细信息,请参见上面的 库目标。
engines
#覆盖为此目标定义的顶级 package.json#engines
和 browserslist
字段中的引擎。目标内的 engines.browsers
字段可以像 browserslist
一样使用。有关更多信息,请参见上面的 环境 和 多个目标。
outputFormat
#'global' | 'esmodule' | 'commonjs'
定义要输出的哪种类型的模块。
global
– 一个经典脚本,可以在浏览器中的<script>
标签中加载。库目标不支持。esmodule
– 使用import
和export
语句的 ES 模块。可以在浏览器中的<script type="module">
标签中加载,也可以由 Node.js 或其他捆绑器加载。commonjs
– 使用require
和module.exports
的 CommonJS 模块。可以由 Node.js 或其他捆绑器加载。
对于内置库目标(例如 main
和 module
),outputFormat
会自动推断。目标的顶级 package.json 字段中定义的文件扩展名也可能影响输出格式。有关更多详细信息,请参见上面的 库目标。
scopeHoist
#启用或禁用作用域提升。默认情况下,作用域提升在生产构建中启用。--no-scope-hoist
CLI 标志可用于在运行 parcel build
时禁用作用域提升。作用域提升也可以通过在目标配置中设置 scopeHoist
选项来禁用。
isLibrary
#当设置为 true
时,目标将被视为一个库,该库将发布到 npm 并由另一个工具使用,而不是直接在浏览器或其他目标环境中使用。当为 true
时,outputFormat
选项必须为 esmodule
或 commonjs
,并且 scopeHoist
不能设置为 false
。
对于内置库目标(例如 main
和 module
),这将自动设置为 true
。有关更多详细信息,请参见上面的 库目标。
optimize
#启用或禁用优化(例如最小化)。确切的行为由插件决定。默认情况下,优化在生产构建(parcel build
)期间启用,库目标除外。这可以使用 --no-optimize
CLI 标志或目标配置中的 optimize
选项覆盖。
includeNodeModules
#确定是捆绑 node_modules
还是将其视为外部。默认情况下,浏览器目标为 true
,库目标为 false
。可能的值是
-
false
– 不包含node_modules
中的任何文件。 -
一个数组 – 要包含的包名称列表。在以下示例中,仅
react
被捆绑。node_modules
中的所有其他文件都被排除在外。{
"targets": {
"main": {
"includeNodeModules": ["react"]
}
}
} -
一个对象 – 包名称到布尔值的映射。如果未列出包,则将其包含在内。在以下示例中,所有
node_modules
除了 react 被捆绑。{
"targets": {
"main": {
"includeNodeModules": {
"react": false
}
}
}
}
sourceMap
#启用或禁用源映射,并设置源映射选项。默认情况下,源映射已启用。可以使用 `--no-source-maps` CLI 标志或将目标配置中的 `sourceMap` 选项设置为 `false` 来覆盖此设置。
`sourceMap` 选项还接受包含以下选项的对象。
- `inline` - 是否将源映射作为数据 URL 内联到捆绑包中,而不是将其链接为单独的输出文件。
- `inlineSources` - 是否将原始源代码内联到源映射中,而不是从 `sourceRoot` 加载它们。在为生产环境构建浏览器目标时,默认情况下将其设置为 `true`。
- `sourceRoot` - 加载原始源代码的 URL。在使用内置 Parcel 开发服务器进行开发时,此选项会自动设置。否则,它默认为从项目根目录到捆绑包的相对路径。
source
#覆盖 `package.json` 中目标的顶级 `source` 字段。这允许每个目标具有不同的条目。有关更多详细信息,请参阅 package.json#targets.*.source。
distDir
#设置将此目标中编译的捆绑包写入的位置。默认情况下,如果只给出一个目标,则为 `dist`,如果给出多个目标,则为 `dist/${targetName}`。有关更多详细信息,请参阅 目标。
publicUrl
#设置此捆绑包在运行时加载的基准 URL。捆绑包相对于 `distDir` 的相对路径将自动附加。`publicUrl` 可以是完全限定的 URL(例如 `https://some-cdn.com/`)或绝对路径(例如 `/public`),如果捆绑包从与您的网站相同的域加载。
默认情况下,`publicUrl` 为 `/`。如果您的 HTML 文件和其他资产部署到相同的位置,这是一个很好的默认值。如果您将资产部署到不同的位置,则可能需要设置 `publicUrl`。也可以使用 `--public-url` CLI 选项设置公共 URL。
在大多数情况下,捆绑包使用从父捆绑包到子捆绑包的相对路径加载。这允许将部署移动到新位置而无需重新构建(例如,将暂存构建提升到生产环境)。当相对路径不可用时(例如在 HTML 中),将使用 `publicUrl`。