使用 Rspack

这篇文档会向你介绍如何在 Builder 中开启 Rspack 构建模式。

什么是 Rspack

Rspack 是一个基于 Rust 的高性能 Web 构建工具,具备与 webpack 生态系统的互操作性,可以被 webpack 项目低成本集成,并提供更好的构建性能。

相较于 webpack,Rspack 的构建性能有明显提升,除了 Rust 带来的语言优势,这也来自于它的并行架构和增量编译等特性。经过 benchmark 验证,Rspack 可以带来 5 ~ 10 倍编译性能的提升。

启用 Rspack

在 Modern.js 框架中启用

Modern.js 框架默认使用 webpack 作为打包工具。如果希望启用 Rspack 作为打包工具,可参考:使用 Rspack

在前端框架中接入

如果你基于 Builder 开发了一个前端框架,接入 rspack-provider 和 接入 webpack-provider 的方式类似,只需要把依赖从 @modern-js/builder-webpack-provider 改为 @modern-js/builder-rspack-provider 即可。

modern.config.ts
import { createBuilder } from '@modern-js/builder';
import { builderRspackProvider } from '@modern-js/builder-rspack-provider';

const provider = builderRspackProvider({
  builderConfig: {
    // some configs
  },
});
package.json
{
  "devDependencies": {
-    "@modern-js/builder-webpack-provider": "2.8.0",
+    "@modern-js/builder-rspack-provider": "2.8.0"
  }
}

注意事项

在使用 Rspack 之前,请留意 Rspack 仍然是一个早期项目,当前还处于快速迭代阶段。因此,你需要预先了解以下事项:

  • Rspack 的 API 和配置项还不稳定,同时 Modern.js 对 Rspack 的支持属于实验性的,因此在后续的非 major 版本中,可能会引入不兼容更新。
  • Rspack 并未实现完整的 webpack 优化能力(如 tree shaking、bundle splitting、scope hoist 等能力,我们将在 6 ~ 12 月持续补齐相关优化能力),迁移到 Rspack 后,你可能会发现产物的包体积相较 webpack 有一定程度的增加。
  • Rspack 目前基于 SWC 进行代码编译和压缩,由于 SWC 的成熟度不及 babel 和 terser,因此你可能会遇到 SWC 的 bug。
  • Rspack 模式兼容了大部分 webpack 生态的插件和 loaders,但仍有部分插件和 loaders 暂时无法使用。

Rspack 正在积极改善上述问题,并计划在未来的版本中逐步解决它们。我们建议在决定是否使用 Rspack 之前,评估你的项目需求和风险承受能力。如果你的项目对稳定性和性能要求较高,可以先选择更成熟的 webpack。如果你愿意尝试新的工具并为其发展做出贡献,我们欢迎你使用 Rspack,并提供反馈和报告问题,以帮助改进它的稳定性和功能。

从 webpack 迁移到 Rspack

Builder 旨在消除不同打包工具之间的主要差异,帮助用户以较低成本进行迁移。但由于各个打包工具提供的能力不同,你仍需要了解其中的部分差异。

本文将从 Builder 的角度介绍 webpack 和 Rspack 之间的区别。如果需要了解更深层次的差异,请参考 Rspack 文档

1. Builder 配置差异

目前,Builder 内大部分的配置项已经适配了 Rspack,但仍有部分配置在支持中。

Source Config

Builder 中与源代码解析、编译方式相关的配置。

不支持的配置项及能力包括:

Html Config

Builder 中与 HTML 有关的配置。

所有 html 下的配置项及能力在 Rspack 内均可使用。

Security Config

Builder 中与安全有关的配置。

不支持的配置项及能力包括:

Dev Config

Builder 中与本地开发有关的配置。

所有 dev 下的配置项及能力在 Rspack 内均可使用。

Output Config

Builder 中与构建产物有关的配置。

不支持的配置项及能力包括:

Experiments Config

Builder 中的一些实验性配置。

不支持的配置项及能力包括:

Performance Config

Builder 中与性能有关的配置。

不支持的配置项及能力包括:

Tools Config

Builder 中与底层工具有关的配置。

不支持的配置项包括:

TIP

除上述配置外,一些已支持的配置可能存在能力差异,请参考各配置 API 获取具体差异信息。

2. 从 tools.webpackChain 迁移至 tools.bundlerChain

Builder 支持通过 bundlerChain 来修改 Rspack config。通过 bundlerChain 修改的配置,在 webpack 和 Rspack 构建时均可生效。

export default {
  tools: {
-   webpackChain: (chain, { env }) => {
+   bundlerChain: (chain, { env }) => {
      if (env === 'development') {
        chain.devtool('cheap-module-eval-source-map');
      }
    },
  },
};
TIP

bundlerChain 只为 Rspack & webpack 配置提供一致的 api 修改方式,实际 plugin / loader 是否可用,需要看 Rspack / webpack 实际支持情况。

CHAIN_ID 差异

因为 webpack 和 Rspack 的一些实现差异,所以在规则配置上会有些不同。

可通过 tools.bundlerChain#CHAIN_ID 查看所有在 Rspack & webpack 中都支持的规则。

3. 从 tools.webpack 迁移至 tools.rspack

BundlerChain 只支持修改 Rspack & webpack 交集部分,更多 Rspack 独有功能,需要通过 tools.rspack 修改。

在修改 Rspack 配置之前,你可能需要了解 Rspack 和 Webpack 的配置兼容性

export default {
  tools: {
-   webpack: (config, { env }) => {
+   rspack: (config, { env }) => {
      if (env === 'development') {
        config.devtool = 'cheap-module-eval-source-map';
      }
      return config;
    },
  },
};

关于 Rspack 的详细配置信息,请参考 Rspack 官网

4. Babel 配置迁移

Rspack 默认会使用 SWC 进行转译和压缩,因此,在启用 Rspack 构建时,babel-loader 默认不会被启用。

对于大部分常见的 Babel 插件,你可以在 Rspack 中找到对应的替代品,同时 Builder 也提供了一些相应的配置项。

Babel 插件 Rspack 配置项 Builder 配置项
@babel/preset-env builtins.presetEnv 设置浏览器范围
浏览器兼容性
@babel/preset-react builtins.react 模块热更新
@emotion/babel-plugin builtins.emotion 暂无
babel-plugin-import builtins.pluginImport source.transformImport
babel-plugin-lodash 暂无 暂无
babel-plugin-styled-components 暂无 暂无
@babel/plugin-react-transform-remove-prop-types 暂无 暂无
TIP

在使用 Rspack 构建时,仍然支持通过 tools.babel 配置 Babel 插件,但会产生额外的编译开销,在一定程度上拖慢 Rspack 构建速度。

5. SWC 配置支持

Rspack 中已内置了一部分的 swc 配置支持,如 builtins.react 等,可参考 Builtins

暂不支持在 Rspack 中添加 swc 插件和更多自定义配置,相关需求可追踪对应 issue 进度

6. Webpack Plugin 插件迁移

目前 Rspack 中兼容的 webpack 插件有限,当你的项目中有用到以下插件(或间接依赖)时,需要暂时将该插件移除或使用替代方案,否则不支持切换至 Rspack 构建:

具体插件支持情况可参考:Plugin 兼容情况

未列出的插件可根据 Rspack Plugin API 支持情况 自行判断。

7. CSS Modules 配置迁移

Rspack 模式下不支持通过 tools.cssLoader 修改 CSS Modules 配置,Builder 提供了 output.cssModules 配置项,用来抹平 Rspack 模式和 webpack 模式下的实现差异。

export default {
+  output: {
+    cssModules: {
+      auto: resource => {
+        return resource.includes('.module.') || resource.includes('shared/');
+      },
+    },
+  },
-  tools: {
-    cssLoader: {
-      modules: {
-        auto: path => {
-          return resource.includes('.module.') || resource.includes('shared/');
-        },
-      },
-    },
-  }
};

Rspack 性能分析

Builder 支持使用 RSPACK_PROFILE 环境变量来进行构建性能分析。

$ RSPACK_PROFILE=ALL pnpm build

执行该命令后会在当前产物目录下生成一个 rspack-profile-${timestamp} 文件夹,该文件夹下会包含 logging.jsontrace.jsonjscpuprofile.json 三个文件

  • trace.json:使用 tracing 细粒度地记录了 Rust 侧各个阶段的耗时,可以使用 ui.perfetto.dev 进行查看
  • jscpuprofile.json:使用 Node.js inspector 细粒度地记录了 JavaScript 侧的各个阶段的耗时,可以使用 speedscope.app 进行查看
  • logging.json:包含一些日志信息,粗粒度地记录了构建的各个阶段耗时

对比 Rspack CLI

Builder Rspack 构建模式对比 Rspack CLI 添加了很多开箱即用的能力,同时,这些能力的封装会带来一定程度上的性能开销和行为表现上的差异:

功能 描述 相关链接
浏览器兼容性 Builder 会根据构建产物类型来设置不同的 Browserslist 默认值
SourceMap 生成 Builder 默认根据环境生成不同的 SourceMap (Rspack CLI 中默认是 false)
SVG 转 React 组件 Builder 默认支持在 React 组件中引用 SVG 作为组件
按需引入常用组件库 当项目中安装了 Ant DesignArco Design 组件库时,Builder 会自动添加对应的按需引入能力
默认开启 TypeScript 类型检查 Builder 会默认通过 TS Checker 检查类型问题
默认集成 PostCSS Builder 内默认开启 PostCSS 编译,并内置 autoprefixer 等多个插件
使用 @rspack/html-plugin Builder 内默认集成 @rspack/html-plugin 以支持更多 HTML 模版功能 (Rspack CLI 中默认使用 builtins.html)
DevServer Builder 内基于 webpack-dev-middleware 实现 DevServer (Rspack CLI 使用 @rspack/dev-server)

以上能力均提供可调整的配置选项,可以根据项目实际情况按需进行调整。

更多内置能力,可参考 功能导航

常见问题

启用 Rspack 构建后,性能没有预期的快?

通常情况下,启用 Rspack 后,相较 Webpack 会有 5 到 10 倍的编译性能提升。

目前已知以下行为会在一定程度上拖慢 Rspack 构建性能:

使用依赖 Babel 实现的配置项或插件

在使用 Rspack 构建时,Builder 默认不会启用 babel-loader。但当项目中使用到依赖 Babel 实现的配置项或插件时,会额外添加 babel-loader 进行文件转译:

你可以通过开启调试模式 来查看最终生成的 Rspack 配置中是否存在 Babel 插件。

开启 TypeScript 类型检查

Builder 构建时会默认开启 TypeScript 类型检查。在大型项目中,类型检查的耗时可能远超过 Rspack 本身的构建耗时,因此在生产环境构建时,该行为会在一定程度上拖慢构建速度。

此时,可通过 output.disableTsChecker 关闭类型检查,以查看排除类型检查后 Rspack 性能是否符合预期。

大量 Less 文件

目前 Less 文件使用基于 JavaScript 实现的 less-loader 进行处理,未提供 Rust 版本,因此在处理大量 Less 文件时会拖累构建性能。

TIP

在使用 Arco Design 等组件库时,请尽量避免全量引入 Less 样式。你可以改为按需引入,或直接引入 CSS 样式。

大量 SVG 文件

Builder 默认支持将 SVG 资源作为 React 组件使用,这会产生一定的性能开销。如果你不需要此能力,可以将 output.disableSvgr 设置为 true 来关闭此行为,以提升构建性能。

组件库未按需引入

默认情况下,在使用 Ant DesignArco Design 组件库时,Builder 会自动开启按需引入功能,默认配置可参考 source.transformImport

在使用其他组件库时,如果该组件库支持按需引入,我们推荐优先通过 source.transformImport 配置按需引入。