生产

Parcel 的生产模式会自动打包并优化你的生产应用。可以使用 parcel build 命令运行它:

¥Parcel’s production mode automatically bundles and optimizes your application for production. It can be run using the parcel build command:

parcel build src/index.html

尺寸优化

#

¥Size optimization

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

¥Parcel includes many optimizations designed to reduce bundle sizes, including automatic minification, tree shaking, image optimization, and more.

缩小化

#

¥Minification

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

¥Parcel includes minifiers for JavaScript, CSS, HTML, and SVG out of the box. Minification reduces the file size of your output bundles by removing whitespace, renaming variables to shorter names, and many other optimizations.

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

¥By default, minification is enabled when using the parcel build command. You can use the --no-optimize CLI flag to disable minification and other optimizations if needed.

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

¥Parcel uses SWC to minify JavaScript, lightningcss for CSS, htmlnano for HTML, and svgo for SVG. If needed, you can configure these tools using a .terserrc, .htmlnanorc, or svgo.config.json config file. See the docs for JavaScript, CSS, HTML, and SVG for more details.

摇树优化

#

¥Tree shaking

在生产版本中,Parcel 静态分析每个模块的导入和导出,并删除所有未使用的内容。这称为 "摇树" 或 "死代码消除"。静态和动态 import()、CommonJS 和 ES 模块,甚至具有 CSS 模块的跨语言都支持 Tree Shaking。

¥In production builds, Parcel statically analyzes the imports and exports of each module, and removes everything that isn't used. This is called "tree shaking" or "dead code elimination". Tree shaking is supported for both static and dynamic import(), CommonJS and ES modules, and even across languages with CSS modules.

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

¥Parcel also concatenates modules into a single scope when possible, rather than wrapping each module in a separate function. This is called “scope hoisting”. This helps make minification more effective, and also improves runtime performance by making references between modules static rather than dynamic object lookups.

请参阅 作用域提升 文档,了解使 Tree Shaking 更有效的提示。

¥See the Scope hoisting docs for tips to make tree shaking more effective.

开发分支移除

#

¥Development branch removal

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

¥parcel build automatically sets the NODE_ENV environment variable to production. This environment variable is often used in libraries to enable development-only debugging features that can be stripped in production builds to reduce bundle size. Parcel inlines this environment variable and optimizes comparisons to remove dead branches.

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

¥You can take advantage of this feature in your own code as well. For example, you could use an if statement to check the NODE_ENV environment variable.

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

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

¥See the Node emulation docs for more details on environment variable inlining.

图片优化

#

¥Image optimization

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

¥Parcel supports resizing, converting, and optimizing images. You can use query parameters when referencing an image in HTML, CSS, or JavaScript to specify which format and size the image should be converted to. You can request multiple sizes or formats from the same source image, which helps support different types of devices or browsers efficiently.

<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>

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

¥Resizing and converting images occurs both in development and production mode, so you can test with the correct image dimensions and formats as well. See the Image transformer docs for more details.

Parcel 还默认在生产模式下对 JPEG 和 PNG 进行无损图片优化,从而在不影响图片质量的情况下减小图片的大小。这不需要任何查询参数或配置即可使用。但是,由于优化是无损的,因此与使用 quality 查询参数或使用现代格式(例如 WebP 或 AVIF)相比,可能减少的大小可能会更少。

¥Parcel also includes lossless image optimization for JPEGs and PNGs by default in production mode, which reduces the size of images without affecting their quality. This does not require any query parameters or configuration to use. However, since the optimization is lossless, the size reduction possible may be less than if you use the quality query param, or use a modern format such as WebP or AVIF.

差异化打包

#

¥Differential bundling

Parcel 会自动生成具有现代 JavaScript 语法的 <script type="module">,并在必要时为旧版浏览器生成后备 <script nomodule>。通过避免类、异步/等待等功能的转译,这可以减少大多数用户的包大小。有关更多详细信息,请参阅目标文档中的 差异化打包

¥Parcel automatically produces a <script type="module"> with modern JavaScript syntax, as well as a fallback <script nomodule> for older browsers when necessary. This reduces bundle sizes for a majority of users by avoiding transpilation of features like classes, async/await, and more. See Differential bundling in the Targets documentation for more details.

压缩

#

¥Compression

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

¥Parcel supports compressing bundles using Gzip and Brotli. While many servers compress data on the fly, others require you to upload pre-compressed payloads ahead of time. This may also allow for better compression, which would be too slow to do on every network request.

因为不是每个人都需要它,所以默认情况下不启用压缩。要启用它,请将 @parcel/compressor-gzip 和/或 @parcel/compressor-brotli 添加到 .parcelrc

¥Because not everyone needs it, compression is not enabled by default. To enable it, add @parcel/compressor-gzip and/or @parcel/compressor-brotli to your .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 文件。如果基于文本的文件类型比上面示例中列出的更多,则需要相应地扩展 glob。

¥Now you’ll get a .gz and a .br file along side the original uncompressed bundle. If you have more text-based file types than listed in the above example, you'll need to extend the glob accordingly.

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

¥If you don’t need the uncompressed bundle, you can also remove the "..." from the above example to only output compressed files. For example, to only output a .gz file, you could use the following config:

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

缓存优化

#

¥Cache optimization

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

¥Parcel includes several optimizations related to browser and CDN caching, including content hashing, bundle manifests, and shared bundles.

内容哈希

#

¥Content hashing

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

¥Parcel automatically includes content hashes in the names of all output files, which enables long-term browser caching. Whenever the contents of a bundle changes, the hash included in the filename will be updated, triggering invalidation of CDN and browser caches.

默认情况下,所有打包包都包含内容哈希,但入口和某些需要名称稳定的依赖类型除外。例如,Service Worker 需要稳定的文件名才能正常工作,HTML 中的 <a> 标记引用用户可读的 URL。

¥By default, all bundles include a content hash except entries and certain dependency types that require names to be stable. For example, service workers require a stable file name to work properly, and <a> tags in HTML reference user readable URLs.

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

¥You can also disable content hashing using the --no-content-hash CLI flag. Note that the name will still include a hash, but it will not change on each build. You can customize bundle naming completely using Namer plugins.

级联失效

#

¥Cascading invalidation

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

¥Parcel uses a manifest in each entry bundle to avoid the cascading invalidation problem in many cases. This manifest includes a mapping of stable bundle ids to final content hashed filenames. When one bundle needs to reference another, it uses the bundle id rather than the content hashed name. This means that when a bundle updates, only that bundle and the entry will need to be invalidated in the browser cache and intermediary bundles will not change. This improves the cache hit rate across deployments.

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

¥When the size of an entry bundle is over a threshold (100 KB by default), the manifest is automatically split into a separate bundle. Since the manifest changes on every build, this avoids invalidating the entire entry bundle even when no other code in the entry changed. This can help decrease the number of bytes a user needs to download to receive an update. The size threshold at which to split the manifest into its own bundle can be configured in the package.json file in your project root. It is defined in bytes prior to minification.

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

共享打包包

#

¥Shared bundles

在生产版本中,Parcel 会自动优化应用中的打包图,以减少重复并提高可缓存性。当应用的多个部分依赖于相同的公共模块时,它们会自动进行数据去重并放入单独的包中。这允许常用的依赖与应用代码并行加载,并由浏览器单独缓存。

¥In production builds, Parcel automatically optimizes the bundle graph in your application to reduce duplication and improve cacheability. When multiple parts of your application depend on the same common modules, they are automatically deduplicated into a separate bundle. This allows commonly used dependencies to be loaded in parallel with your application code and cached separately by the browser.

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

¥For example, if multiple pages in your app depend on react and lodash, they might be moved into a separate bundle rather than duplicated in each page. This way, when a user navigates from one page to another, they only need to download the additional code for that page rather than re-downloading those libraries which are already cached.

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

¥See the Code splitting docs for more details on how to configure this.

分析包大小

#

¥Analyzing bundle sizes

Parcel 包含一些工具可帮助你分析打包包大小。

¥Parcel includes some tools to help you analyze bundle sizes.

详细报告

#

¥Detailed report

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

¥By default, Parcel outputs a bundle report in the terminal when building for production. It includes the size and build time for each output bundle. To see more details about what files make up each bundle, you can use the --detailed-report CLI option. By default, it shows up to 10 files in each bundle, sorted by size. You can also pass a number to increase this, e.g. --detailed-report 20.

包分析器

#

¥Bundle analyzer

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

¥The @parcel/reporter-bundle-analyzer plugin can be used to generate an HTML file containing a tree map that shows the relative size of each asset in every bundle visually. You can run it using the --reporter CLI option.

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

这会在项目根目录中生成一个文件夹 parcel-bundle-reports,其中每个目标都有一个 HTML 文件:

¥This generates a folder parcel-bundle-reports in your project root with an HTML file for every target:

A screenshot of the bundle analyzer output

如果你想在每个构建上自动运行打包分析器,你还可以将其添加到 .parcelrc 文件中的 "reporters"

¥You can also add it to "reporters" in your .parcelrc file if you want to run the bundle analyzer on every build automatically.

Bundle Buddy

#

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

¥The @parcel/reporter-bundle-buddy plugin can be used to generate a report that is compatible with Bundle Buddy. You can run it using the --reporter CLI option.

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

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

¥Now upload the files in the dist directory to the Bundle Buddy website.

A screenshot of the Bundle Buddy website with a loaded project

Parcel 中文网 - 粤ICP备13048890号