.scss 或 .yaml。在 Bun 的打包器中,插件可以实现框架级功能,如 CSS 提取、宏和客户端-服务器代码共存。
生命周期钩子
插件注册在打包生命周期的各个点运行的回调:onStart():打包器开始打包后运行一次onResolve():在模块被解析之前运行onLoad():在模块被加载之前运行onBeforeParse():在文件被解析之前,在解析器线程中运行零拷贝原生插件
参考
类型的大致概览(完整类型定义见 Bun 的bun.d.ts):
插件类型
使用
插件的定义是一个包含name 属性和 setup 函数的 JavaScript 对象。
myPlugin.ts
Bun.build 时,将插件传入 plugins 数组。
index.ts
插件生命周期
命名空间
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
index.ts
Promise。在打包过程初始化后,打包器会等待所有 onStart() 回调完成,然后再继续。
例如:
index.ts
onStart() 回调完成:第一个睡眠 10 秒,第二个将打包时间写入文件。
onStart() 回调(与每个其他生命周期回调一样)不能修改 build.config 对象。要修改 build.config,请在 setup() 函数中直接进行。
onResolve
onResolve() 生命周期回调自定义模块的解析方式。
onResolve() 的第一个参数是一个包含 filter 和 namespace 属性的对象。filter 是一个对导入字符串运行的正则表达式。它们共同决定了你的自定义解析逻辑适用于哪些模块。
onResolve() 的第二个参数是一个回调,为 Bun 找到的每个匹配第一个参数中 filter 和 namespace 的模块导入运行。
回调接收匹配模块的 路径,并可以返回一个 新路径。Bun 会读取 新路径 的内容并将其解析为模块。
例如,将所有 images/ 的导入重定向到 ./public/images/:
index.ts
onLoad
onLoad() 生命周期回调在 Bun 读取和解析模块之前修改模块的_内容_。
与 onResolve() 类似,onLoad() 的第一个参数过滤此 onLoad() 调用适用的模块。
onLoad() 的第二个参数是一个回调,在 Bun 将每个匹配模块的内容加载到内存之前运行。
回调接收匹配模块的 路径、它的 命名空间、该文件的默认 加载器 以及一个 defer 函数。
回调可以为该模块返回新的 contents 字符串以及新的 loader。
例如:
index.ts
import env from "env" 形式的导入转换为导出当前环境变量的 JavaScript 模块。
.defer()
onLoad 回调接收一个 defer 函数,该函数返回一个在所有 其他 模块加载完成后解析的 Promise。当一个模块的内容依赖于其他模块时,请 await 它。
示例:跟踪和报告未使用的导出
index.ts
.defer() 函数每个 onLoad 回调只能调用一次。
原生插件
Bun 的打包器之所以快,部分原因在于它是用原生代码编写的,并且使用多个线程并行加载和解析模块。用 JavaScript 编写的插件无法利用这一点,因为 JavaScript 本身是单线程的。 原生插件被编写为 NAPI 模块,可以在多个线程上运行,因此它们比 JavaScript 插件运行得快得多。它们还可以跳过不必要的工作,例如将字符串传递给 JavaScript 所需的 UTF-8 到 UTF-16 转换。 以下生命周期钩子可用于原生插件:onBeforeParse():在任何线程上,在 Bun 的打包器解析文件之前调用。
在 Rust 中创建原生插件
terminal
terminal
lib.rs 中,使用 bun_native_plugin::bun 过程宏定义一个实现你的原生插件的函数。
这是一个实现 onBeforeParse 钩子的示例:
lib.rs
Bun.build() 中使用: