插件开发
插件系统是 Rsbuild 架构的核心,Rsbuild 的大部分功能都是通过插件实现的,这种设计让核心保持轻量,同时提供了灵活的扩展性。
Rsbuild 插件是一个函数,它可以在不同阶段注册钩子,监听事件并执行自定义逻辑。无论你想要修改默认行为、添加新功能,还是集成第三方工具,插件都提供了丰富的 API 来实现这些需求。
对比其他插件
在开发 Rsbuild 插件之前,你可能已经接触过 webpack、Vite、esbuild 等工具的插件系统。
总体而言,Rsbuild 的插件 API 和 esbuild 相似,与 webpack 或 Rspack 插件相比,Rsbuild 的插件 API 更加简洁和容易上手。
从功能上看,Rsbuild 的插件 API 主要围绕 Rsbuild 的运行流程和构建配置,并提供一些 hooks 用于扩展。而 Rspack 的插件 API 则更加复杂和丰富,能够修改打包过程的每一个环节。
Rsbuild 插件中可以集成 Rspack 插件,如果 Rsbuild 提供的 hooks 无法满足你的需求,你也可以通过 Rspack 插件来实现功能,并在 Rsbuild 插件中注册 Rspack 插件:
开发插件
插件提供类似 (options?: PluginOptions) => RsbuildPlugin 的函数作为入口。
插件示例
注册插件:
插件结构
函数形式的插件可以 接受选项对象 并 返回插件实例,并通过闭包机制管理内部状态。
其中各部分的作用分别为:
name属性用于标注插件名称。setup作为插件逻辑的主入口。api对象包含了各类钩子和工具函数。
命名规范
插件的命名规范如下:
- 插件的函数命名为
pluginAbc,并通过具名导出。 - 插件的
name采用scope:foo-bar或plugin-foo-bar格式,添加scope:可以避免和其他插件产生命名冲突。
下面是一个例子:
Rsbuild 官方插件的 name 统一使用 rsbuild: 作为前缀,比如 rsbuild:react 对应 @rsbuild/plugin-react。
模板仓库
rsbuild-plugin-template 是一个最小的 Rsbuild 插件模板仓库,你可以基于该仓库来开发你的 Rsbuild 插件。
Environment 插件
Rsbuild 支持同时为多个环境构建产物,并支持某个插件仅在指定环境下运行。
当你希望你开发的插件支持作为 Environment 插件使用时,需要注意以下几点:
- 每个 environment 有自身的 Rsbuild 配置:
- 使用 environment 上下文 代替
getRsbuildConfig获取 environment 信息。 - 修改特定 environment 的 Rsbuild 配置时,优先使用 modifyEnvironmentConfig 代替 modifyRsbuildConfig ,以避免对其他 environments 产生影响。
- 使用 environment 上下文 代替
- 避免副作用,你的插件代码可能执行多次:
- 当同一个插件在不同环境下注册多次时,会被视为多个 Rsbuild 插件(哪怕它们指向同一个插件实例),这是因为它们带有不同的 Rsbuild environment 上下文。
下面是一个 Environment 插件例子:
引用其他插件
Rsbuild 的 plugins 配置项支持传入一个嵌套的数组,这意味着你可以通过这种方式在插件内部引用其他 Rsbuild 插件。
例如,在 pluginFoo 内部引用并注册 pluginBar:
生命周期钩子
Rsbuild 在内部按照约定的生命周期进行任务调度,插件可以通过注册钩子来介入工作流程的任意阶段,并实现自己的功能。
Rsbuild 生命周期钩子的完整列表参考 API 文档。
Rsbuild 不会接管底层 Rspack 的生命周期,相关生命周期钩子的使用方式见对应文档:Rspack Plugin API。
迁移 Vite 插件
参考 迁移 Vite 插件 了解如何迁移一个 Vite 插件到 Rsbuild 插件。
读写 Rsbuild 配置
当插件需要读取或修改项目的 Rsbuild 配置时,可以使用 Rsbuild 提供的配置 API。
修改基础配置
在 setup 中注册 api.modifyRsbuildConfig,可以在基础配置与各个 environment 的配置合并前对其进行修改:
modifyRsbuildConfig 是全局 hook。如果修改仅针对部分 environment,或需要根据当前 environment 调整配置,建议改用 api.modifyEnvironmentConfig。详细说明请参考全局 hooks 与 environment hooks。
读取规范化后的配置
配置修改 hooks 执行完毕后,可以无参数调用 api.getNormalizedConfig,获取包含所有 environment 的完整配置。该配置已经过规范化处理并包含默认值,类型也比 api.getRsbuildConfig 的返回值更明确。
如果当前没有 environment context,但需要读取某个 environment 的配置,可以将其名称传给 getNormalizedConfig:
返回值类型请参考 NormalizedConfig 和 NormalizedEnvironmentConfig。
读取当前环境的配置
当 hook 的回调参数中包含 environment context 时,建议通过 environment.config 获取配置。该配置由基础配置与当前 environment 的配置合并并经过规范化处理后得到。
读取所有环境的配置
onBeforeBuild 和 onAfterBuild 等全局 hooks 会提供 environments,其中包含所有 environment 的上下文。当插件需要读取每个 environment 的配置时,可以遍历该对象:
多环境配置的详细说明请参考多环境构建。
修改 Rspack 配置
Rsbuild 插件允许你修改内置的 Rspack 配置,包括:
- api.modifyRspackConfig:修改 Rspack 配置对象。
- api.modifyBundlerChain 通过 rspack-chain 来修改 Rspack 配置。
示例
比如,通过 Rsbuild 插件来注册 eslint-rspack-plugin:
扩展插件 API
当你基于 Rsbuild 的 JavaScript API 来实现自定义的工具时,可能希望在现有插件 API 的基础上,提供更多能力,例如添加工具方法或共享上下文对象。
此时,你可以使用 Rsbuild 实例上的 rsbuild.expose() 方法。它的作用与插件的 api.expose() 一致,用于向 Rsbuild 插件暴露自定义的方法或对象。
例如,向插件暴露 getState 和 setCount 方法:
然后,插件可以通过 api.useExposed() 方法访问这些扩展 API:
依赖声明
发布 Rsbuild 插件时,应该在 package.json 中声明 @rsbuild/core 的 peerDependencies,并在 devDependencies 中安装它用于开发:
如果插件只引用了 @rsbuild/core 的类型导出,可以将其声明为 optional peer dependency:
这种情况下,插件在被基于 Rsbuild 的上层工具(如 Rslib 或 Rspress)使用时,不会产生不必要的 peer dependency 警告。

