使用 Rspack

Rspack - 高性能 Web 构建工具

Rspack 是一个基于 Rust 编写的高性能 JavaScript 打包工具, 它提供对 webpack 生态良好的兼容性,能够无缝替换 webpack, 并提供闪电般的构建速度。

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

Modern.js 提供开箱即用的 Rspack 支持,你可以在成熟的 webpack 和更快的 Rspack 之间进行切换。

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

初始化 Rspack 项目

Modern.js 新项目已默认启用 Rspack 构建,只需执行 初始化项目,即可创建一个 Rspack 项目:

$ npx @modern-js/create@latest myapp
? 请选择开发语言:TS
? 请选择包管理工具:pnpm

项目创建完成后,在项目中执行 pnpm run dev 即可体验项目,更多信息可参考快速上手

开启 Rspack 构建

从 Modern.js 2.59.0 版本起,在一个已有的 Modern.js 项目中,你仅需在 modern.config.ts 中添加以下配置,即可启用 Rspack 构建:

modern.config.ts
import { appTools, defineConfig } from '@modern-js/app-tools';

export default defineConfig({
  plugins: [
    appTools({
+     bundler: 'rspack',
    }),
  ],
});
TIP

如果你当前版本低于 2.59.0,可通过执行 npx modern upgrade 进行升级。

注意事项

在使用 Rspack 前,你需要了解以下事项:

  • Rspack 能够兼容大部分 webpack 插件和几乎所有的 loaders,但仍有少数 webpack 插件暂时无法使用,详见 Plugin 兼容

  • Rspack 默认基于 SWC 进行代码编译和压缩,在个别情况下,你可能会遇到 SWC 在边界场景的 bug,可以通过 SWC 的 issue 反馈。

配置迁移

Modern.js 中 tools.webpacktools.webpackChain 配置仅在 webpack 模式下生效,开启 Rspack 构建能力后,可根据实际使用场景决定是否修改为 tools.rspacktools.bundlerChain

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

修改转译配置

Modern.js 在 Rspack 模式下使用 Rspack builtin:swc-loader 进行代码转译。

Modern.js 已对 builtin:swc-loader 的常见配置提供了更方便的配置方式,如:通过 source.transformImport 配置组件库按需引入。如果对 builtin:swc-loader 有自定义配置的需求,可通过 tools.swc 进行配置:

import { defineConfig } from '@modern-js/app-tools';

export default defineConfig<'rspack'>({
  tools: {
    swc: {
      jsc: {
        externalHelpers: false,
      },
    },
  },
});
TIP

在启用 Rspack 构建时,babel-loader 默认不会被启用。如需添加 babel 插件,可通过 tools.babel 配置,此时会产生额外的编译开销,在一定程度上拖慢 Rspack 构建速度。

Rspack 和 Modern.js 的版本关系

通常情况下,Modern.js 内会集成 Rspack 的最新版本,通过 npx modern upgrade 即可将当前项目中的 Modern.js 相关依赖以及内置的 Rspack 更新至最新版本。

但 Modern.js 对于 Rspack 的依赖方式为锁版本方式(非自动升级),由于发版周期不同步等原因,可能会出现 Modern.js 内集成的 Rspack 版本落后于 Rspack 最新版本的情况。

当你执行 dev / build 命令时,Modern.js 会在开启调试模式时自动打印当前使用的 Rspack 版本:

rspack_version_log

修改内置 Rspack 版本

可以使用 pnpm / yarn / npm 等包管理工具自带的依赖升级功能来将 Rspack 强制升级到指定版本。

以 pnpm 为例,可通过 overrides 修改内置的 Rspack 版本。假设需要指定 Rspack 的版本为 0.7.5:

package.json
{
  "pnpm": {
    "overrides": {
      "@rspack/binding": "0.7.5",
      "@rspack/core": "0.7.5",
      "@rspack/plugin-react-refresh": "0.7.5"
    }
  }
}

如果需要使用 Rspack 的 nightly/canary 版本,Rspack 的 nightly/canary 版本的包名会在增加 -canary 后缀之后发布,需要修改为:

package.json
{
  "pnpm": {
    "overrides": {
      "@rspack/binding": "npm:@rspack/binding-canary@nightly",
      "@rspack/core": "npm:@rspack/core-canary@nightly",
      "@rspack/plugin-react-refresh": "npm:@rspack/plugin-react-refresh@nightly"
    },
    "peerDependencyRules": {
      "allowAny": ["@rspack/*"]
    }
  }
}

Rspack 提供了 install-rspack 工具来快速修改 Rspack 版本:

npx install-rspack --version nightly # nightly npm tag
npx install-rspack --version 0.7.5-canary-d614005-20240625082730 # A specific canary version
Nightly 版本介绍

每天,Rspack 会自动构建基于最新代码的 nightly 版本,用于测试和及早发现错误。

通常情况下,这些版本是可用的。如果发现问题,我们会及时进行修复。但如果 Rspack 有一些 breaking change、需要 Modern.js 同步修改代码,那么我们建议等待下一个 Modern.js 版本再进行更新。

如果想了解其他包管理工具锁定依赖版本的示例,可以参考:锁定子依赖