先建立心智模型

用 Node.js 开发经验理解 Bun 的四个角色和边界

最后更新于

一句话理解

Bun 不是“更快的 npm”。它把过去常由 Node.js、npm/pnpm、Jest/Vitest 和 esbuild 等工具承担的职责,集中进一个 bun 可执行文件。

你熟悉的角色Bun 中的入口是否必须全量替换
Node.js 运行时bun run app.ts否,可以先只替换脚本或开发环境
npm / pnpm / Yarnbun install否,可分阶段验证锁文件和生命周期脚本
Jest / Vitestbun test否,先迁移独立单测最稳妥
esbuild / Rollupbun build否,框架项目可继续用原构建链

bun run 的两种含义

bun run server.ts   # 运行文件
bun run dev         # 运行 package.json 中的 dev 脚本

如果文件名和脚本名可能冲突,运行源码时写清相对路径与扩展名,例如 bun run ./dev.ts;运行 package.json 脚本时显式写 bun run dev--bun 不是消除歧义的开关,它用于强制本地 CLI 以 Bun 而不是 Node.js 运行。

运行参数也要放对位置:

bun --watch run dev   # --watch 交给 Bun
bun run dev -- --port 4000   # --port 交给 dev 脚本

Bun 能直接处理 TypeScript,但不是类型检查器

Bun 会去掉 TypeScript 类型并执行代码,但运行前不会替你完成完整静态类型检查。需要把 tsc --noEmit 或框架自带的类型检查留在 CI:

{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "test": "bun test"
  }
}

Web API 与 Node.js API

Bun 优先提供标准 Web API(fetchRequestResponseWebSocket),同时实现大量 Node.js 兼容 API。迁移时应逐项验证原生扩展、边缘行为和框架支持,不能把“兼容”理解为每个包都无需测试。

一个安全的学习顺序

  1. bun run 执行独立 TypeScript 脚本。
  2. bun install 复现依赖安装,并审查 bun.lock
  3. bun test 迁移没有复杂模拟的单元测试。
  4. 最后再评估生产运行时或整套构建链。

新手判断法

不知道该用哪个子命令时,先说出目标:执行源码、管理依赖、跑测试或生成产物。目标分别对应 runinstalltestbuild