配置 Rspack

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

修改 Rspack 配置对象

你可以使用 Rsbuild 的 tools.rspack 选项来修改 Rspack 配置对象,请查看 tools.rspack 文档 来了解完整用法。

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

使用 Bundler Chain

Bundler chain 是 webpack chain 的子集,其中包含一部分 webpack chain API,你可以用它来同时修改 Rspack 和 webpack 的配置。

通过 bundler chain 修改的配置,在 Rspack 和 webpack 构建时均可生效。需要注意的是,bundler chain 只支持修改 Rspack 和 webpack 间无差异部分的配置。如,修改 devtool 配置项(Rspack 和 webpack 的 devtool 属性值类型相同),或添加一个Rspack 兼容 的 webpack 插件。

相较于直接修改 Rspack 配置对象,bundler-chain 不仅支持链式调用,并且能够基于 id 来修改内置的 rule 或 plugin.

tools.bundlerChain

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

tools.bundlerChain 的值为 Function 类型,接收两个参数:

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

下面是一个基本示例:

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

基础知识

在开始使用 bundler-chain 来修改 Rspack 配置之前,建议你先了解一些基础知识。

bundler-chain 是如何快速定位的

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

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

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

rsbuild.config.ts
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      //
      chain.plugins.delete(CHAIN_ID.PLUGIN.HTML);
    },
  },
};

bundler-chain 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 的示例。

rsbuild.config.ts
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      // 新增 loader
      chain.module
        .rule('md')
        .test(/\.md$/)
        .use('md-loader')
        .loader('md-loader');

      // 修改 loader
      chain.module
        .rule(CHAIN_ID.RULE.JS)
        .use(CHAIN_ID.USE.BABEL)
        .tap((options) => {
          options.plugins.push('babel-plugin-abc');
          return options;
        });

      // 删除 loader
      chain.module.rule(CHAIN_ID.RULE.JS).uses.delete(CHAIN_ID.USE.BABEL);
    },
  },
};

配置 Plugin

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

rsbuild.config.ts
export default {
  tools: {
    bundlerChain: (chain, { bundler, CHAIN_ID }) => {
      // 新增插件
      chain.plugin('custom-define').use(bundler.DefinePlugin, [
        {
          'process.env': {
            NODE_ENV: JSON.stringify(process.env.NODE_ENV),
          },
        },
      ]);

      // 修改插件
      chain.plugin(CHAIN_ID.PLUGIN.HMR).tap((options) => {
        options[0].fullBuildTimeout = 200;
        return options;
      });

      // 删除插件
      chain.plugins.delete(CHAIN_ID.PLUGIN.HMR);
    },
  },
};

根据环境修改

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

rsbuild.config.ts
export default {
  tools: {
    bundlerChain: (chain, { env, isProd, target, isServer, isWebWorker }) => {
      if (utils.env === 'development' || utils.env === 'test') {
        // ...
      }
      if (utils.isProd) {
        // ...
      }
      if (utils.target === 'node') {
        // ...
      }
      if (utils.isServer) {
        // ...
      }
      if (utils.isWebWorker) {
        // ...
      }
    },
  },
};

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