Parcel v2.9.0

Parcel v2.9.0 包含了许多长期以来一直要求的功能,包括一个全新的解析器,支持 package.json "exports" 和 tsconfig.json 功能,支持 ESM 插件和配置,以及本地 Parcel 插件。它还通过一个新的默认 JS 压缩器(由 SWC 提供支持)、增量符号传播和改进的捆绑器数据结构来提高性能,并包含一个新的构建性能跟踪功能。这是一个重大版本 - 让我们深入了解一下!

新的解析器

#

Parcel 的解析器负责为依赖项(例如 import "react")查找文件路径。这似乎很简单,但随着 JavaScript 生态系统这些年的发展,它变得越来越复杂。Parcel 当前的解析器实现最初是在 2018 年 写的,缺少一些现代功能,例如 package.json "exports" 和 "imports"。

Parcel v2.9.0 包含一个全新的解析器实现,它从头开始用 Rust 编写。它支持所有现有的 Parcel 解析功能,同时添加了对 package.json "exports" 和 "imports" 以及 tsconfig.json "baseUrl"、"paths" 和 "moduleSuffixes" 的支持。

不幸的是,启用对 package.json "exports" 的支持是一个重大更改。当一个包声明 "exports" 时,使用者将无法再导入未导出的文件。此外,由于像 "import" 和 "require" 这样的导出条件,存在 双包风险。出于这些原因,导出支持目前是可选的,必须在您的项目中显式启用。这可以通过在您的项目根目录 package.json 中添加以下内容来完成

{
"@parcel/resolver-default": {
"packageExports": true
}
}

查看有关 package.json exportstsconfig.json 的文档,以了解有关新功能的更多信息!

ESM 插件和配置

#

Parcel 现在除了支持 CommonJS 之外,还支持以原生 ES 模块编写的插件和配置文件。这意味着插件可以使用 .mjs 格式发布到 npm,或者在它们的 package.json 中使用 "type": "module" 来在 .js 文件中启用 ESM 语法。现在也支持像 postcss.config.mjs 这样的配置文件。

这令人惊讶地难以实现,这就是为什么它花了我们这么长时间。Parcel 为它所做的一切都支持细粒度的缓存,以提高开发性能。为了使这工作,它需要跟踪与您的构建相关的每个文件。这包括所有影响输出的开发依赖项,例如插件、编译器和配置文件。如果这些依赖项中的任何一个发生更改,Parcel 仅重新编译必要的文件。

在内部,这依赖于修补 Node 的 require 实现,以便我们可以跟踪加载的所有开发依赖项。但这只适用于 CommonJS 模块。对于原生 ESM,目前还没有稳定的方法可以进入 Node 中的模块加载器,这意味着我们无法跟踪导入的文件。

为了跟踪 ESM 依赖项,Parcel 现在使用了一个优秀的 es-module-lexer 项目的分支,这是一个用 C 编写的极快的解析器,专门用于分析 ES 模块导入和导出语法。我们已将其与一个 Rust 库集成,该库使用我们的新解析器实现解析这些依赖项,并收集 ESM 插件或配置文件使用的所有文件。这使我们能够在这些依赖项中的任何一个发生更改时使缓存失效。

我们尽最大努力静态分析尽可能多的内容,但某些语法(例如 import(someVariable))不受支持,会导致缓存每次构建都失效。您将在这些情况下看到警告。

ESM 支持在此版本中是实验性的。如果您有任何反馈,请在 Github 上打开一个问题或讨论。

本地插件

#

从历史上看,Parcel v2 插件需要是 npm 包。如果您使用的是单仓库,则可以在您的项目中使用本地插件,但我们始终鼓励将插件发布到 npm 或内部公司注册表,以便其他人可以重复使用它们。但是,我们收到了反馈,这使得构建和原型插件对于没有使用单仓库设置的项目来说更加困难。

在 Parcel v2.9.0 中,插件可以从您的 .parcelrc 配置中作为相对路径引用。它们不需要有自己的 package.json - 您可以直接引用一个 JavaScript 文件。插件在您进行更改时热重载,因此您甚至不需要在开发时重新启动 Parcel。虽然我们仍然鼓励将插件发布到 npm,但这应该使原型设计新插件变得更加容易。

您可以在 文档 中了解有关本地插件的更多信息。

SWC 压缩器

#

Parcel 是最早切换到 SWC JavaScript 编译器的工具之一,它帮助我们在 2021 年 将性能提高了 10 倍。在 Parcel v2.9.0 中,我们也将默认的压缩器从 Terser 切换到 SWC。

SWC 压缩器比 Terser 快约 7 倍,同时产生可比甚至更小的输出大小。大多数 Terser 配置选项也受 SWC 支持,因此如果您有 .terserrc,它应该继续工作。

非常感谢 SWC 团队为整个生态系统改进压缩性能所做的出色工作!

增量符号传播

#

从一开始,Parcel 的主要目标之一就是使重建根据更改的大小而不是整个项目的大小进行扩展。这意味着如果您的项目是 1 个文件或 100,000 个文件,重建速度应该很快。这就是为什么我们从 2017 年的第一个版本开始就实现了细粒度的缓存,以及为什么我们继续引入像 增量捆绑 这样的新功能。

符号传播是一种算法,它遍历项目的完整依赖关系图,并确定每个模块的哪些导出实际上被使用,哪些可以被树状摇动。在 Parcel v2.9.0 中,该算法现在是增量的。它不会每次更改时都遍历整个图,而是跟踪您更改的文件中哪些依赖项已修改,并对现有图进行手术更新。对于非常大的项目,这有助于显着减少每次保存文件时需要完成的工作量。

符号传播现在也在开发中运行,而不仅仅是在生产构建中运行。这使我们能够在开发过程中发出正确的错误,当您尝试导入模块中未导出的内容时,这在调试时可能会有所帮助。

构建性能跟踪

#

Parcel 现在包含一个 --trace CLI 标志,它将跟踪在构建的每个阶段花费了多少时间,调用了哪些插件以及每个插件花费了多长时间。Parcel 跟踪可以帮助您通过回答以下问题来优化构建:“在我的构建过程中,哪个插件花费的时间最长?”或“我的项目中的哪个文件转换时间最长?”

Parcel 一直支持 --profile 标志,它运行 V8 的采样 CPU 分析器。--trace 的级别更高,使您更容易在插件级别而不是函数级别查看性能数据。两者都以 Chrome Tracing 格式输出数据,您可以将其加载到 Chrome Dev Tools 或其他更高级的分析工具(例如 Perfetto)中。在那里,您可以对数据运行 SQL 查询以回答上面列出的问题。

查看 文档 了解更多信息。

还有更多!

#

除了上面提到的主要功能之外,此版本中还有许多更小的功能和错误修复。查看 完整的发行说明 以了解详细信息。

感谢所有为这个版本做出贡献的人!