一步步:从 Node.js 21 迁移到 Bun 1.2 以用于您的后端 API
Source: Dev.to
为什么迁移到 Bun 1.2?
Bun 1.2 是一个为速度而生的现代 JavaScript 运行时,提供原生 TypeScript 支持、内置打包器、测试运行器和包管理器。与 Node.js 21 相比,Bun 可实现高达 3 倍更快的启动时间、更低的内存使用,并与大多数 Node.js API 无缝兼容。对于后端 API,这意味着基础设施成本降低、响应时间更快以及工具链更简化。
迁移前检查清单
- 审计所有依赖 – 使用
bun audit或参考 Bun Node.js Compatibility page 以确认关键包的支持情况。 - 备份你的项目 – 创建一个单独的 Git 分支或快照,以便在需要时回滚。
- 识别 Node 特定实现 – 查找
__dirname、__filename的使用,或可能需要调整的自定义核心模块 polyfills。
安装 Bun
curl -fsSL https://bun.sh/install | bash
验证安装:
bun --version
# Should output 1.2.x
配置项目
导航到您现有的 Node.js 21 项目目录。如果没有 bunfig.toml 文件,创建一个来自定义 Bun 的行为:
# bunfig.toml
[install]
registry = "https://registry.npmjs.org"
[test]
preload = ["./test/setup.ts"]
更新 package.json 以将项目类型设置为 ESM(Bun 支持 CommonJS,但出于更好的兼容性,推荐使用 ESM):
{
"type": "module",
"scripts": {
"start": "bun run src/index.ts",
"test": "bun test"
}
}
将 npm install 替换为 Bun 的内置包管理器:
bun install
Bun 将读取您现有的 package.json 和锁文件(package-lock.json / yarn.lock),并生成二进制的 bun.lockb。如果任何依赖抛出错误,请寻找兼容 Bun 的替代方案或更新到最新版本。
代码调整
从 CommonJS 切换到 ESM
// Before (CommonJS)
const express = require("express");
const { PORT } = require("./config");
// After (ESM)
import express from "express";
import { PORT } from "./config.js"; // note the .js extension
替换 __dirname / __filename
// Before (Node.js CJS)
console.log(__dirname);
// After (Bun ESM)
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
环境变量
// Bun 的别名(稍快一点)
const port = Bun.env.PORT || 3000;
可选:使用 Bun 优化的框架
如果你使用 Express,它仍然可以正常工作,但你可以切换到像 Elysia 这样的 Bun 原生框架,以获得额外的性能提升:
import { Elysia } from "elysia";
const app = new Elysia()
.get("/", () => "Hello from Bun 1.2!")
.listen(3000, () => {
console.log("Server running on port 3000");
});
ORM
对于 Prisma、Drizzle 或其他 ORM,请将数据库连接更新为使用兼容 Bun 的驱动(例如 SQLite 使用 bun:sqlite,或使用在 Bun 上可运行的标准 PostgreSQL/MySQL 驱动)。
使用 Bun 进行测试
Bun 包含一个内置的测试运行器,兼容 Jest 语法。
# Run all tests
bun test
# Run a specific test file
bun test src/__tests__/api.test.ts
手动验证 API 端点:
curl http://localhost:3000/api/users
运行完整的集成测试套件,以确认没有回归。
替换 Node‑specific API(可选但推荐)
- 当不使用框架时,使用
Bun.serve()来创建 HTTP 服务器,而不是http.createServer()。 - 使用
Bun.file()和Bun.write()进行文件操作,而不是fs模块的 polyfill。 - 移除不必要的 Node shim(例如,
node-fetch是多余的,因为 Bun 已内置fetchAPI)。
使用 Bun 1.2 部署
Docker
FROM oven/bun:1.2
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install
COPY . .
EXPOSE 3000
CMD ["bun", "run", "src/index.ts"]
云平台提供商
Bun 在 Fly.io、Railway 和 Render 等平台上受支持。请参阅各平台的文档以启用 Bun 运行时。
CI/CD
在运行构建和测试步骤之前,将您的 CI 流水线(GitHub Actions、GitLab CI 等)更新为安装 Bun 而非 Node.js 21。
常见需要避免的陷阱
- 在迁移到 ESM 时忘记在
package.json中设置"type": "module"。 - 使用 Bun 尚未支持的 Node 核心模块(请先查看兼容性文档)。
- 跳过全面测试——在投入生产之前,请务必在预发布环境中进行验证。
从 Node.js 21 迁移到 Bun 1.2 对大多数后端 API 来说相对直接,只需进行极少的代码更改。您将获得更快的性能、更简化的工具链,以及对 Bun 日益壮大的原生工具生态系统的访问。先从一个小型、非关键的 API 开始测试迁移过程,等对工作流熟悉后再推广到更大的服务。