从 Node.js 迁移
以可回滚、可验证的阶段把现有 Node.js 项目迁到 Bun
最后更新于
推荐策略:并行采用
不要在一个提交里同时替换运行时、包管理器、测试和打包器。每多替换一个边界,定位问题的成本都会上升。
| 阶段 | 改动 | 通过条件 | 回滚 |
|---|---|---|---|
| 1. 本地脚本 | 用 Bun 跑独立工具脚本 | 输出与 Node 一致 | 保留 node script.js |
| 2. 包管理 | 生成 bun.lock | 冻结安装、测试、构建通过 | 保留旧锁文件到评审完成 |
| 3. 测试 | 迁移一组单测 | 结果和覆盖率可接受 | 原 runner 仍可运行 |
| 4. 开发运行时 | 本地服务用 Bun | 集成测试通过 | 旧 dev 脚本可用 |
| 5. 生产运行时 | 改容器 / 入口 | 预发布压测和回滚演练通过 | 可切回旧镜像 |
迁移进度清单
已完成 0 / 5
进度只保存在当前浏览器,不会上传。
迁移前盘点
rg "node:|process\.|__dirname|require\(|worker_threads|child_process" src
bun pm ls重点检查:
.node原生扩展;- 自定义 ESM loader、require hook 或 Babel transformer;
- 依赖 Node/V8 特定诊断行为的工具;
- Jest 专属环境、插件和 fake timers;
- 框架官方支持矩阵与部署平台运行时。
包管理迁移
bun install
bun install --frozen-lockfileBun 在没有 bun.lock 时可迁移现有锁文件。先审查生成结果并跑全套验证,不要立即删除原锁文件。切换获批后,只保留一个权威锁文件。
Docker 基线
FROM oven/bun:1 AS install
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
FROM oven/bun:1 AS release
WORKDIR /app
COPY --from=install /app/node_modules ./node_modules
COPY . .
ENV NODE_ENV=production
USER bun
CMD ["bun", "run", "start"]真实项目应使用 .dockerignore、按框架复制构建产物,并固定经组织验证的镜像版本或 digest。
验收矩阵
- 类型检查、单元、集成、端到端测试;
- 冷启动、吞吐、内存和长时间稳定性;
- SIGTERM 优雅退出;
- 时区、Unicode、文件路径和大小写;
- TLS、代理、数据库连接池与 DNS;
- 容器平台的 CPU 架构和 libc 差异;
- 可观测性 Agent 和 sourcemap。
建立双运行时兼容 CI
迁移期间对同一组纯业务和集成测试分别运行 Node 与 Bun,把差异变成可观察证据:
strategy:
matrix:
runtime: [node, bun]真实工作流应让 Node Job 使用组织支持的 Node 版本和原包管理流程,让 Bun Job 固定验证过的 Bun 版本。比较退出码、HTTP 契约、数据库行为和构建产物,不要求两个运行时的内部日志或性能数字完全相同。只有 Bun 路径通过全部发布门禁后才移除 Node 回滚路径。
兼容性必须实测
“Node.js-compatible” 是迁移起点,不是项目验收结果。依赖树、框架版本和生产平台共同决定是否可切换。