插件 API
本章节了介绍 Rsbuild 插件的 API 类型定义和使用方法。
RsbuildPlugin
插件对象的类型,插件对象包含以下属性:
name:插件的名称,唯一标识符。setup:插件逻辑的主入口函数,可以是一个异步函数。该函数仅会在初始化插件时执行一次。插件 API 对象上挂载了提供给插件使用的上下文数据、工具函数和注册生命周期钩子的函数,关于生命周期钩子的完整介绍,请阅读 插件 hooks 章节。apply: 控制插件在serve或build时生效,详见 条件启用。enforce: 指定插件的执行顺序,详见 enforce 属性。pre:声明前置插件的名称,这些插件会在当前插件之前执行,详见 前置插件。post:声明后置插件的名称,这些插件会在当前插件之后执行,详见 后置插件。remove:声明需要移除的插件,可以传入插件 name 的数组,详见 移除插件。
你可以从 @rsbuild/core 中导入该类型:
条件启用
默认情况下,插件在运行开发服务器和生产构建时都会生效。如果你希望一个插件只在其中某个场景下生效,你可以通过 apply 属性来指定插件的生效时机:
serve:运行开发或预览服务器时生效build:运行生产构建时生效
apply 属性也可以是一个函数,函数接收 config 和 context 两个参数。
apply 函数返回 true 来应用插件,返回 false 来跳过插件。
apply 属性是在 @rsbuild/core v1.4.8 版本中引入的。
enforce 属性
默认情况下,插件会按照添加顺序依次执行,插件可以通过添加 enforce 属性来调整执行顺序:
pre:在其他插件之前执行当前插件post:在其他插件之后执行当前插件
enforce 会影响钩子注册的顺序,但如果钩子指定了 order 属性,则 order 具有更高的优先级。
enforce 属性是在 @rsbuild/core v1.4.9 版本中引入的。
前置插件
通过设置 pre 属性可以强制指定某些插件在当前插件之前执行,pre 属性的优先级高于 enforce 属性。
比如有下面两个插件:
Bar 插件在 pre 属性中配置了 Foo 插件,因此 Foo 插件一定会在 Bar 插件之前执行。
后置插件
通过设置 post 属性可以强制指定某些插件在当前插件之后执行,post 属性的优先级高于 enforce 属性。
Bar 插件在 post 属性中配置了 Foo 插件,因此 Foo 插件一定会在 Bar 插件之后执行。
移除插件
通过 remove 属性可以在一个插件中移除其他插件。
比如同时注册上述的 Foo 和 Bar 插件,由于 Bar 插件声明 remove 了 Foo 插件,因此 Foo 插件不会生效。
需要注意的是:如果当前插件注册为特定环境插件,则仅支持移除同环境插件,不能移除全局插件。
api.context
api.context 是一个只读对象,提供一些上下文信息。
api.context 的内容与 rsbuild.context 完全一致,请参考 rsbuild.context。
- 示例:
api.getRsbuildConfig
获取 Rsbuild 配置。
- 类型:
- 参数:
你可以通过 type 参数来指定读取的 Rsbuild 配置类型:
- 调用时机:
在插件 setup 中即可获取 original 或 current 配置;获取 normalized 配置则需要等待配置规范化完成。
- 示例:
api.getNormalizedConfig
获取所有环境或指定环境的规范化 Rsbuild 配置。
与 getRsbuildConfig 相比,该方法返回经过规范化处理、类型更明确的配置。例如,config.html 的类型不再包含 undefined。
使用 getNormalizedConfig() 获取包含所有环境的完整配置。如需获取指定环境的配置,则使用 getNormalizedConfig({ environment: name })。
- 类型:
- 调用时机:
请在配置规范化完成后执行的钩子中调用,例如 modifyBundlerChain 或 onBeforeBuild。在 setup、modifyRsbuildConfig 和 modifyEnvironmentConfig 中,此方法尚不可用。
- 示例:
当插件钩子的回调参数中包含 environment 时,建议通过 environment.config 获取当前环境的规范化配置。该配置由基础配置与当前环境的配置合并并经过规范化处理后得到。
api.logger
提供统一日志输出格式的实例,可以用于输出与 Rsbuild 一致的日志格式。
详见 日志。
- 版本:
>= 1.4.0 - 示例:
api.isPluginExists
判断某个插件是否已经在当前 Rsbuild 实例中注册。
-
如果未指定
environment参数,则判断全局注册的插件中是否存在该插件。 -
如果指定了
environment参数,则同时检查全局注册的插件和在指定环境中注册的插件。 -
类型:
- 示例:
或者检查指定环境中是否存在插件:
api.transform
api.transform 是 Rspack loader 的简化封装,让你能够在构建过程中轻松转换特定模块的代码。
每次调用都会注册一个转换函数。你可以通过 descriptor 配置该函数的匹配条件和执行方式。
- 类型:
api.transform 接受两个参数:
descriptor:一个对象,用于配置转换函数的匹配条件和执行方式。handler:一个转换函数,接收模块当前的代码,并返回转换后的代码。
示例
比如匹配以 .pug 为后缀的模块,并转换为 JavaScript 代码:
descriptor 参数
descriptor 参数是一个对象,用于配置转换函数的匹配条件和执行方式。
- 类型:
descriptor 参数支持以下选项:
test
- 类型: RuleSetCondition
匹配模块的路径(不包含 query),等价于 Rspack 的 rules[].test。
codeFilter
- 类型:
string | RegExp - 版本:
>= 2.3.0
根据输入代码,决定是否执行本次 api.transform 注册的转换函数。代码中包含指定字符串或匹配指定正则表达式时,才会执行;否则会跳过当前转换函数,并将代码原样传递给后续处理。
例如,以下转换函数只处理代码中包含 console.log 的 JavaScript 模块:
匹配的是当前转换函数即将接收的代码。如果此前的 loader 或转换函数已修改代码,会使用修改后的内容进行匹配。该选项对应 Rspack 的 rules[].use.codeFilter。
targets
- 类型:
('web' | 'node' | 'web-worker')[]
匹配 Rsbuild output.target,仅对匹配的构建目标应用当前转换函数。
environments
- 类型:
string[]
匹配 Rsbuild environment 的名称,仅对匹配的环境应用当前转换函数。
resourceQuery
- 类型: RuleSetCondition
匹配模块的 query,等价于 Rspack 的 rules[].resourceQuery。
raw
- 类型:
boolean - 默认值:
false
当 raw 为 true 时,转换函数接收 Buffer 类型的代码;否则接收字符串类型的代码。
layer
- 类型:
string
将匹配的模块归入指定的 layer,等同于 Rspack 的 rules[].layer。
issuerLayer
- 类型:
string
匹配引入当前模块的模块所属的 layer,等同于 Rspack 的 rules[].issuerLayer。
issuer
- 类型: RuleSetCondition
匹配引入当前模块的模块的绝对路径,等同于 Rspack 的 rules[].issuer。
with
- 类型:
Record<string, RuleSetCondition>
匹配 import attributes,等同于 Rspack 的 rules[].with。
mimetype
- 类型: RuleSetCondition
根据 MIME 类型匹配模块,等同于 Rspack 的 rules[].mimetype。主要用于 data URI 模块,例如 data:text/javascript,...。
order
- 类型:
'pre' | 'post' | 'default' - 默认值:
'default'
指定转换函数的执行顺序,对应 Rspack 的 rules[].enforce。
- 当
order为pre时,转换函数会在其他转换函数(或 Rspack loader)之前执行。 - 当
order为post时,转换函数会在其他转换函数(或 Rspack loader)之后执行。 - 当
order为default时,转换函数会使用默认的 loader 顺序。
as
- 类型:
string - 版本:
>= 2.3.3
as 可以改变后续规则用于匹配当前文件的路径,从而让文件命中或跳过某些规则,等价于 Rspack 的 rules[].as。它只影响规则匹配,文件读取和 handler 处理仍使用原始资源。
as 的值是一个路径模板,其中的 [resource-path] 代表当前用于匹配的完整文件路径,包含扩展名。例如,[resource-path].js 会在当前匹配路径末尾追加 .js。
同时设置 as 和 order: 'pre' 时,Rsbuild 会将这条 transform 规则放在内置规则之前,使不同扩展名的文件可以复用已有的编译规则。例如,将 .template 文件的内容转换为 JavaScript,并复用内置 SWC 规则:
导入 ./example.template 时,它的匹配路径会变为 example.template.js,因此也会命中 SWC 规则。handler 先将内容转换为 JavaScript,再由 SWC 编译为配置的目标版本。
enforce
- 类型:
'pre' | 'post'
已废弃,请使用 order 代替。
handler 参数
handler 参数是一个转换函数,接收模块当前的代码,并返回转换后的代码。
- 类型:
handler 函数提供以下参数:
code:模块的代码。context:当前被处理的模块所在的目录路径,与 Rspack loader 的 this.context 相同。resolve:解析一个模块标识符。与 Rspack loader 的 this.resolve 相同。resource:模块的绝对路径,包含 query,与 Rspack loader 的 this.resource 相同。resourcePath:模块的绝对路径,不包含 query,与 Rspack loader 的 this.resourcePath 相同。resourceQuery:模块路径上的 query,与 Rspack loader 的 this.resourceQuery 相同。environment: 当前构建的 environment 上下文.addDependency:添加一个额外的文件作为依赖。该文件将被监听,并在发生变更时触发重新构建。与 Rspack loader 的 this.addDependency 相同。addMissingDependency:添加一个不存在的文件作为依赖。该文件将被监听,并在发生变更时触发重新构建。与 Rspack loader 的 this.addMissingDependency 相同。addContextDependency:添加一个额外的目录作为依赖。该目录将被监听,并在发生变更时触发重新构建。与 Rspack loader 的 this.addContextDependency 相同。emitFile:将一个文件输出到构建结果中。与 Rspack loader 的 this.emitFile 相同。importModule:在构建时编译并执行一个模块。与 Rspack loader 的 this.importModule 相同。
比如:
与 loader 的区别
api.transform 可以理解为 Rspack loader 的一个轻量化实现,它提供了简单易用的 API,并在底层自动调用 Rspack loader 进行代码转换。
在 Rsbuild 插件中,你可以通过 api.transform 快速实现代码转换功能,能够满足大部分常见场景,而无须学习 Rspack loader 的编写方法。
注意,对于一些复杂的代码转换场景,api.transform 可能无法满足,此时你可以使用 Rspack loader 进行实现。
Source maps
你可以在 transform 函数中返回一个 source map,Rsbuild 会自动将返回的 source map 与其他 Rspack loader 或 transform hook 生成的 source maps 合并,使最终的 source map 能够正确映射到原始源代码。
api.resolve
在模块解析开始之前,拦截并修改模块的请求信息。等价于 Rspack 的 normalModuleFactory.hooks.resolve hook。
- 类型:
示例
- 修改
a.js文件请求:
handler 参数
handler 参数是一个回调函数,接收一个模块的请求信息,并允许你修改它。
- 类型:
handler 函数提供以下参数:
resolveData:当前模块请求信息,详情可参考 Rspack - resolve 钩子。compiler:Rspack 的 Compiler 对象。compilation:Rspack 的 Compilation 对象。environment: 当前构建的 environment 上下文。
api.processAssets
在输出产物之前对 assets 进行修改,等价于 Rspack 的 compilation.hooks.processAssets hook。
- 类型:
api.processAssets 接受两个参数:
descriptor:一个对象,用于描述 processAssets 触发的 stage 和匹配条件。handler:一个回调函数,接收 assets 对象并允许你修改它。
示例
- 在
additional阶段输出一个新的 asset:
- 更新一个已经存在的 asset:
- 移除一个 asset:
descriptor 参数
descriptor 参数是一个对象,用于描述 processAssets 触发的 stage 和匹配条件。
- 类型:
descriptor 参数支持设置以下属性:
stage:Rspack 内部将 processAssets 划分为多个 stages(参考 process assets stages,你可以根据需要进行的操作来选择合适的 stage。
targets:匹配 Rsbuild output.target,仅对匹配的 targets 应用当前 processAssets 函数。
environments:匹配 Rsbuild environment name,仅对匹配的 environments 应用当前 processAssets 函数。
handler 参数
handler 参数是一个回调函数,接收一个 assets 对象,并允许你修改它。
- 类型:
handler 函数提供以下参数:
assets:一个对象,其中 key 是 asset 的路径名,值是由 Source 表示的 asset 数据。compiler:Rspack 的 Compiler 对象。compilation:Rspack 的 Compilation 对象。environment: 当前构建的 environment 上下文.sources:Rspack Sources 对象,它包含了多种表示 Sources 的 classes。
Process assets stages
下面是支持的 stage 列表,Rspack 会按由上至下的顺序依次执行这些 stages,请根据你需要进行的操作来选择合适的 stage。
additional— 在编译中添加额外的 asset。pre-process— asset 进行了基础的预处理。derived— 从现有 asset 中派生新的 asset。additions— 为现有的 asset 添加额外的内容,例如 banner 或初始代码。none— 在PROCESS_ASSETS_STAGE_NONE阶段运行,不指定专门的处理阶段。optimize— 以通用的方式优化现有 asset。optimize-count— 优化现有 asset 的数量,例如,进行合并操作。optimize-compatibility— 优化现有 asset 的兼容性,例如添加 polyfills 或者 vendor prefixes。optimize-size— 优化现有 asset 的大小,例如进行压缩或者删除空格。dev-tooling— 为 asset 添加开发者工具,例如,提取 source map。optimize-inline— 将 asset 内联到其他 asset 中来优化现有 asset 数量。summarize— 整理现有 asset 列表。optimize-hash— 优化 asset 的 hash 值,例如,生成基于 asset 内容的真实 hash 值。optimize-transfer— 优化已有 asset 的转换操作,例如对 asset 进行压缩,并作为独立的 asset。analyse— 分析已有 asset。report— 创建用于上报的 asset。
api.expose
用于插件间通信。
api.expose 可以显式暴露当前插件的一些属性或方法,其他插件可以通过 api.useExposed 来获取这些 API。
- 类型:
- 示例:
如果 api.expose 被多次调用且使用了相同的 id 和 environment,则后一次调用会覆盖前一次调用暴露的 API。
Environment 级别的 API
你可以通过设置 options.environment(对应 config.environments 的 key)为指定 environment 注册暴露的 API。
当在 environment plugin 中调用 api.useExposed 时,Rsbuild 会优先解析同一 environment 注册的 API,如果不存在,则回退到全局 API。
如果未设置 options.environment,则 API 会被注册为全局 API,可以作为所有 environment 中插件的 fallback。
api.useExposed
用于插件间通信。
api.useExposed 可以获取到其他插件暴露的属性或方法。
- 类型:
- 示例:
标识符
你可以使用 Symbol 作为唯一标识符,从而避免潜在的命名冲突:
类型声明
你可以通过函数的泛型来声明类型:
执行顺序
在进行插件间通信时,你需要留意插件的执行顺序。
比如,在上面的示例中,如果 pluginParent 未注册,或者注册顺序晚于 pluginChild,那么 api.useExposed('plugin-parent') 会返回一个 undefined。
你可以使用插件对象的 pre、post 选项,以及插件 hook 的 order 选项来保证顺序是正确的。

