package.json,并在自己的输出里打印 Bun 命令。
Extension.js CLI 本身跑在 Node 上。这个分工就是下面那个问题的全部答案。
我可以用 Bun 代替 Node 吗?
对你的项目来说,可以。对 CLI 进程来说,不行。
Bun 仍然是你的操作界面,Node 仍然是执行 CLI 的运行时。两者都要装。
用 Bun 创建项目
package.json 会固定住你用的那个管理器:
package.json
安装与构建
bun.lock 文件。之后每次运行,Extension.js 都会读取这个锁文件,以便继续选择 Bun。
extension 这个可执行文件,所以 bun run dev、bun run build 和 bun run preview 都能用。
CLI 为什么需要 Node
发布出去的包声明了"engines": {"node": ">=22.12"}。CLI 在启动时检查 process.versions.node,版本太低就停下来。
Bun 报告的 Node 兼容版本低于这个下限。因此强行使用 Bun 运行时会触发这道守卫:
--bun,同一条命令就能用。普通的 bunx 会尊重 CLI 可执行文件上的 #!/usr/bin/env node shebang,所以进程跑在 Node 上,而解析和缓存交给 Bun。
Extension.js 如何检测 Bun
检测读的是项目,而不是你敲下的那条命令。有三个信号喂给它:- 项目根目录下的
bun.lock或bun.lockb锁文件。 package.json里点名bun的packageManager字段。- Bun 运行脚本时设置的
npm_config_user_agent环境变量。
npm、pnpm、yarn、bun 和 deno。当一个信号都没有时,它会按 pnpm、yarn、bun 的顺序去探测你的 PATH。
自动安装依赖
extension dev 和 extension build 会在编译之前先装上缺失的依赖。这次安装走的是被检测到的那个管理器,并且会传入 --ignore-scripts。因此依赖里的 postinstall 脚本不会在这一步运行。
注意事项
Bun.file这类 Bun 专有的运行时 API 不属于扩展代码。那些代码是跑在浏览器里的。- Extension.js 不会写任何 Bun 专有的脚本。
dev、build和preview脚本对每个管理器都一样。 - 你通过
extension create引入的模板不带锁文件。Extension.js 会从中剥掉bun.lock和bun.lockb。之后由你自己那次安装来决定依赖树。

