配置 Rspack

Rsbuild 支持直接修改 Rspack 配置对象,也支持通过 rspack-chain 来修改 Rsbuild 内置的 Rspack 配置。

TIP

Rsbuild 内置的 Rspack 配置会随着迭代而发生变化,这些变化不会反映在 semver 中,因此在升级 Rsbuild 时,你的自定义配置可能会失效。

修改配置对象

你可以使用 Rsbuild 的 tools.rspack 选项来修改 Rspack 配置对象。

比如注册 Rspack 插件或 webpack 插件:

rsbuild.config.ts

  1. export default {
  2. tools: {
  3. rspack: {
  4. plugins: [SomeWebpackPlugin()],
  5. },
  6. },
  7. };

比如以函数的形式修改 Rspack 配置:

rsbuild.config.ts

  1. export default {
  2. tools: {
  3. rspack: (config, { env }) => {
  4. if (env === 'development') {
  5. config.devtool = 'cheap-module-eval-source-map';
  6. }
  7. return config;
  8. },
  9. },
  10. };

请查看 tools.rspack 文档 来了解完整用法。

使用 Rspack Chain

rspack-chain 是一个用于配置 Rspack 的工具库。它提供了链式 API,使得配置 Rspack 变得更加灵活。通过使用 rspack-chain,你可以更方便地修改和扩展 Rspack 配置,而不需要直接操作复杂的配置对象。

tools.bundlerChain

Rsbuild 提供了 tools.bundlerChain 配置项来修改 rspack-chain。

tools.bundlerChain 的值是一个函数,接收两个参数:

  • 第一个参数为 rspack-chain 实例,你可以通过 它来修改默认的 Rspack 配置。
  • 第二个参数为一个工具对象,包括 envisProdCHAIN_ID 等。

下面是一个基本示例:

rsbuild.config.ts

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { env }) => {
  4. if (env === 'development') {
  5. chain.devtool('cheap-module-eval-source-map');
  6. }
  7. },
  8. },
  9. };

tools.bundlerChain 还可以是一个异步函数:

rsbuild.config.ts

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { env }) => {
  4. const value = await fetchValue();
  5. chain.devtool(value);
  6. },
  7. },
  8. };

背景知识

在开始使用 rspack-chain 来修改 Rspack 配置之前,请先了解一些背景知识。

关于 ID

简单来说,rspack-chain 要求使用者为每个 Rule、Loader、Plugin、Minimizer 都设置一个独一无二的 id,通过这个 id,就可以便捷地从嵌套层级很深的对象中找到所需的对象。

Rsbuild 将内部定义的全部 id 都通过 CHAIN_ID 对象导出,因此你可以通过这些导出的 id,快速定位到你想要修改的 Loader 或 Plugin,而不需要在 Rspack 配置对象里通过复杂的遍历寻找。

比如通过 CHAIN_ID.PLUGIN.HTML 来删除内置的 HTML 插件:

rsbuild.config.ts

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { CHAIN_ID }) => {
  4. //
  5. chain.plugins.delete(CHAIN_ID.PLUGIN.HTML);
  6. },
  7. },
  8. };

ID 类型

CHAIN_ID 对象包含了多种 id,对应的含义如下:

CHAIN_ID 字段 对应的配置 描述
CHAIN_ID.PLUGIN plugins[i] 对应 Rspack 配置中的一个插件
CHAIN_ID.RULE module.rules[i] 对应 Rspack 配置中的一个 Rule
CHAIN_ID.USE module.rules[i].loader 对应 Rspack 配置中的一个 Loader
CHAIN_ID.MINIMIZER optimization.minimizer 对应 Rspack 配置中的一个压缩工具
CHAIN_ID.RESOLVE_PLUGIN resolve.plugins[i] 对应 Rspack 配置中的一个 Resolve 插件

示例

配置 loader

下面是新增、修改和删除 Rspack loader 的示例。

  • 新增一个 loader 来处理 .md 文件:

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain) => {
  4. chain.module
  5. .rule('md')
  6. .test(/\.md$/)
  7. .use('md-loader')
  8. // loader 的包名或模块路径
  9. .loader('md-loader');
  10. },
  11. },
  12. };
  • 修改内置的 SWC loader 选项:

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { CHAIN_ID }) => {
  4. chain.module
  5. .rule(CHAIN_ID.RULE.JS)
  6. .use(CHAIN_ID.USE.SWC)
  7. .tap((options) => {
  8. console.log(options);
  9. return options;
  10. });
  11. },
  12. },
  13. };
  • 删除内置的 SWC loader:

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { CHAIN_ID }) => {
  4. chain.module.rule(CHAIN_ID.RULE.JS).uses.delete(CHAIN_ID.USE.SWC);
  5. },
  6. },
  7. };
  • 在内置的 SWC loader 之后插入一个 loader,它会早于 SWC loader 执行:

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { CHAIN_ID }) => {
  4. chain.module
  5. .rule(CHAIN_ID.RULE.JS)
  6. .use('my-loader')
  7. .after(CHAIN_ID.USE.SWC)
  8. // loader 的包名或模块路径
  9. .loader('my-loader')
  10. .options({
  11. // some options
  12. });
  13. },
  14. },
  15. };

注意:Rspack 的 loader 是以相反顺序执行的。

  • 在内置的 SWC loader 之前插入一个 loader,它会晚于 SWC loader 执行:

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { CHAIN_ID }) => {
  4. chain.module
  5. .rule(CHAIN_ID.RULE.JS)
  6. // loader id,没有实际意义,仅用于定位
  7. .use('my-loader')
  8. .before(CHAIN_ID.USE.SWC)
  9. // loader 的包名或模块路径
  10. .loader('my-loader')
  11. .options({
  12. // some options
  13. });
  14. },
  15. },
  16. };
  • 删除内置的 CSS 处理规则:

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { CHAIN_ID }) => {
  4. chain.module.rules.delete(CHAIN_ID.RULE.CSS);
  5. },
  6. },
  7. };

配置 Plugin

下面是新增、修改和删除 Rspack 插件的示例。

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { bundler, CHAIN_ID }) => {
  4. // 新增插件
  5. chain.plugin('custom-define').use(bundler.DefinePlugin, [
  6. {
  7. 'process.env': {
  8. NODE_ENV: JSON.stringify(process.env.NODE_ENV),
  9. },
  10. },
  11. ]);
  12. // 修改插件
  13. chain.plugin(CHAIN_ID.PLUGIN.HMR).tap((options) => {
  14. options[0].fullBuildTimeout = 200;
  15. return options;
  16. });
  17. // 删除插件
  18. chain.plugins.delete(CHAIN_ID.PLUGIN.HMR);
  19. },
  20. },
  21. };

根据环境修改

tools.bundlerChain 函数的第二个参数中,你可以拿到各种环境的标识,如开发/生产模式构建、 SSR 构建、Web Worker 构建,从而实现不同环境下的配置修改。

rsbuild.config.mjs

  1. export default {
  2. tools: {
  3. bundlerChain: (chain, { env, isProd, target, isServer, isWebWorker }) => {
  4. if (env === 'development' || env === 'test') {
  5. // ...
  6. }
  7. if (isProd) {
  8. // ...
  9. }
  10. if (target === 'node') {
  11. // ...
  12. }
  13. if (isServer) {
  14. // ...
  15. }
  16. if (isWebWorker) {
  17. // ...
  18. }
  19. },
  20. },
  21. };

以上是一些常见的配置示例,完整的 API 请见 rspack-chain 文档

配置修改顺序

Rsbuild 支持通过 tools.rspacktools.bundlerChainmodifyBundlerChain 等方式修改 Rspack 配置对象。

它们之间的执行顺序依次为: