.scss 或 .yaml。在 Bun 的打包器上下文中,插件还可以用来实现框架级功能,如 CSS 提取、宏和客户端-服务器代码共置。
生命周期钩子
插件可以注册回调函数,在打包流程的各个阶段运行:onStart():打包器开始打包时运行onResolve():模块解析前运行onLoad():模块加载前运行onBeforeParse():在文件解析前,在解析线程中零拷贝运行原生插件。
参考
类型的粗略概览(完整类型定义请参见 Bun 的bun.d.ts):
使用方法
插件被定义为一个简单的 JavaScript 对象,包含name 属性和 setup 函数。
Bun.build 的 plugins 数组中。
插件生命周期
命名空间
onLoad 和 onResolve 接受一个可选的 namespace 字符串。什么是命名空间?
每个模块都有一个命名空间。命名空间用于在转译后的代码中为导入前缀,例如,有一个 filter: /\.yaml$/ 和 namespace: "yaml:" 的加载器,会把 ./myfile.yaml 的导入转换为 yaml:./myfile.yaml。
默认命名空间是 "file",通常不必指定。例如:import myModule from "./my-module.ts" 等同于 import myModule from "file:./my-module.ts"。
其他常见命名空间包括:
"bun":Bun 特定模块(如"bun:test"、"bun:sqlite")"node":Node.js 模块(如"node:fs"、"node:path")
onStart
Promise。打包流程初始化后,打包器会等待所有 onStart() 回调完成后才继续。
例如:
onStart()(睡眠 10 秒)和第二个 onStart()(将打包时间写入文件)都完成后再继续。
注意,onStart() 回调(以及其他生命周期回调)不能修改 build.config 对象。如果需要修改配置,必须直接在 setup() 函数中操作。
onResolve
onResolve() 插件生命周期回调允许你配置模块的解析方式。
onResolve() 的第一个参数是包含 filter 和 namespace 的对象。filter 是一个正则表达式,用于匹配导入字符串。实际上,这允许你筛选出自定义解析逻辑适用的模块。
onResolve() 的第二个参数是一个回调,在每个匹配 filter 和 namespace 的模块导入时执行。
回调接收匹配模块的 路径 作为输入,可以返回模块的新路径。Bun 会读取此新路径的内容并解析为模块。
例如,把所有以 images/ 开头的导入重定向到 ./public/images/:
onLoad
onLoad() 插件生命周期回调允许你在 Bun 读取和解析模块之前修改模块的 内容。
与 onResolve() 类似,onLoad() 的第一个参数用于过滤哪些模块将触发此回调。
onLoad() 的第二个参数是每个匹配模块加载前调用的回调。
该回调接收匹配模块的 路径、导入该模块的 importer、模块的 namespace 以及模块的 kind。
回调可以返回模块的新 contents 字符串和新的 loader。
例如:
import env from "env" 类型的导入转成导出当前环境变量的 JavaScript 模块。
.defer()
传给 onLoad 回调的参数之一是 defer 函数。该函数返回一个 Promise,当所有其他模块加载完成后会被 resolve。
这使得你可以延迟 onLoad 回调的执行,直到加载完成其他所有模块。
这对于返回依赖其他模块的模块内容非常有用。
示例:跟踪并报告未使用的导出
.defer() 函数当前限制是每个 onLoad 回调中只能调用一次。
原生插件
Bun 打包器速度快的原因之一是它使用原生代码实现,并利用多线程并行加载和解析模块。 但是,用 JavaScript 编写的插件有个限制:JavaScript 本身是单线程的。 原生插件是以 NAPI 模块的形式编写,可以在多个线程上运行。这使得原生插件运行速度远快于 JavaScript 插件。 此外,原生插件可以跳过将字符串传递给 JavaScript 时必须进行的 UTF-8 -> UTF-16 转换等不必要的工作。 原生插件可用的生命周期钩子包括:onBeforeParse():在 Bun 的打包器解析文件前于任何线程调用。
用 Rust 创建原生插件
原生插件是 NAPI 模块,暴露生命周期钩子为 C ABI 函数。 创建原生插件时,必须导出匹配所实现原生生命周期钩子签名的 C ABI 函数。terminal
terminal
lib.rs 文件中,我们将使用 bun_native_plugin::bun 过程宏定义一个函数来实现原生插件。
下面是实现 onBeforeParse 钩子的示例:
Bun.build() 中: