likes
comments
collection
share

[译] 一个关于打包工具的故事:从 webpack 迁移到 Rspack在 Alan 公司,我们多年来一直使用 webp

作者站长头像
站长
· 阅读数 111

本文翻译自 A bundler story: migrating from webpack to Rspack,原作者 Tim Petricola。

在 Alan 公司,我们多年来一直使用 webpack。虽然它很好地为我们服务,但它已经成为开发的瓶颈。

最近,我们完成了向 Rspack 的迁移(Rspack 是一个承诺提供更快性能的 Rust 替代品)。

这篇文章是我们旅程和经验的简短故事。

选择一个打包工具

打包工具是将代码和依赖项打包成若干个 JavaScript 文件的工具,它可以优化性能和浏览器加载速度。

当 Alan 公司在 2016 年启动时,webpack 是 JavaScript 打包工具的事实标准。它经过了实战考验,拥有庞大的生态系统,并且有非常丰富的配置项。

虽然 webpack 多年来很好地为我们服务,但它已成为开发的瓶颈。我们的本地构建和热模块替换 (HMR) 不够快:

  • 第一次服务器启动需要 45 秒。
  • HMR 需要 15 秒才能完成。
  • 生产环境构建在 CI 上超过 5 分钟。

这些年来,我们通过在配置中引入 webpack 的持久化缓存,用 esbuild 替换 Babel 和 Terser 等方式进行改进。但这逐渐达到了一个瓶颈,在不进行重构的情况下,我们已经无法获得更多的性能提升。

为了改进开发和生产的 feedback loop(反馈循环),我们需要寻找一个新的打包工具。

近年来,JavaScript 生态系统中出现了许多新的构建工具—— Parcel、Vite、esbuild、Rspack、Turbopack、Farm、Mako 等。这些工具都承诺在开发者体验和性能方面具有它们的优势。

但在 Alan,我们喜欢无聊的技术。我们不想使用需要工程师深入研究新概念、或花时间克服工具问题的前沿技术。我们在了解两个新的打包工具 —— ViteRspack 时牢记这一原则。

Vite

我们过去曾探索过切换到 Vite,因为它在 React 生态系统中已经成为一个非常流行的工具。Vite 是一个很棒的工具,采用了不同的实现,因为它在开发时不打包资源,提供更快的服务器启动时间和 HMR。然而,我们发现 Vite 并不适合我们:

  • Vite 在开发和生产构建时依赖不同的工具(开发时使用 esbuild,生产时使用 Rollup)。这可能导致开发和生产构建之间出现差异,并且在构建过程中调试问题变得很难。
  • Vite 在开发时不打包的方式,经常会导致我们应用程序中的模块数量过多,而引起浏览器网络拥塞。虽然这可以优化,但这耗费了我们不愿意花费的时间。
  • Vite 与 webpack 非常不同。我们将不得不重写整个构建配置,这可能会非常耗时,且容易出错。

Rspack

2023 年初,一个新的打包工具加入了竞争:Rspack。它承诺与 webpack 兼容,且具有大幅的性能提升(特别是受益于 Rust 生态)。

虽然我们不喜欢采用全新的技术,但这个承诺太诱人了,所以我们决定在一个冷静期(在季度之间的过渡周,没有既定的 roadmap,便于员工探索新想法)进行尝试。

我们的迁移之旅

实验阶段

由于 Rspack 兼容了 webpack 的大多数配置项,最初的概念验证相当简单。对于不兼容的部分,我们实现了一个小型兼容层,将 webpack 配置项转换为 Rspack 配置。这个兼容层处理了如下问题:

  • 移除不必要的 loader(例如 css-loader)。
  • 将一些插件替换为它们在 Rspack 中的等价实现(例如用 rspack.HtmlwebpackPlugin 替换 html-webpack-plugin)。
  • 用内置 swc-loader 和压缩器替换我们自定义的 esbuild loader 和压缩器。

因为 Rspack 被设计为 webpack 的替代品,我们仅用了大约 200 行代码就实现了一个兼容层。

这次替换的结果令人印象深刻 ⚡:

  • 本地首次构建至多比 webpack 快 3 倍(从 16 秒到 6 秒)
  • HMR 至多比 webpack 快 20 倍(从 7 秒到 400 毫秒)

更重要的是,这些数据低估了实际的性能提升,因为:

  • 他们比较的是未开启 sourcemaps 的 webpack 和开启了 sourcemaps 的 Rspack(webpack 的 sourcemaps 太慢,以至于我们在开发中默认没有启用)。
  • 我们使用了 webpack 的持久化缓存,而 Rspack 未使用缓存。

译者注:Rspack 将在近期提供持久化缓存。

此时,我们遇到了一些问题(当时 Rspack 还处于早期):我们无法让我们的 SSR 配置项正常工作,CSS extract 功能尚未就绪,并且我们遇到了一些短暂的 HMR 异常。

但这整体上已经足够好,让我们决定让工程师在开发中自愿选择使用 Rspack,以观察效果。

上报真实数据

虽然我们已经看到了 Rspack 在本地开发中的优势,但我们希望确保大幅改善开发者体验。

于是我们决定收集构建和 HMR 的数据。这些数据将在开发者的机器上收集,并发送到 Datadog 以便于可视化。

多亏了 Unplugin,我们实现了一个非常简单的插件,该插件同时兼容 webpack 和 Rspack 来完成数据收集。

这使得我们能够确认所有工程师都能受益于这种改进,而不仅仅是在特定场景中。

[译] 一个关于打包工具的故事:从 webpack 迁移到 Rspack在 Alan 公司,我们多年来一直使用 webp

渐进式迁移

随着 Rspack 从 0.1 版本逐渐改进,并发布到 v1.0 稳定版本,我们也在不断升级和改进我们的配置。

我们开始将小型内部项目迁移到 Rspack。每个项目的迁移过程如下:

  • 在本地使用 BUNDLER=rspack 环境变量,选择性地开启 Rspack。
  • 将 Rspack 设置为本地默认的打包工具(并允许通过 BUNDLER=webpack 关闭)。
  • 切换生产构建到 Rspack。
  • 移除对 webpack 的支持。

BUNDLER 环境变量用于收集有关 Rspack 的信息,同时不会对工程师造成限制。将该变量设置为 rspack 会:

  • 将开发过程中使用的打包工具切换为 Rspack。
  • 在控制台中输出更多信息,帮助工程师(例如,参考我们的内部 Rspack 文档,告诉他们在遇到问题时该联系谁,以及如何切换回 webpack)。

在我们迁移的每个项目中,我们都立即看到了构建时间的改进,并逐步将越来越复杂的代码库迁移到 Rspack。

最终,我们只剩下一个使用 webpack 的项目,即我们的 SSR 登陆页项目(我们正等待 Rspack v1.0,以便能够切换该项目)。

完成迁移

随着时间的推移,我们最初在使用 Rspack 时遇到的所有问题都得到了解决(通过新发布的版本,或是调整我们的配置项)。

Rspack 在上周(2024.09)发布了 第一个稳定版本,我们已经准备好切换最后一个应用。

为了完成迁移,我们:

  1. 在生产和开发环境中将最后一个应用切换到 Rspack
  2. 移除兼容层,并使用 Rspack 配置项作为唯一的来源

我们还用 storybook-rsbuild(Rsbuild 是 Rspack 的一个抽象层,与 Storybook 兼容)替换了我们 Storybook 的 webpack5 构建器。

结果

性能

那么,实际的数据表现如何呢?以我们最复杂的项目之一为例,提升是显而易见的:

+---------------------+---------+--------------+
|                     | webpack |    Rspack    |
+---------------------+---------+--------------+
| Dev - Initial build | 16.17s  | 5.99s (-62%) |
| Dev - HMR           | 2.90s   | 700ms (-72%) |
| Prod - Build        | 2min10s | 34s (-86%)   |
+---------------------+---------+--------------+

我们的 Storybook 构建时间从 2 分 25 秒减少到 33 秒 (-88%)。

可维护性

我们还移除了大量的配置项,因为 Rspack 自带了优异的默认配置:

  • 我们移除了 css-loaderstyle-loaderresolve-url-loadermini-css-extract-plugin,改用 Rspack 的 experiments.css
  • 我们用内置的 swc-loader 替换了自定义的 esbuild-loader 配置。
  • 我们移除了 webpack-bundle-analyzer,改用功能更丰富的 Rsdoctor(兼容 Rspack 和 webpack!)
  • 在开发过程中,我们也不再需要维护自定义的持久化缓存(有时还得手动清除),因为 Rspack 在无缓存的情况下已经很快了。

內部反馈

团队的反馈非常积极:

切换到 Rspack 对我过去一年多的前端开发来说是非常革命性的变化。

Rspack 让前端开发变得容易多了!

哇塞,那简直太棒了!!! ⚡

展望未来

我们对 Rspack 非常满意,并对打包工具的未来充满期待。我们也在关注 Vite 的动态(特别是即将推出的 Rolldown,它是基于 Rust 的 Rollup 替代品)。

Rspack 的团队还发布了 Rsbuild。这是一个基于 Rspack 的上层构建工具,具有优秀的默认设置,提供了良好的性能和许多开箱即用的功能。

整个生态系统也在快速推进,采用新一代的打包工具。例如,我们依赖 Docusaurus 来进行一些内部文档,迫不及待地想看到他们从 webpack 切换到 Rspack 的完成!

译者注:Docusaurus 已支持 Rspack

如果你在考虑从 webpack 切换到 Rspack,我们强烈建议你试试看!

转载自:https://juejin.cn/post/7425598941859676170
评论
请登录