Plugin Hooks
本章节介绍 Rsbuild 插件可用的 plugin hooks。
总览
Common Hooks
Dev Hooks
仅在执行 rsbuild dev
命令或 rsbuild.startDevServer()
方法时调用。
Build Hooks
仅在执行 rsbuild build
命令或 rsbuild.build()
方法时调用。
Preview Hooks
仅在执行 rsbuild preview
命令或 rsbuild.preview()
方法时调用。
Hooks 顺序
Dev Hooks
执行 rsbuild dev
命令或 rsbuild.startDevServer()
方法时,Rsbuild 会依次执行以下 hooks:
Build Hooks
执行 rsbuild build
命令或 rsbuild.build()
方法时,Rsbuild 会依次执行以下 hooks:
Preview Hooks
执行 rsbuild preview
命令或 rsbuild.preview()
方法时,Rsbuild 会依次执行以下 hooks:
回调函数顺序
默认行为
如果多个插件注册了相同的 hook,那么 hook 的回调函数会按照注册时的顺序执行。
在以下例子中,控制台会依次输出 '1'
和 '2'
:
const plugin1 = () => ({
setup: (api) => {
api.modifyRsbuildConfig(() => console.log('1'));
},
});
const plugin2 = () => ({
setup: (api) => {
api.modifyRsbuildConfig(() => console.log('2'));
},
});
rsbuild.addPlugins([plugin1, plugin2]);
order 字段
在注册 hook 时,可以通过 order
字段来声明 hook 的顺序。
type HookDescriptor<T extends (...args: any[]) => any> = {
handler: T;
order: 'pre' | 'post' | 'default';
};
在以下例子中,控制台会依次输出 '2'
和 '1'
,因为 plugin2 在调用 modifyRsbuildConfig 时设置了 order 为 pre
。
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
修改传递给 Rsbuild 的配置项,你可以直接修改传入的 config 对象,也可以返回一个新的对象来替换传入的对象。
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
修改最终的 Rspack 配置对象,你可以直接修改传入的 config 对象,也可以返回一个新的对象来替换传入的对象。
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
什么是 BundlerChain
Bundler chain 是 webpack chain 的子集,其中包含一部分 webpack chain API,你可以用它来同时修改 Rspack 和 webpack 的配置。
通过 bundler chain 修改的配置,在 Rspack 和 webpack 构建时均可生效。需要注意的是,bundler chain 只支持修改 Rspack 和 webpack 间无差异部分的配置。如,修改 devtool 配置项(Rspack 和 webpack 的 devtool 属性值类型相同),或添加一个Rspack 兼容的 webpack 插件。
modifyBundlerChain
用于调用 bundler chain 来修改 Rspack 的配置。
type ModifyBundlerChainUtils = {
env: NodeEnv;
isDev: boolean;
isProd: boolean;
target: RsbuildTarget;
isServer: boolean;
isWebWorker: boolean;
CHAIN_ID: ChainIdentifier;
HtmlPlugin: typeof import('html-webpack-plugin');
bundler: {
// 取决于 bundler 类型
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
是在创建底层 Compiler 实例前触发的回调函数,当你执行 rsbuild.startDevServer
、rsbuild.build
或 rsbuild.createCompiler
时,都会调用此钩子。
你可以通过 bundlerConfigs
参数获取到底层打包工具的最终配置数组:
- 如果当前打包工具为 Rspack,则获取到的是 Rspack 配置数组。
- 如果当前打包工具为 webpack,则获取到的是 webpack 配置数组。
- 配置数组中可能包含一份或多份配置,这取决于你是否开启了 SSR 等功能。
你可以通过 bundlerConfigs
参数获取到底层打包工具的最终配置对象。
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
是在创建 Compiler 实例后、执行构建前触发的回调函数,当你执行 rsbuild.startDevServer
、rsbuild.build
或 rsbuild.createCompiler
时,都会调用此钩子。
你可以通过 compiler
参数获取到 Compiler 实例对象:
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
是在执行生产环境构建前触发的回调函数,你可以通过 bundlerConfigs
参数获取到底层打包工具的最终配置数组:
-
如果当前打包工具为 Rspack,则获取到的是 Rspack 配置数组。
-
如果当前打包工具为 webpack,则获取到的是 webpack 配置数组。
-
配置数组中可能包含一份或多份配置,这取决于 Rsbuild 当前 target 配置的值。
-
类型:
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
是在执行生产环境构建后触发的回调函数,你可以通过 stats
参数获取到构建结果信息:
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
在启动开发服务器前调用。
function OnBeforeStartDevServer(callback: () => Promise<void> | void): void;
const myPlugin = () => ({
setup: (api) => {
api.onBeforeStartDevServer(() => {
console.log('before start!');
});
},
});
onAfterStartDevServer
在启动开发服务器后调用。你可以通过 port
参数获得开发服务器监听的端口号,通过 routes
获得页面路由信息。
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
在每次开发环境构建结束后调用,你可以通过 isFirstCompile
来判断是否为首次构建。
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
关闭开发服务器时调用。
function onCloseDevServer(callback: () => Promise<void> | void): void;
rsbuild.onCloseDevServer(async () => {
console.log('close dev server!');
});
Preview Hooks
onBeforeStartProdServer
在启动生产预览服务器前调用。
function OnBeforeStartProdServer(callback: () => Promise<void> | void): void;
const myPlugin = () => ({
setup: (api) => {
api.onBeforeStartProdServer(() => {
console.log('before start!');
});
},
});
onAfterStartProdServer
在启动生产预览服务器后调用,你可以通过 port
参数获得生产服务器监听的端口号,通过 routes
获得页面路由信息。
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
在进程即将退出时调用,这个钩子只能执行同步代码。
function OnExit(callback: () => void): void;
const myPlugin = () => ({
setup: (api) => {
api.onExit(() => {
console.log('exit!');
});
},
});