ECC bun-runtime 技能:Bun 运行时、Node 迁移与 Vercel 部署实战指南
本文围绕 ECC 仓库中的 bun-runtime 技能文档 展开,系统讲解 Bun 作为 JavaScript 一体化工具链(运行时、包管理器、打包器、测试运行器)的定位与用法:何时选 Bun 何时选 Node、如何从 Node 迁移脚本与依赖安装、如何在 Vercel 上配置 Bun 部署,并结合 ECC 仓库自身的包管理器检测源码验证这些命令与锁文件约定,读完后你可以直接在自己的 JS/TS 项目中落地 Bun 工具链。
bun-runtime 技能在 ECC 中的位置
ECC 是一个面向 Claude Code、Codex、Opencode、Cursor 等 Agent 环境的"技能(Skill)"集合仓库,每个技能是一份供 AI 编码助手加载的 Markdown 指南。bun-runtime 是其中之一,其规范版本位于 skills/bun-runtime/SKILL.md,而本文指定的 .cursor/skills/bun-runtime/SKILL.md 是随 Cursor 配置分发的镜像副本(两者正文完全一致,仅 frontmatter 写法略有差异:镜像版用顶层 origin: ECC,规范版用 metadata.origin)。从源码结构看,scripts/install-apply.js 中 cursor 安装目标负责"将规则、hooks 和捆绑的 Cursor 配置安装到 ./.cursor/",这正是镜像文件的来源;同时 package.json 的 files 清单与 manifests/install-modules.json 均登记了 skills/bun-runtime 目录,说明该技能是安装清单中的一等模块。
何时选用 Bun,何时留在 Node
技能文档给出的决策边界非常明确,完整继承如下:
优先选择 Bun 的场景:
- 新建的 JS/TS 项目;
- 安装与运行速度敏感的脚本场景;
- 使用 Bun 运行时的 Vercel 部署;
- 希望"一条工具链"同时覆盖
run + install + test + build的项目。
优先选择 Node 的场景:
- 需要最大化的生态兼容性;
- 遗留工具链默认假设 Node 环境;
- 某个依赖已知的 Bun 兼容性问题。
适用时机(Use when):引入 Bun、从 Node 迁移、编写或调试 Bun 脚本与测试、在 Vercel 或其他平台上配置 Bun。这条边界本质是"新项目/新脚本激进采用、存量项目按依赖兼容性谨慎推进",后文所有迁移操作都应在此前提下执行。
四大组件工作原理
技能文档将 Bun 拆解为四个组件,每个都值得展开:
- 运行时(Runtime):Node 兼容的"即插即用"运行时,底层基于 JavaScriptCore 引擎、用 Zig 实现。这意味着绝大多数 Node 代码无需改动即可运行,而 JSC 引擎与 Zig 实现是其启动/IO 性能的来源。
- 包管理器(Package Manager):
bun install速度显著快于 npm/yarn。锁文件默认是文本格式的bun.lock(当前 Bun 版本),旧版本使用二进制的bun.lockb——这一"锁文件演进史"在 ECC 的源码中有直接印证,见下文 package-manager.js 的实现。 - 打包器(Bundler):内置面向应用与库的 bundler 与 transpiler,
bun build即可产出产物,无需单独引入 esbuild/webpack。 - 测试运行器(Test Runner):内置
bun test,提供类似 Jest 的 API(test/expect断言)。
ECC 源码印证:Bun 的命令与锁文件约定
ECC 仓库自身需要按项目自动选择包管理器(npm/pnpm/yarn/bun),scripts/lib/package-manager.js 中为 bun 定义的字段与技能文档逐条对应:
bun: {
name: 'bun',
lockFile: 'bun.lock',
// Bun switched its default lockfile from the binary bun.lockb to the
// text-based bun.lock. Keep recognizing the legacy file too.
lockFileAliases: ['bun.lockb'],
installCmd: 'bun install',
runCmd: 'bun run',
execCmd: 'bunx',
testCmd: 'bun test',
buildCmd: 'bun run build',
devCmd: 'bun run dev'
}
这段定义证实了三件事:其一,当前 Bun 默认锁文件是文本版 bun.lock,但系统仍通过 lockFileAliases: ['bun.lockb'] 兼容旧的二进制锁文件——与技能文档中"current Bun 默认 bun.lock,older versions 用 bun.lockb"的说法完全一致;其二,脚本执行统一走 bun run,一次性命令(npx 风格)对应 bunx;其三,ECC 的自动检测优先级是 ['pnpm', 'bun', 'yarn', 'npm'](见 DETECTION_PRIORITY),即当一个项目中同时存在多种锁文件时,Bun 优先于 yarn/npm 被识别,这解释了为什么锁定项目工具链时提交锁文件如此重要。此外,scripts/setup-package-manager.js 支持 node scripts/setup-package-manager.js --project bun 将当前项目显式设为 Bun 项目,Windows 下 bunx 还有 .cmd shim 处理(见 scripts/lib/resolve-formatter.js),这些工程细节可以辅助你在跨平台 CI 中排错。
从 Node 迁移的操作清单
技能文档给出的迁移步骤可整理为如下对照:
| Node 习惯 | Bun 对应写法 |
|---|---|
node script.js |
bun run script.js 或 bun script.js |
npm install |
bun install |
npm run <script> |
bun run <script> |
npx <pkg> |
bun x <pkg> |
迁移时的两个要点:一是"大部分包直接可用",但遇到已知的 Bun 兼容性问题应回退 Node(呼应前文的决策边界);二是 Node 内置模块受支持,但当存在对应的 Bun 原生 API 时(如 Bun.file、Bun.serve),优先使用它们以获得更好性能——这不是强制要求,而是性能优化选项。
实操命令:安装、运行与环境变量
安装依赖与运行脚本
# 安装依赖(创建/更新 bun.lock 或 bun.lockb)
bun install
# 运行脚本或文件
bun run dev
bun run src/index.ts
bun src/index.ts
注意最后两种写法:bun run src/index.ts 走 npm scripts 语义,bun src/index.ts 是直接以 Bun 运行时执行文件,两者对 TypeScript 均原生生效(Bun 原生运行 .ts,无需预编译或 ts-node)。
脚本与环境变量
bun run --env-file=.env dev
FOO=bar bun run script.ts
--env-file 让 Bun 在运行 npm script 前自动加载 .env 文件;FOO=bar 前缀语法则用于单次注入环境变量。相比 Node 侧通常需要 dotenv 或 shell 包装,这是内置能力。
测试
bun test
bun test --watch
测试代码使用 bun:test 模块,API 与 Jest 风格一致,可直接替换现有 Jest 用例的断言习惯:
// test/example.test.ts
import { expect, test } from "bun:test";
test("add", () => {
expect(1 + 2).toBe(3);
});
--watch 模式用于开发时监听文件变更重跑测试。ECC 自身脚本的测试入口命令则由包管理器定义统一给出(bun test),与上面源码片段一致。
运行时 API
技能文档示例的两个 API 是最能体现"Bun 优于 Node 内置能力"的部分:
const file = Bun.file("package.json");
const json = await file.json();
Bun.serve({
port: 3000,
fetch(req) {
return new Response("Hello");
},
});
Bun.file(...).json() 是零拷贝式的文件读取 + 一步解析,替代 fs.readFile + JSON.parse 的两步组合;Bun.serve 则以内置 HTTP 服务直接暴露 fetch 处理器,返回标准 Response 对象,适合快速搭建服务端或 API 原型而不引入框架。
Vercel 上的 Bun 部署
技能文档给出的部署配置要点:
- 项目设置:在 Vercel 项目设置中将 runtime 设为 Bun;
- 构建:
bun run build或直接bun build ./src/index.ts --outdir=dist,后者体现内置打包器"入口 + 输出目录"的最小用法; - 安装:
bun install --frozen-lockfile做可复现安装,确保 CI 产物与本地一致。
--frozen-lockfile 与 lockfile 提交实践(下节)配套:CI 中锁文件与 package.json 不一致时直接失败,避免"本地能跑、云端漂移"。
最佳实践
完整继承技能文档的三条实践,并补充上文源码依据:
- 提交锁文件(
bun.lock或bun.lockb)以保证可复现安装。ECC 的 package-manager.js 同时识别两种锁文件,说明存量项目可能两种并存,迁移时按当前 Bun 版本自然转换为文本版即可; - 脚本优先用
bun run;TypeScript 文件由 Bun 原生执行,省去构建步骤; - 保持依赖更新,因为 Bun 本体与周边生态演进快,行为细节(尤其是默认锁文件格式这类)会随版本变化——本文所有结论均以当前仓库内文档与源码记录为准,采用前请核对所用 Bun 版本。
小结
bun-runtime 技能文档以极小篇幅给出了完整决策与操作闭环:选型边界(新工具链选 Bun、兼容性敏感选 Node)、四大组件原理、Node 迁移命令对照、bun:test 与 Bun.file/Bun.serve API 示例、Vercel 部署三连(设 runtime、bun build/--outdir、--frozen-lockfile)以及锁文件提交规范。结合 ECC 仓库 scripts/lib/package-manager.js 的锁文件别名与命令定义,可以确认文档中关于 bun.lock 演进与 bun run/bunx/bun test 命令族的描述与真实工程实现一致。需要延伸阅读时,可从规范版 skills/bun-runtime/SKILL.md 与安装清单 manifests/install-modules.json 继续深入。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00