close

从 v1 升级到 v2

当前文档列出了从 Rsbuild 1.x 到 2.0 的所有不兼容更新,你可以参考此文档来迁移。

本指南仍在持续完善中。随着 Rsbuild 2.0 Beta 的推进,相关内容将逐步补充。

使用 Agent Skills

如果你在使用支持 Skills 的 Coding Agent,可以安装 rsbuild-v2-upgrade 技能来辅助完成 v1 到 v2 的升级流程。

npx skills add rstackjs/agent-skills --skill rsbuild-v2-upgrade

安装后,让 Coding Agent 协助完成升级即可。

升级 Rsbuild 到 v2

  • @rsbuild/core 升级到 2.0 Beta 版本:
{
  "devDependencies": {
-   "@rsbuild/core": "^1.0.0",
+   "@rsbuild/core": "^2.0.0-beta.0"
  }
}
  • 将 Rsbuild 插件升级到最新版本:
# 升级当前目录
npx taze major --include /rsbuild/ -w

# 或递归升级整个 monorepo
npx taze major --include /rsbuild/ -w -r

Rspack v2

Rsbuild v2 现在依赖 @rspack/core v2,如果你使用了自定义的 Rspack 配置或插件,可能需要进行相应的调整。

参考 Rspack v2 升级指南 了解所有不兼容更新。

默认 browserslist 更新

在 Rsbuild 2.0 中,默认的 browserslist 已进行更新,以更好地反映现代 Web 平台的基线水平。

Web 产物

默认的 Web browserslist 已升级到更现代的 Baseline。新的默认值对应于 baseline widely available on 2025-05-01

  • Chrome 87 → 107
  • Edge 88 → 107
  • Firefox 78 → 104
  • Safari 14 → 16

这一变化会影响 JavaScript 和 CSS 的转换结果,以及 polyfill 的注入方式。

如果你的项目已经定义了自己的 browserslist 配置,例如通过 .browserslistrcpackage.json#browserslist,Rsbuild 将继续使用该配置。默认值只会在未检测到任何 browserslist 配置时生效。

如果你希望保持之前的行为,可以在项目根目录创建一个 .browserslistrc 文件:

.browserslistrc
chrome >= 87
edge >= 88
firefox >= 78
safari >= 14

Node 产物

Rsbuild 2.0 也更新了默认的 Node.js 产物版本。由于 Node.js 18 已于 2025 年 4 月 结束维护,Rsbuild 现在默认使用 Node 20+。

  • Node 16 → 20

如果你希望保持之前的行为,可以通过 output.overrideBrowserslist 进行配置:

rsbuild.config.ts
export default {
  output: {
    target: 'node',
    overrideBrowserslist: ['node >= 16'],
  },
};

Node.js 支持

Rsbuild 2.0 最低支持的 Node.js 版本为 20.19+ 或 22.12+,不再支持 Node.js 18。

Pure ESM 包

@rsbuild/core 现已以 pure ESM 包的形式发布,并移除了自身的 CommonJS 构建产物。这一调整仅影响 Rsbuild 本身的发布形式,使安装体积减少了约 500KB。

在 Node.js 20 及以上版本中,运行时已原生支持通过 require(esm) 加载 ESM 模块。因此,对大多数仍通过 JavaScript API 使用 Rsbuild 的项目来说,这一变更通常不会带来实际影响,也无需额外修改现有代码。

这一变更不影响 Rsbuild 构建 CommonJS 产物的能力,相关的构建行为和配置方式也保持不变。

Polyfill 依赖变更

core-js@rsbuild/core 的默认依赖变更为可选的 peer 依赖,这减少了 1.2MB 的安装体积。

如果你启用了 output.polyfill,请在项目中安装 core-js v3:

npm
yarn
pnpm
bun
deno
npm add core-js

配置

默认 host 变更

server.host 的默认值从 '0.0.0.0' 变更为 'localhost'

这防止了开发服务器默认暴露在局域网中,从而确保了"默认安全"。

如果你需要从同一局域网内的其他设备访问服务器(例如进行移动端测试),可以将 host 手动设置为 '0.0.0.0'

rsbuild.config.ts
export default {
  server: {
    host: '0.0.0.0',
  },
};

你也可以使用 CLI 的 --host 选项来开启网络访问:

rsbuild dev --host

Node 产物

output.targetnode 时,Rsbuild 2.0 会通过 output.module 默认输出 ESM 产物,并保持 output.minify 关闭。在 Rsbuild 1.x 中,默认行为是输出 CommonJS 且开启压缩。

该调整更贴近 Node 的现代 ESM 生态,同时保留更清晰的调试堆栈与排查体验。

因此运行时需要支持加载 ESM(例如在 package.json 中设置 "type": "module" 或输出 .mjs 文件),否则需要显式切回 CommonJS。

如果你希望恢复 v1 的行为,可以显式禁用 ESM 并开启压缩:

rsbuild.config.ts
export default {
  output: {
    target: 'node',
    module: false,
    minify: true,
  },
};

移除 source.alias

废弃的 source.alias 选项已被移除,使用 resolve.alias 进行替代。

rsbuild.config.ts
export default {
- source: {
+ resolve: {
    alias: {
      '@': './src',
    },
  },
};

移除 source.aliasStrategy

废弃的 source.aliasStrategy 选项已被移除,使用 resolve.aliasStrategy 进行替代。

rsbuild.config.ts
export default {
- source: {
+ resolve: {
    aliasStrategy: 'prefer-alias',
  },
};

移除 performance.bundleAnalyze

废弃的 performance.bundleAnalyze 选项已被移除。

早期 Rsbuild 内置了 webpack-bundle-analyzer,但如今 Rsdoctor 已支持产物体积分析,因此无需在 @rsbuild/core 中继续内置;同时移除内置依赖可以降低安装体积。

推荐使用 Rsdoctor 分析产物体积,或通过 tools.rspack 自行注册 webpack-bundle-analyzer

rsbuild.config.ts
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

export default {
  tools: {
    rspack: {
      plugins: [
        new BundleAnalyzerPlugin({
          analyzerMode: 'static',
        }),
      ],
    },
  },
};

移除 performance.removeMomentLocale

performance.removeMomentLocale 选项已被移除。

该选项原本用于从产物中移除 Moment.js 的语言包。但在 Rspack v2 中,Moment 的 locales 默认不会被打包,因此该选项已不再需要。

背景信息可参考 web-infra-dev/rsbuild#6991

移除 performance.profile

performance.profile 选项已被移除。如果你依赖它来输出 stats JSON 文件,可以在自定义插件中调用 stats.toJson() 代替:

rsbuild.config.ts
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';

const statsJsonPlugin = {
  name: 'stats-json-plugin',
  setup(api) {
    api.onAfterBuild(({ stats }) => {
      writeFileSync(
        join(api.context.distPath, 'stats.json'),
        JSON.stringify(stats?.toJson({}), null, 2),
      );
    });
  },
};

export default {
  plugins: [statsJsonPlugin],
};

迁移 performance.chunkSplit

performance.chunkSplit 已在 Rsbuild 2.0 中废弃,但暂未移除,仍可继续使用。

我们推荐使用新的 splitChunks 选项代替它,新选项对齐了 Rspack 的 optimization.splitChunks 配置,并提供了与 performance.chunkSplit.strategy 相似的预设选项。

strategy

  • strategy: 'split-by-experience'splitChunks.preset: 'default'
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      strategy: 'split-by-experience',
-    },
-  },
+  splitChunks: {
+    preset: 'default',
+  },
};
  • strategy: 'split-by-module'splitChunks.preset: 'per-package'
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      strategy: 'split-by-module',
-    },
-  },
+  splitChunks: {
+    preset: 'per-package',
+  },
};
  • strategy: 'single-vendor'splitChunks.preset: 'single-vendor'
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      strategy: 'single-vendor',
-    },
-  },
+  splitChunks: {
+    preset: 'single-vendor',
+  },
};
  • strategy: 'all-in-one' → 关闭拆包
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      strategy: 'all-in-one',
-    },
-  },
+  splitChunks: false,
};
  • strategy: 'custom' + splitChunkssplitChunks.preset: 'none'
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      strategy: 'custom',
-      splitChunks: {
-        // ...
-      },
-    },
-  },
+  splitChunks: {
+    preset: 'none',
+    // ...
+  },
};
  • strategy: 'split-by-size' → 直接配置 minSize / maxSize
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      strategy: 'split-by-size',
-      minSize: 20000,
-      maxSize: 50000,
-    },
-  },
+  splitChunks: {
+    preset: 'none',
+    minSize: 20000,
+    maxSize: 50000,
+  },
};
  • override → 直接使用 splitChunks
rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      override: {
-        // ...
-      },
-    },
-  },
+  splitChunks: {
+    // ...
+  },
};

forceSplitting

forceSplitting 是对 cacheGroups 的语法糖,可以直接替换为 cacheGroups

rsbuild.config.ts
export default {
-  performance: {
-    chunkSplit: {
-      forceSplitting: {
-        axios: /node_modules[\\/]axios/,
-      },
-    },
-  },
+  splitChunks: {
+    cacheGroups: {
+      axios: {
+        test: /node_modules[\\/]axios/,
+        name: 'axios',
+        chunks: 'all',
+        priority: 0, // 使用 single-vendor 时可设置为 1
+        enforce: true,
+      },
+    },
+  },
};

Proxy 中间件升级

Rsbuild 依赖的 http-proxy-middleware 从 v2 升级到了 v3,个别配置项发生了变化。

你可以根据以下示例进行迁移,或查看 http-proxy-middleware v3 迁移指南 了解更多细节。

  • context 选项替换为 pathFilter
rsbuild.config.ts
export default {
  server: {
    proxy: [
      {
-       context: '/api',
+       pathFilter: '/api',
        target: 'https://example.com',
      },
    ],
  },
};
  • 事件改为使用 on 统一配置:
rsbuild.config.ts
export default {
  server: {
    proxy: {
      '/api': {
-       onOpen: () => {},
-       onClose: () => {},
-       onError: () => {},
-       onProxyReq: () => {},
-       onProxyRes: () => {},
+       on: {
+         open: () => {},
+         close: () => {},
+         error: () => {},
+         proxyReq: () => {},
+         proxyRes: () => {},
+       },
      },
    },
  },
};

JavaScript API

  • 移除 rsbuild.build() 中废弃的 compiler 参数
  • 移除 rsbuild.startDevServer() 中废弃的 compiler 参数
  • 移除 sockWrite 中废弃的 content-changed 消息类型,使用 static-changed 代替
  • loadConfig 方法的 loader 参数的默认值从 jiti 变更为 auto,优先使用原生 Node.js 加载器

移除 webpack 支持

Rsbuild 2.0 不再支持使用 webpack 作为打包工具。在 Rsbuild 1.x 版本中,该能力主要用于验证 Rspack 与 webpack 之间的兼容性。随着 Rspack 的逐步成熟和稳定,这一用途已不再必要,因此相关支持被正式移除。

具体变更如下:

  • 移除 @rsbuild/webpack 包。
  • 移除 @rsbuild/plugin-webpack-swc 包。
  • 移除 provider 配置项。
  • 移除 tools.webpacktools.webpackChain 配置项。
  • 移除 api.modifyWebpackChainapi.modifyWebpackConfig 插件钩子。
  • 移除 api.context.bundlerType 中的 webpack 类型。
  • 移除 webpack 相关的类型。

内置规则变化

Rsbuild 内置的 JS 和 CSS 转换规则现在使用了 oneOf 来区分不同的分支,如果你使用 tools.bundlerChainapi.modifyBundlerChain 修改了 JS 或 CSS 规则,可能需要进行相应调整。

JS 规则

内置 JS 规则现在拆分为两个 oneOf 分支:

  • CHAIN_ID.ONE_OF.JS_MAIN:用于 SWC 转换
  • CHAIN_ID.ONE_OF.JS_RAW:用于处理 ?raw 导入

如果你之前在 CHAIN_ID.RULE.JS 上添加 loader,需要迁移到 JS_MAIN 分支:

rsbuild.config.ts
export default {
  tools: {
    bundlerChain(chain, { CHAIN_ID }) {
      const jsRule = chain.module.rule(CHAIN_ID.RULE.JS);

-     jsRule.use('my-loader').loader('my-loader');
+     jsRule
+       .oneOf(CHAIN_ID.ONE_OF.JS_MAIN)
+       .use('my-loader')
+       .loader('my-loader');
    },
  },
};

CSS 规则

内置 CSS 规则拆分为三个 oneOf 分支:

  • CHAIN_ID.ONE_OF.CSS_MAIN:常规 CSS 转换
  • CHAIN_ID.ONE_OF.CSS_RAW:用于处理 ?raw 导入
  • CHAIN_ID.ONE_OF.CSS_INLINE:用于处理 ?inline 导入

如果你之前在 CHAIN_ID.RULE.CSS 上添加 loader,需要迁移到 CSS_MAIN 分支:

rsbuild.config.ts
export default {
  tools: {
    bundlerChain(chain, { CHAIN_ID }) {
      const cssRule = chain.module.rule(CHAIN_ID.RULE.CSS);

-     cssRule.use('my-css-loader').loader('my-css-loader');
+     cssRule
+       .oneOf(CHAIN_ID.ONE_OF.CSS_MAIN)
+       .use('my-css-loader')
+       .loader('my-css-loader');
    },
  },
};

Less / Sass / Stylus 插件的内置规则也已采用相同的 oneOf 结构,修改规则时请使用对应的 ONE_OF 分支。

其他

  • 查询参数 ?__inline=false 已被移除,使用 ?url 代替。
  • html.templateParameters 中废弃的默认参数已被移除:
    • webpackConfig:使用 rspackConfig 代替。
    • htmlWebpackPlugin:使用 htmlPlugin 代替。