Parcel 2 beta 1

📦 Parcel 2 beta 1 - 改进的稳定性、树摇、源映射性能等!🚀

Parcel 团队非常高兴今天发布 Parcel 2 的第一个测试版!这标志着第一个比我们的夜间和 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 的大部分代码一样,我们投入了巨大的努力使这一过程透明。在大多数情况下我们可以进行静态分析,并在执行不安全操作时自动退出并将模块包装在函数中。在过去的几个月里,我们发现并修复了树摇实现中的许多 bug 和边缘情况,并进行了广泛测试。我们很想听听它在你的应用程序中的表现!请报告你发现的任何 bug

Parcel 现在还为树摇后的包生成源映射。这是自初始树摇发布以来的一个限制,对我们来说是一个主要挑战。由于树摇并不是简单地线性连接文件,因此以正确的方式组合源映射很困难。相反,我们现在在缓存中存储 AST,并将它们组合在一起。这保留了 AST 节点中的位置信息,可以在代码生成过程结束时用于生成最终的源映射。

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

非常感谢 Niklas Mischkulnig 在改进 Parcel 的树摇编译器方面所做的所有工作。🙏

源映射

#

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

为了解决这个问题,我们实现了我们自己的库来合并和操作源映射。这是一个原生 Node 模块,用 C++ 编写,专门为 Parcel 的用例而构建。它利用 FlatBuffers 在工作进程和缓存之间进行序列化,这极大地降低了我们之前使用 JSON 时生成和解析的成本。总体而言,它在合并源映射时快约 20 倍于 JavaScript 实现。举个例子,之前需要 3 秒生成源映射的包现在只需 175 毫秒!

除了原生 Node 模块,还有同一个库的 WebAssembly 构建,允许它在 Web 浏览器等环境中使用。虽然不如原生绑定快,但能够重用相同的代码而不需要维护纯 JS 实现是很令人兴奋的。

感谢 Jasper De Moor 在 Parcel 源映射方面所做的出色工作!🥳

内容哈希

#

v1.7.0 以来,我们就通过内容哈希文件名支持长期缓存。这些内容哈希历来是通过哈希包中包含的每个单独文件生成的。这确保了包中任何文件的更改都会导致文件名更新,并使浏览器和 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 的第一个测试版。这意味着它比夜间或 alpha 版本更稳定,但在完全稳定发布之前仍然预期会有一些变化。特别是,测试版意味着我们不打算更改大多数面向用户的 API,如配置格式(在 package.json 和 .parcelrc 中)和 CLI 参数。在第一个发布候选版本之前,插件 API 仍可能有一些更改,但此时我们不希望有重大变化。

试用!

#

如果你一直在等待尝试 Parcel 2,现在是个好时机!你可以通过运行 yarn add parcel@next 来安装。如果需要帮助,可以在 GitHub 讨论中提问,如果遇到 bug,请在 GitHub issues 上报告。你还可以在 Twitter 上找到我 @devongovett。我们真的很期待听到你的反馈!