Plugin Hooks
This chapter introduces the plugin hooks available for Rsbuild plugins.
Overview
Common Hooks
Dev Hooks
Called only when running the rsbuild dev
command or the rsbuild.startDevServer()
method.
Build Hooks
Called only when running the rsbuild build
command or the rsbuild.build()
method.
- onBeforeBuild: Called before running the production build.
- onAfterBuild: Called after running the production build. You can get the build result information.
Preview Hooks
Called only when running the rsbuild preview
command or the rsbuild.preview()
method.
Hooks Order
Dev Hooks
When the rsbuild dev
command or rsbuild.startDevServer()
method is executed, Rsbuild will execute the following hooks in order:
Build Hooks
When the rsbuild build
command or rsbuild.build()
method is executed, Rsbuild will execute the following hooks in order:
Preview Hooks
When executing the rsbuild preview
command or rsbuild.preview()
method, Rsbuild will execute the following hooks in order:
Callback Order
Default Behavior
If multiple plugins register the same hook, the callback functions of the hook will execute in the order in which they were registered.
In the following example, the console will output '1'
and '2'
in sequence:
const plugin1 = () => ({
setup: (api) => {
api.modifyRsbuildConfig(() => console.log('1'));
},
});
const plugin2 = () => ({
setup: (api) => {
api.modifyRsbuildConfig(() => console.log('2'));
},
});
rsbuild.addPlugins([plugin1, plugin2]);
order
Field
When registering a hook, you can declare the order of hook through the order
field.
type HookDescriptor<T extends (...args: any[]) => any> = {
handler: T;
order: 'pre' | 'post' | 'default';
};
In the following example, the console will sequentially output '2'
and '1'
, because order
was set to pre
when plugin2 called modifyRsbuildConfig
.
const plugin1 = () => ({
setup: (api) => {
api.modifyRsbuildConfig(() => console.log('1'));
},
});
const plugin2 = () => ({
setup: (api) => {
api.modifyRsbuildConfig({
handler: () => console.log('2'),
order: 'pre',
});
},
});
rsbuild.addPlugins([plugin1, plugin2]);
Common Hooks
modifyRsbuildConfig
Modify the config passed to the Rsbuild, you can directly modify the config object, or return a new object to replace the previous object.
type ModifyRsbuildConfigUtils = {
mergeRsbuildConfig: typeof mergeRsbuildConfig;
};
function ModifyRsbuildConfig(
callback: (
config: RsbuildConfig,
utils: ModifyRsbuildConfigUtils,
) => PromiseOrNot<RsbuildConfig | void>,
): void;
const myPlugin = () => ({
setup: (api) => {
api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => {
config.html = config.html || {};
config.html.title = 'Hello World!';
return mergeRsbuildConfig(config, {
source: { preEntry: 'foo.js' },
});
});
},
});
modifyRspackConfig
To modify the final Rspack config object, you can directly modify the config object, or return a new object to replace the previous object.
type ModifyRspackConfigUtils = {
env: NodeEnv;
isDev: boolean;
isProd: boolean;
target: RsbuildTarget;
isServer: boolean;
isWebWorker: boolean;
rspack: typeof import('@rspack/core');
};
function ModifyRspackConfig(
callback: (
config: RspackConfig,
utils: ModifyRspackConfigUtils,
) => Promise<RspackConfig | void> | RspackConfig | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.modifyRspackConfig((config, utils) => {
if (utils.env === 'development') {
config.devtool = 'eval-cheap-source-map';
}
});
},
});
modifyBundlerChain
Bundler chain is a subset of webpack chain, which contains part of the webpack chain API that you can use to modify both Rspack and webpack configuration.
modifyBundlerChain
is used to call the bundler chain to modify the Rspack configuration.
This hook only supports modifying the configuration of the non-differentiated parts of Rspack and webpack. For example, modifying the devtool configuration option (Rspack and webpack have the same devtool property value type), or adding an Rspack-compatible webpack plugin.
type ModifyBundlerChainUtils = {
env: NodeEnv;
isDev: boolean;
isProd: boolean;
target: RsbuildTarget;
isServer: boolean;
isWebWorker: boolean;
CHAIN_ID: ChainIdentifier;
HtmlPlugin: typeof import('html-webpack-plugin');
bundler: {
// Depends on bundler type
BannerPlugin: typeof webpack.BannerPlugin | typeof rspack.BannerPlugin;
DefinePlugin: typeof webpack.DefinePlugin | typeof rspack.DefinePlugin;
ProvidePlugin: typeof webpack.ProvidePlugin | typeof rspack.ProvidePlugin;
};
};
function ModifyBundlerChain(
callback: (
chain: BundlerChain,
utils: ModifyBundlerChainUtils,
) => Promise<void> | void,
): void;
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
const myPlugin = () => ({
setup: (api) => {
api.modifyBundlerChain((chain, utils) => {
if (utils.env === 'development') {
chain.devtool('eval');
}
chain.plugin('bundle-analyze').use(BundleAnalyzerPlugin);
});
},
});
onBeforeCreateCompiler
onBeforeCreateCompiler
is a callback function that is triggered after the Compiler instance has been created, but before the build process begins. This hook is called when you run rsbuild.startDevServer
, rsbuild.build
, or rsbuild.createCompiler
.
You can access the Compiler instance object through the compiler
parameter:
-
If the current bundler is Rspack, you will get the Rspack Compiler object.
-
If the current bundler is webpack, you will get the webpack Compiler object.
-
Type:
function OnBeforeCreateCompiler(
callback: (params: {
bundlerConfigs: WebpackConfig[] | RspackConfig[];
}) => Promise<void> | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.onBeforeCreateCompiler(({ bundlerConfigs }) => {
console.log('the bundler config is ', bundlerConfigs);
});
},
});
onAfterCreateCompiler
onAfterCreateCompiler
is a callback function that is triggered after the compiler instance has been created, but before the build process. This hook is called when you run rsbuild.startDevServer
, rsbuild.build
, or rsbuild.createCompiler
.
You can access the Compiler instance object through the compiler
parameter:
-
If the current bundler is Rspack, you will get the Rspack Compiler object.
-
If the current bundler is webpack, you will get the webpack Compiler object.
-
Type:
function OnAfterCreateCompiler(callback: (params: {
compiler: Compiler | MultiCompiler;
}) => Promise<void> | void;): void;
const myPlugin = () => ({
setup: (api) => {
api.onAfterCreateCompiler(({ compiler }) => {
console.log('the compiler is ', compiler);
});
},
});
Build Hooks
onBeforeBuild
onBeforeBuild
is a callback function that is triggered before the production build is executed. You can access the final configuration array of the underlying bundler through the `bundlerConfigs' parameter:
-
If the current bundler is Rspack, you will get an Rspack configuration array.
-
If the current bundler is webpack, you will get a webpack configuration array.
-
The configuration array can contain one or more configurations, depending on the current target
config of Rsbuild.
-
Type:
function OnBeforeBuild(
callback: (params: {
bundlerConfigs?: WebpackConfig[] | RspackConfig[];
}) => Promise<void> | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.onBeforeBuild(({ bundlerConfigs }) => {
console.log('the bundler config is ', bundlerConfigs);
});
},
});
onAfterBuild
onAfterBuild
is a callback function that is triggered after running the production build. You can access the build result information via the `stats' parameter:
-
If the current bundler is Rspack, you will get Rspack Stats.
-
If the current bundler is webpack, you will get webpack Stats.
-
Type:
function OnAfterBuild(
callback: (params: { stats?: Stats | MultiStats }) => Promise<void> | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.onAfterBuild(({ stats }) => {
console.log(stats?.toJson());
});
},
});
Dev Hooks
onBeforeStartDevServer
Called before starting the dev server.
function OnBeforeStartDevServer(callback: () => Promise<void> | void): void;
const myPlugin = () => ({
setup: (api) => {
api.onBeforeStartDevServer(() => {
console.log('before start!');
});
},
});
onAfterStartDevServer
Called after starting the dev server, you can get the port number with the port
parameter, and the page routes info with the routes
parameter.
type Routes = Array<{
entryName: string;
pathname: string;
}>;
function OnAfterStartDevServer(
callback: (params: { port: number; routes: Routes }) => Promise<void> | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.onAfterStartDevServer(({ port, routes }) => {
console.log('this port is: ', port);
console.log('this routes is: ', routes);
});
},
});
onDevCompileDone
Called after each development environment build, you can use isFirstCompile
to determine whether it is the first build.
function OnDevCompileDone(
callback: (params: {
isFirstCompile: boolean;
stats: Stats | MultiStats;
}) => Promise<void> | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.onDevCompileDone(({ isFirstCompile }) => {
if (isFirstCompile) {
console.log('first compile!');
} else {
console.log('re-compile!');
}
});
},
});
onCloseDevServer
Called when close the dev server.
function onCloseDevServer(callback: () => Promise<void> | void): void;
rsbuild.onCloseDevServer(async () => {
console.log('close dev server!');
});
Preview Hooks
onBeforeStartProdServer
Called before starting the production preview server.
function OnBeforeStartProdServer(callback: () => Promise<void> | void): void;
const myPlugin = () => ({
setup: (api) => {
api.onBeforeStartProdServer(() => {
console.log('before start!');
});
},
});
onAfterStartProdServer
Called after starting the production preview server, you can get the port number with the port
parameter, and the page routes info with the routes
parameter.
type Routes = Array<{
entryName: string;
pathname: string;
}>;
function OnAfterStartProdServer(
callback: (params: { port: number; routes: Routes }) => Promise<void> | void,
): void;
const myPlugin = () => ({
setup: (api) => {
api.onAfterStartProdServer(({ port, routes }) => {
console.log('this port is: ', port);
console.log('this routes is: ', routes);
});
},
});
Other Hooks
onExit
Called when the process is going to exit, this hook can only execute synchronous code.
function OnExit(callback: () => void): void;
const myPlugin = () => ({
setup: (api) => {
api.onExit(() => {
console.log('exit!');
});
},
});