Parcel 2 beta 1

📦 Parcel 2 beta 1 - 提升稳定性、摇树优化、源映射性能等等! 🚀

Parcel 团队非常高兴今天发布 Parcel 2 的第一个 beta 版本!这是第一个比我们的 nightly 和 alpha 版本更稳定的 Parcel 2 版本,我们承诺避免更改大多数面向用户的 API。请试用它,并在 GitHub 上给我们反馈!

自从我们上次发布 alpha 版本以来,Parcel 2 已经进行了大量的开发。我们一直在专注于 **稳定性**、**性能** 和 **可靠性**,为我们的稳定版 v2 版本做准备,但我们也设法偷偷地加入了一些新功能!

摇树优化

#

构建一个生产级的 JavaScript 编译器极具挑战性。我们一直在努力改进 Parcel 的摇树优化实现 自 2018 年以来,并且它自那时以来有了巨大的改进。Parcel 2 默认启用摇树优化,我们最近一直在使用它在 Atlassian 和 Adobe 的生产环境中部署一些非常大型的应用程序。

Parcel 的摇树优化实现是捆绑器中独一无二的。除了像许多其他工具一样支持 ES 模块之外,Parcel 还原生支持摇树优化 CommonJS。虽然一些库现在提供 ES 模块,但 npm 上的大多数代码仍然是用 CommonJS 编写的,或者在发布之前被转译为 CommonJS。CommonJS 很难进行静态分析,就像大多数 JavaScript 代码一样,我们投入了大量精力来使它变得透明。我们可以在大多数情况下进行静态分析,并在执行不安全操作时自动退出并用函数包装模块。在过去几个月里,我们发现了并修复了摇树优化实现中的许多错误和边缘情况,并对其进行了广泛的测试。我们很乐意听取它在您的应用程序中的运作情况!请 报告您发现的任何错误

Parcel 现在也为摇树优化后的捆绑包生成源映射。这是自最初的摇树优化发布以来的一个限制,也是我们面临的一项重大挑战。由于摇树优化不仅仅是线性地将文件连接在一起,因此很难以正确的方式合并源映射。相反,我们现在将 AST 存储在我们的缓存中,并将它们合并在一起。这将位置信息保留为 AST 节点的一部分,这些信息可用于在代码生成结束时作为代码生成的一部分生成最终的源映射。

除了源映射之外,位置信息还允许我们提供更准确的错误消息。我们现在能够显示详细的代码框架,用于诸如从模块导入不存在的导出以及更多错误。

非常感谢 Niklas Mischkulnig 为改进 Parcel 中的摇树优化编译器所做的一切工作。🙏

源映射

#

源映射的生成可能非常占用 CPU 和内存,尤其是在合并来自多个文件的源映射时。我们之前使用 Mozilla source-map 库来完成此操作,但在大型捆绑包上遇到了性能问题。

为了解决这个问题,我们实现了 我们自己的库 用于合并和操作源映射。它是一个用 C++ 编写的原生节点模块,专门为 Parcel 的用例而构建。它利用 FlatBuffers 进行 worker 之间以及与缓存的序列化,这极大地降低了我们之前在 JSON 中看到的生成和解析成本。总的来说,它在合并源映射时比 JavaScript 实现快了 **约 20 倍**。例如,以前需要 3 秒才能生成源映射的捆绑包现在只需要 175 毫秒!

除了原生节点模块之外,还有一个相同库的 WebAssembly 版本,它允许它在 Web 浏览器等环境中使用。虽然不像原生绑定那么快,但令人兴奋的是,可以使用相同的代码,而不是还需要维护一个纯 JS 实现。

感谢 Jasper De Moor 为 Parcel 中的源映射所做的一切惊人工作!🥳

内容哈希

#

我们自 v1.7.0 以来一直通过内容哈希文件名在 Parcel 中支持长期缓存。这些内容哈希历来是通过对捆绑包中包含的每个单独文件进行哈希来生成的。这确保了捆绑包中任何文件的更改都会导致文件名更新,并使浏览器和 CDN 缓存失效。但是,它没有考虑 Parcel 运行时代码本身发生更改而不是源代码的情况。当升级 Parcel 的版本或在后面运行的插件(例如缩小器)时,可能会发生这种情况。

Parcel 现在根据捆绑包的最终内容生成哈希,在完成所有打包和缩小之后。这意味着,即使 Parcel 注入的运行时代码发生更改,或者您的缩小器更改了它编译代码的方式,内容哈希现在也会正确更新。

这很难实现,因为捆绑包可能会将其他捆绑包作为代码的一部分引用。由于最终名称只有在代码生成后才能知道,Parcel 现在将占位符引用插入捆绑包的内容中,而不是最终的捆绑包名称。最后,这些名称将在它们被写入磁盘时被替换为最终名称。

除了更可靠的内容哈希之外,Parcel 现在还避免了在许多情况下出现的 级联失效 问题。这篇文章在上面链接的博客文章中得到了很好的介绍,但本质上是,由于捆绑包可能会通过内容哈希文件名引用其他捆绑包,因此当叶捆绑包更新时,所有通向该捆绑包的捆绑包也必须更新才能清除缓存。这会导致缓存性能不佳。

Parcel 现在不是直接通过完整的内容哈希名称引用捆绑包,而是在每个入口捆绑包中包含一个清单。此清单包含稳定捆绑包 ID 到最终内容哈希文件名的映射。不是直接引用其他捆绑包,而是只包含捆绑包 ID。当树中更深层的捆绑包更新时,失效不再需要级联到中间捆绑包,因为捆绑包 ID 是稳定的。只有入口捆绑包(包含清单)和发生更改的捆绑包需要更新。这可以显着提高缓存命中率。

感谢 Maia TeegardenWill Binns-Smith 为 Parcel 2 中的内容哈希所做的工作!

解析器诊断

#

Parcel 现在在无法找到您引用的模块时包含改进的错误报告。这包括一个代码框架堆栈,显示您错误发生的确切位置,以及导致该问题的任何中间文件。

例如,下面的屏幕截图显示了一个错误,该错误通常只包含第一行(无法从“./src/index.js”解析“invalid-entries”)以及可能的第一行代码框架(如果您幸运的话)。但是,这并不能告诉您错误实际上发生在哪里。在本例中,invalid-entries 模块确实存在,但它指向其 package.json 中不存在的文件。Parcel 现在显示 package.json 的第二个代码框架,指向导致底层问题的准确行。

升级

#

从之前的 Parcel 2 alpha 版本升级应该相当简单,但有一些需要注意的地方。

文档

#

我们一直在为 Parcel 2 开发一个 新的文档网站!它仍然是一个正在进行中的工作,但我们计划涵盖从使用 Parcel 构建基本应用程序或库开始,到更高级的功能、食谱和构建自己的插件等内容。请查看它并给我们反馈!

稳定性

#

如前所述,这是 Parcel 2 的第一个 beta 版本。这意味着它比 nightly 或 alpha 版本更稳定,但在完全稳定版本发布之前,仍然预计会有一些更改。特别是,beta 意味着我们不打算更改大多数面向用户的 API,例如配置格式(在 package.json 和 .parcelrc 中)和 CLI 参数。在第一个发布候选版本之前,仍然预计插件 API 会有一些更改,但是我们预计此时不会出现重大更改。

试用它!

#

如果您一直在等待尝试 Parcel 2,现在是绝佳时机!您可以通过运行 yarn add parcel@next 来安装它。如果您需要帮助,可以在 GitHub 讨论 中提问,如果您遇到错误,请在 GitHub 问题 中报告。您也可以在 Twitter 上找到我 @devongovett。我们非常期待您的反馈!