Parcel v2.9.0
Parcel v2.9.0 包括许多长期以来被请求的功能,包括一个全新的解析器,支持 package.json "exports" 和 tsconfig.json 功能,支持 ESM 插件和配置,以及本地 Parcel 插件。它还通过由 SWC 提供支持的新默认 JS 压缩器、增量符号传播和改进的捆绑器数据结构来提高性能,并包括一个新的构建性能跟踪功能。这是一个重大版本 - 让我们深入了解!
新的解析器
#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 导出和tsconfig.json的文档以了解更多新功能!
ESM 插件和配置
#除了现有的对 CommonJS 的支持外,Parcel 现在还支持作为原生 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 包。如果您使用 monorepo,本地项目内的插件是可能的,但我们总是鼓励将插件发布到 npm 或内部公司注册表,以便其他人可以重用。然而,我们听到反馈说,对于不使用 monorepo 设置的项目来说,这使得构建和原型设计插件变得更加困难。
在 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 跟踪格式输出数据,您可以将其加载到 Chrome 开发工具或其他更高级的分析工具(如 Perfetto)中。在那里,您可以对数据运行 SQL 查询以回答上面列出的问题。
查看文档以了解更多。
还有更多!
#除了上面的主要功能外,此版本还有大量更小的功能和错误修复。查看完整发行说明以了解详情。
感谢所有为此版本做出贡献的人!