为什么是 Bun
Node.js 生态经过十几年演化,形成了一条“缝合”的工具链:npm/yarn/pnpm 装包、esbuild/swc 转译、jest/vitest 测试、tsc 类型检查、nodemon 热重载、dotenv 配置。每多一层,就多一份冷启动成本和配置心智负担。
Bun 用 Zig 编写、基于 JavaScriptCore,把包管理器、运行时、转译器、测试运行器、打包器塞进了一个二进制。它的口号很直白:让 JS 项目“开箱即跑”。
安装与初始化
# macOS / Linux
curl -fsSL https://bun.sh/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1 | iex"
bun --version
bun init -ybun init 生成的 bunfig.toml 就是全部配置,没有 package-lock.json 之外的第二套锁文件烦恼。
用 Bun 写 HTTP 服务:内置 API 足够好用
// server.ts
import { sql } from "bun";
const server = Bun.serve({
port: 3000,
routes: {
"/": () => new Response("hello bun"),
"/users/:id": async (req) => {
const id = Number(req.params.id);
const [user] = await sql`select id, name from users where id = ${id}`;
if (!user) return new Response("not found", { status: 404 });
return Response.json(user);
},
"/upload": async (req) => {
const form = await req.formData();
const file = form.get("file") as File;
await Bun.write(`./uploads/${file.name}`, file);
return Response.json({ ok: true, size: file.size });
},
},
// 全局错误兜底
error(error) {
console.error(error);
return new Response("internal error", { status: 500 });
},
});
console.log(`listening on ${server.port}`);注意几个 Bun 独有能力:
Bun.serve的 routes:无需引入 Express/Hono 就能做路由与参数解析;Bun.sql:内置 PostgreSQL 客户端,带连接池与标签模板防注入;File是一等公民:Bun.write直接写磁盘,流式处理大文件不占内存。
测试:兼容 Jest 语法但快得多
// user.test.ts
import { expect, test, beforeEach, mock } from "bun:test";
import { createUser } from "./user";
beforeEach(() => {
mock.restore();
});
test("createUser 校验邮箱", () => {
expect(() => createUser({ email: "bad" })).toThrow(/email/i);
});
test("createUser 返回 id", () => {
const u = createUser({ email: "a@b.com" });
expect(u.id).toBeString();
});bun test # 跑全部
bun test --watch # 监听
bun test --coverage # 覆盖率构建与部署
# 打包成单文件可执行程序(含运行时)
bun build ./server.ts --compile --target=bun-linux-x64 --outfile app
# 或者产出静态产物
bun build ./src/index.tsx --outdir dist --target browser--compile 会生成一个几十 MB 的自包含二进制,部署到没有 Node 的机器上也能直接跑,冷启动通常在 10ms 级别。
Docker 场景可以用官方极小镜像:
FROM oven/bun:1-alpine
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile
COPY . .
EXPOSE 3000
CMD ["bun", "run", "server.ts"]bun install 的安装速度通常比 npm 快 5~20 倍,CI 上收益非常明显。
迁移注意事项
- Node API 兼容度已很高,但依赖
node:v8、部分worker_threads细节的库仍可能踩坑,先跑一遍测试。 - 不要用
bun run跑关键的类型检查,Bun 只做转译不做检查,保留tsc --noEmit或改用tsgo。 - 锁文件:Bun 2.x 默认生成文本格式的
bun.lock,可直接 diff,建议在 CI 里使用--frozen-lockfile。
小结
Bun 的价值不只是“快”,而是把工具链从十几个包压缩成一个二进制。对于新项目、CLI 工具、边缘函数这类场景,它已经完全可以作为首选运行时。
评论 0
还没有评论,来说两句吧。