生产

Parcel 的生产模式会自动打包和优化您的应用程序以供生产使用。可以使用 parcel build 命令运行它。

parcel build src/index.html

大小优化

#

Parcel 包含许多旨在减小包大小的优化,包括自动缩小、摇树优化、图像优化等等。

缩小

#

Parcel 内置了 JavaScript、CSS、HTML 和 SVG 的缩小器。缩小通过删除空格、将变量重命名为更短的名称以及许多其他优化来减小输出包的文件大小。

默认情况下,在使用 parcel build 命令时会启用缩小。如果需要,可以使用 --no-optimize CLI 标志禁用缩小和其他优化。

Parcel 使用 SWC 来缩小 JavaScript,lightningcss 用于 CSS,htmlnano 用于 HTML,以及 svgo 用于 SVG。如果需要,可以使用 .terserrc.htmlnanorcsvgo.config.json 配置文件来配置这些工具。有关更多详细信息,请参阅 JavaScriptCSSHTMLSVG 的文档。

摇树优化

#

在生产构建中,Parcel 会静态分析每个模块的导入和导出,并删除所有未使用的部分。这被称为“摇树优化”或“死代码消除”。摇树优化支持静态和动态 import()、CommonJS 和 ES 模块,甚至跨语言支持 CSS 模块。

Parcel 还会尽可能将模块连接到单个作用域中,而不是将每个模块包装在单独的函数中。这被称为“作用域提升”。这有助于使缩小更有效,并且通过使模块之间的引用成为静态引用而不是动态对象查找来提高运行时性能。

有关使摇树优化更有效的技巧,请参阅 作用域提升 文档。

开发分支移除

#

parcel build 会自动将 NODE_ENV 环境变量设置为 production。此环境变量通常用于库中启用仅限开发的调试功能,这些功能可以在生产构建中被剥离以减小包大小。Parcel 会内联此环境变量并优化比较以删除死分支。

您也可以在自己的代码中利用此功能。例如,您可以使用 if 语句来检查 NODE_ENV 环境变量。

if (process.env.NODE_ENV !== 'production') {
// Only runs in development and will be stripped in production builds.
}

有关环境变量内联的更多详细信息,请参阅 Node 模拟文档

图像优化

#

Parcel 支持调整图像大小、转换图像和优化图像。您可以在 HTML、CSS 或 JavaScript 中引用图像时使用查询参数来指定图像应转换为哪种格式和大小。您可以从同一个源图像请求多个大小或格式,这有助于有效地支持不同类型的设备或浏览器。

<picture>
<source type="image/webp" srcset="image.jpg?as=webp&width=400, image.jpg?as=webp&width=800 2x">
<source type="image/jpeg" srcset="image.jpg?width=400, image.jpg?width=800 2x">
<img src="image.jpg?width=400" width="400">
</picture>

调整图像大小和转换图像在开发模式和生产模式下都会发生,因此您也可以使用正确的图像尺寸和格式进行测试。有关更多详细信息,请参阅 图像转换器 文档。

Parcel 默认情况下在生产模式下还包括 JPEG 和 PNG 的无损图像优化,这会减小图像大小而不会影响其质量。这不需要任何查询参数或配置即可使用。但是,由于优化是无损的,因此与使用 quality 查询参数或使用 WebP 或 AVIF 等现代格式相比,可能的大小减少幅度较小。

差异化打包

#

Parcel 会自动生成一个包含现代 JavaScript 语法的 <script type="module">,以及一个在必要时为旧版浏览器提供回退的 <script nomodule>。这通过避免对类、async/await 等功能进行转译来减小大多数用户的包大小。有关更多详细信息,请参阅目标文档中的 差异化打包

压缩

#

Parcel 支持使用 GzipBrotli 压缩包。虽然许多服务器会动态压缩数据,但其他服务器要求您提前上传预压缩的有效负载。这还可以实现更好的压缩,这对于每个网络请求来说都太慢了。

由于并非每个人都需要它,因此默认情况下不会启用压缩。要启用它,请将 @parcel/compressor-gzip 和/或 @parcel/compressor-brotli 添加到您的 .parcelrc 中。

yarn add @parcel/compressor-gzip @parcel/compressor-brotli --dev
.parcelrc
{
"compressors": {
"*.{html,css,js,svg,map}": [
"...",
"@parcel/compressor-gzip",
"@parcel/compressor-brotli"
]
}
}

现在,您将在原始未压缩包旁边获得一个 .gz 文件和一个 .br 文件。如果您有比上面示例中列出的更多基于文本的文件类型,则需要相应地扩展通配符。

如果您不需要未压缩的包,也可以从上面的示例中删除 "..." 以仅输出压缩文件。例如,要仅输出 .gz 文件,可以使用以下配置

.parcelrc
{
"compressors": {
"*.{html,css,js,svg,map}": ["@parcel/compressor-gzip"]
}
}

缓存优化

#

Parcel 包含几个与浏览器和 CDN 缓存相关的优化,包括内容哈希、包清单和共享包。

内容哈希

#

Parcel 会自动在所有输出文件的名称中包含内容哈希,这使得长期浏览器缓存成为可能。每当包的内容发生更改时,文件名中包含的哈希值都会更新,从而触发 CDN 和浏览器缓存的失效。

默认情况下,所有包都包含内容哈希,除了条目和某些需要名称保持稳定的依赖项类型。例如,服务工作者需要稳定的文件名才能正常工作,而 HTML 中的 <a> 标签引用的是用户可读的 URL。

您也可以使用 --no-content-hash CLI 标志禁用内容哈希。请注意,名称仍然会包含哈希值,但它不会在每次构建时都更改。您可以使用 命名器 插件完全自定义包命名。

级联失效

#

Parcel 在每个条目包中使用清单来避免在许多情况下出现 级联失效 问题。此清单包含一个稳定的包 ID 到最终内容哈希文件名的映射。当一个包需要引用另一个包时,它使用包 ID 而不是内容哈希名称。这意味着当一个包更新时,只有该包和条目需要在浏览器缓存中失效,而中间包不会更改。这提高了跨部署的缓存命中率。

当条目包的大小超过阈值(默认情况下为 100 KB)时,清单会自动拆分为一个单独的包。由于清单在每次构建时都会更改,因此即使条目中没有其他代码更改,这也避免了使整个条目包失效。这有助于减少用户需要下载以接收更新的字节数。可以在项目根目录的 package.json 文件中配置将清单拆分为其自身包的尺寸阈值。它在缩小之前以字节为单位定义。

package.json
{
"@parcel/runtime-js": {
"splitManifestThreshold": 10000
}
}

共享包

#

在生产构建中,Parcel 会自动优化应用程序中的包图以减少重复并提高可缓存性。当应用程序的多个部分依赖于相同的公共模块时,它们会自动去重到一个单独的包中。这使得常用的依赖项可以与应用程序代码并行加载,并由浏览器单独缓存。

例如,如果应用程序中的多个页面依赖于 reactlodash,它们可能会被移动到一个单独的包中,而不是在每个页面中重复。这样,当用户从一个页面导航到另一个页面时,他们只需要下载该页面的额外代码,而不需要重新下载已经缓存的那些库。

有关如何配置此功能的更多详细信息,请参阅 代码拆分 文档。

分析包大小

#

Parcel 包含一些工具来帮助您分析包大小。

详细报告

#

默认情况下,Parcel 在为生产构建时会在终端中输出包报告。它包含每个输出包的大小和构建时间。要查看有关构成每个包的文件的更多详细信息,可以使用 --detailed-report CLI 选项。默认情况下,它会显示每个包中最多 10 个文件,按大小排序。您也可以传递一个数字来增加这个数字,例如 --detailed-report 20

包分析器

#

@parcel/reporter-bundle-analyzer 插件可用于生成一个 HTML 文件,其中包含一个树状图,以直观地显示每个包中每个资产的相对大小。您可以使用 --reporter CLI 选项运行它。

parcel build src/index.html --reporter @parcel/reporter-bundle-analyzer

这会在您的项目根目录中生成一个名为 parcel-bundle-reports 的文件夹,其中包含每个目标的 HTML 文件

A screenshot of the bundle analyzer output

您也可以将其添加到 .parcelrc 文件中的 "reporters" 中,如果您希望在每次构建时自动运行包分析器。

Bundle Buddy

#

@parcel/reporter-bundle-buddy 插件可用于生成与 Bundle Buddy 兼容的报告。您可以使用 --reporter CLI 选项运行它。

parcel build src/index.html --reporter @parcel/reporter-bundle-buddy

现在将 dist 目录中的文件上传到 Bundle Buddy 网站

A screenshot of the Bundle Buddy website with a loaded project