.scss 或 .yaml。在 Bun 的打包器中,插件可以实现框架级功能,例如 CSS 提取、宏,以及客户端与服务器代码共置。
生命周期钩子
插件会注册在 bundle 生命周期各个阶段运行的回调:onStart():在打包器开始构建 bundle 后运行一次onResolve():在解析模块之前运行onLoad():在加载模块之前运行onBeforeParse():在解析文件之前,于解析器线程中运行零拷贝原生插件
参考
类型概览(完整的类型定义请参阅 Bun 的bun.d.ts):
Plugin Types
使用方法
一个插件被定义为一个包含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 匹配的每个模块导入,该回调都会运行。
回调会接收匹配模块的 path,并可以为其返回一个 新路径。Bun 会读取 新路径 的内容,并将其解析为模块。
例如,把所有以 images/ 开头的导入重定向到 ./public/images/:
index.ts
onLoad
onLoad() 生命周期回调,可以在 Bun 读取并解析模块的 contents 之前修改它。
与 onResolve() 一样,onLoad() 的第一个参数用于筛选此次 onLoad() 调用适用的模块。
onLoad() 的第二个参数是一个回调函数,对于每个匹配的模块,该回调都会在 Bun 将其内容加载到内存 之前 运行。
回调会接收匹配模块的 path、其 namespace、该文件的默认 loader 以及一个 defer 函数。
回调可以返回模块的新 contents 字符串和新的 loader。
例如:
index.ts
import env from "env" 的导入转换为一个导出当前环境变量的 JavaScript 模块。
.defer()
onLoad 回调会接收一个 defer 函数,该函数返回一个 Promise,当所有 其他 模块都加载完成后,该 Promise 才会解析。当模块的内容依赖其他模块时,请等待该 Promise。
示例:跟踪并报告未使用的导出
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() 中使用: