Configure Rspack

Rsbuild supports directly modifying the Rspack configuration object, and also supports modifying the built-in Rspack configuration of Rsbuild through rspack-chain.

TIP

The built-in Rspack config in Rsbuild may change with iterations, and these changes won't be reflected in semver. Therefore, your custom config may become invalid when you upgrade Rsbuild.

Modify Config Object

You can use the tools.rspack option of Rsbuild to modify the Rspack config object.

For example, register Rspack plugins or webpack plugins:

rsbuild.config.ts
export default {
  tools: {
    rspack: {
      plugins: [SomeWebpackPlugin()],
    },
  },
};

Or modify the Rspack config with a function:

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

Please refer to the tools.rspack documentation for detailed usage.

Use Bundler Chain

rspack-chain is a utility library for configuring Rspack. It provides a chaining API, making the configuration of Rspack more flexible. By using rspack-chain, you can more easily modify and extend Rspack configurations without directly manipulating the complex configuration object.

tools.bundlerChain

Rsbuild provides the tools.bundlerChain config to modify the rspack-chain. Its value is a function that takes two arguments:

  • The first argument is an rspack-chain instance, which you can use to modify the Rspack config.
  • The second argument is an utils object, including env, isProd, CHAIN_ID, etc.

Here's a basic example:

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

tools.bundlerChain can also be an async function:

rsbuild.config.ts
export default {
  tools: {
    bundlerChain: (chain, { env }) => {
      const value = await fetchValue();
      chain.devtool(value);
    },
  },
};

Basics

Before using the rspack-chain to modify the Rspack configuration, it is recommended to familiarize yourself with some basics.

About ID

In short, the rspack-chain requires users to set a unique ID for each rule, loader, plugin, and minimizer. With this ID, you can easily find the desired object from deeply nested objects.

Rsbuild exports all internally defined IDs through the CHAIN_ID object, so you can quickly locate the loader or plugin you want to modify using these exported IDs, without the need for complex traversal in the Rspack configuration object.

For example, you can remove the built-in HTML plugin using CHAIN_ID.PLUGIN.HTML:

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

ID Types

The CHAIN_ID object contains various IDs, which correspond to the following configurations:

CHAIN_ID Field Corresponding Configuration Description
CHAIN_ID.PLUGIN plugins[i] Corresponds to a plugin in the Rspack configuration
CHAIN_ID.RULE module.rules[i] Corresponds to a rule in the Rspack configuration
CHAIN_ID.USE module.rules[i].loader Corresponds to a loader in the Rspack configuration
CHAIN_ID.MINIMIZER optimization.minimizer Corresponds to a minimizer in the Rspack configuration
CHAIN_ID.RESOLVE_PLUGIN resolve.plugins[i] Corresponds to a resolve plugin in the Rspack configuration

Examples

Configure loader

Here are examples of adding, modifying, and removing Rspack loaders.

  • Add a loader to handle .md files:
rsbuild.config.mjs
export default {
  tools: {
    bundlerChain: (chain) => {
      chain.module
        .rule('md')
        .test(/\.md$/)
        .use('md-loader')
        // The package name or module path of the loader
        .loader('md-loader');
    },
  },
};
  • Modify options of the built-in SWC loader:
rsbuild.config.mjs
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      chain.module
        .rule(CHAIN_ID.RULE.JS)
        .use(CHAIN_ID.USE.SWC)
        .tap((options) => {
          console.log(options);
          return options;
        });
    },
  },
};
  • Remove the built-in SWC loader:
rsbuild.config.mjs
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      chain.module.rule(CHAIN_ID.RULE.JS).uses.delete(CHAIN_ID.USE.SWC);
    },
  },
};
  • Insert a loader after the built-in SWC loader that executes earlier:
rsbuild.config.mjs
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      chain.module
        .rule(CHAIN_ID.RULE.JS)
        .use('my-loader')
        .after(CHAIN_ID.USE.SWC)
        // The package name or module path of the loader
        .loader('my-loader')
        .options({
          // some options
        });
    },
  },
};

Note: Rspack loaders are executed in reverse order.

  • Insert a loader before the built-in SWC loader that executes later:
rsbuild.config.mjs
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      chain.module
        .rule(CHAIN_ID.RULE.JS)
        // Loader ID, not actually meaningful, just for locating
        .use('my-loader')
        .before(CHAIN_ID.USE.SWC)
        // The package name or module path of the loader
        .loader('my-loader')
        .options({
          // some options
        });
    },
  },
};
  • Remove the built-in CSS handling rule:
rsbuild.config.mjs
export default {
  tools: {
    bundlerChain: (chain, { CHAIN_ID }) => {
      chain.module.rules.delete(CHAIN_ID.RULE.CSS);
    },
  },
};

Configure Plugin

Here are examples of adding, modifying, and deleting Rspack plugins.

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

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

      // Delete plugin
      chain.plugins.delete(CHAIN_ID.PLUGIN.HMR);
    },
  },
};

Modify based on environment

In the tools.bundlerChain function, you can access various environment identifiers in the second parameter, such as development/production build, SSR build, Web Worker build, to achieve configuration modifications for different environments.

rsbuild.config.mjs
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) {
        // ...
      }
    },
  },
};

The above are some common configuration examples. For the complete rspack-chain API, please refer to the rspack-chain documentation.