Bun 运行时¶
为什么要学¶
Bun 是用 Zig 编写的全新 JavaScript/TypeScript 运行时,目标是替代 Node.js + npm + webpack 的整个工具链:
- 极快的速度:启动速度比 Node.js 快 4 倍,包安装比 npm 快 25 倍
- All-in-One:运行时 + 包管理器 + 打包器 + 测试运行器
- 原生 TypeScript:无需 tsc 或 ts-node,直接运行 .ts 文件
- Node.js 兼容:大部分 npm 包和 Node.js API 直接可用
- 内置 Web API:fetch、WebSocket、FormData 等开箱即用
- SQLite 内置:bun:sqlite 原生模块
如果你想要更快的 JS/TS 开发体验并减少工具链复杂度,Bun 值得尝试。
核心概念¶
白话解释¶
Bun 就像一个"瑞士军刀"——把你需要的 JavaScript 工具全集成在一个程序里: - 以前:Node.js(运行) + npm(安装包) + webpack(打包) + jest(测试) + tsc(TypeScript) - 现在:bun(全搞定)
核心概念对照表¶
| Bun 功能 | 替代工具 | 提升 |
|---|---|---|
| bun run | node / ts-node | 直接运行TS, 更快启动 |
| bun install | npm / yarn / pnpm | 安装速度25x+ |
| bun build | webpack / esbuild | 内置打包 |
| bun test | jest / vitest | Jest兼容, 更快 |
| Bun.serve() | express / fastify | 内置HTTP服务器 |
| bun:sqlite | better-sqlite3 | 原生SQLite |
| bunx | npx | 更快执行 |
安装配置¶
安装¶
# macOS/Linux
curl -fsSL https://bun.sh/install | bash
# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"
# Homebrew
brew install oven-sh/bun/bun
# 验证
bun --version
项目初始化¶
# 创建新项目
bun init
# 目录结构:
# ├── index.ts
# ├── package.json
# ├── tsconfig.json
# └── bun.lockb (二进制lockfile)
包管理¶
# 安装依赖(极快)
bun install
# 添加包
bun add express
bun add -d @types/express # 开发依赖
bun add -g typescript # 全局安装
# 移除包
bun remove express
快速上手¶
运行 TypeScript¶
// index.ts - 无需任何配置直接运行
const greeting: string = "Hello from Bun!";
console.log(greeting);
interface User {
name: string;
age: number;
}
const user: User = { name: "张三", age: 25 };
console.log(user);
HTTP 服务器¶
// server.ts
const server = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/") {
return new Response("Hello Bun!");
}
if (url.pathname === "/json") {
return Response.json({ message: "Hello", timestamp: Date.now() });
}
if (url.pathname === "/api/users" && req.method === "POST") {
return handleCreateUser(req);
}
return new Response("Not Found", { status: 404 });
},
});
async function handleCreateUser(req: Request): Promise<Response> {
const body = await req.json();
return Response.json({ id: 1, ...body }, { status: 201 });
}
console.log(`Server running at http://localhost:${server.port}`);
文件操作¶
// Bun内置快速文件API
const file = Bun.file("./data.json");
// 读取
const content = await file.text();
const json = await file.json();
// 写入
await Bun.write("./output.txt", "Hello World");
await Bun.write("./data.json", JSON.stringify({ key: "value" }));
// 文件信息
console.log(file.size); // 字节数
console.log(file.type); // MIME类型
进阶用法¶
1. 内置测试¶
// math.test.ts
import { expect, test, describe, beforeAll } from "bun:test";
describe("数学函数", () => {
test("加法", () => {
expect(1 + 1).toBe(2);
});
test("异步操作", async () => {
const result = await fetchData();
expect(result).toBeDefined();
});
test("快照测试", () => {
const obj = { name: "test", values: [1, 2, 3] };
expect(obj).toMatchSnapshot();
});
});
2. 打包构建¶
// build.ts
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser", // browser | bun | node
format: "esm",
minify: true,
sourcemap: "external",
splitting: true, // 代码分割
external: ["react", "react-dom"], // 外部依赖
});
3. SQLite (内置)¶
import { Database } from "bun:sqlite";
const db = new Database("app.db");
// 创建表
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE
)`);
// 插入
const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
insert.run("张三", "zhangsan@example.com");
// 查询
const users = db.query("SELECT * FROM users WHERE name LIKE ?").all("%张%");
console.log(users);
// 事务
const insertMany = db.transaction((users) => {
for (const user of users) {
insert.run(user.name, user.email);
}
});
insertMany([
{ name: "李四", email: "lisi@example.com" },
{ name: "王五", email: "wangwu@example.com" },
]);
4. WebSocket 服务器¶
const server = Bun.serve({
port: 3000,
fetch(req, server) {
// 升级到WebSocket
if (server.upgrade(req)) return;
return new Response("HTTP fallback");
},
websocket: {
open(ws) {
console.log("连接已建立");
ws.subscribe("chat");
},
message(ws, message) {
// 广播给所有订阅者
ws.publish("chat", `用户说: ${message}`);
},
close(ws) {
console.log("连接已关闭");
},
},
});
console.log(`WebSocket server on ws://localhost:${server.port}`);
5. 环境变量与配置¶
// .env文件自动加载(无需dotenv)
// .env
// DATABASE_URL=postgresql://localhost/mydb
// API_KEY=secret123
console.log(Bun.env.DATABASE_URL);
console.log(Bun.env.API_KEY);
// bunfig.toml - Bun配置文件
# bunfig.toml
[install]
registry = "https://registry.npmmirror.com"
[test]
coverage = true
coverageThreshold = { line = 0.8 }
6. Worker 线程¶
// worker.ts
self.onmessage = (event: MessageEvent) => {
const result = heavyComputation(event.data);
postMessage(result);
};
function heavyComputation(n: number): number {
// CPU密集型任务
let sum = 0;
for (let i = 0; i < n; i++) sum += i;
return sum;
}
// main.ts
const worker = new Worker(new URL("./worker.ts", import.meta.url));
worker.postMessage(100000000);
worker.onmessage = (event) => {
console.log("结果:", event.data);
};
7. Shell 脚本¶
import { $ } from "bun";
// 像shell脚本一样执行命令
const result = await $`ls -la`.text();
console.log(result);
// 管道
const count = await $`cat data.txt | wc -l`.text();
// 变量插值
const dir = "./src";
await $`find ${dir} -name "*.ts" | head -5`;
// 错误处理
try {
await $`exit 1`.throws(true);
} catch (e) {
console.error("命令失败");
}
常见问题¶
Q1: Node.js 兼容性如何?¶
大部分 npm 包和 Node.js API 可以直接使用,但少数情况不兼容: - 原生 C++ 插件可能需要重新编译 - 某些 Node.js 特有 API 尚未完全实现 - 建议查看 Bun 兼容性页面
Q2: 和 Node.js 性能对比?¶
| 场景 | Bun | Node.js |
|---|---|---|
| 启动速度 | ~4x 快 | 基线 |
| HTTP 吞吐 | ~2.5x 快 | 基线 |
| 包安装 | ~25x 快 | 基线 |
| 文件I/O | ~10x 快 | 基线 |
Q3: 生产环境可以用吗?¶
Bun 1.0+ 已声明生产就绪,但建议: - 先在非关键服务尝试 - 充分测试你的依赖兼容性 - 关注 Bun 的更新日志
Q4: 如何从 Node.js 迁移?¶
# 1. 安装Bun
# 2. 删除node_modules和package-lock.json
rm -rf node_modules package-lock.json
# 3. 用Bun安装依赖
bun install
# 4. 运行测试
bun test
# 5. 逐步替换启动命令
# "start": "node dist/index.js" → "start": "bun src/index.ts"
参考资源¶
- Bun 官网 - 官方文档
- Bun GitHub - 源代码
- Bun API 文档 - 完整API
- Bun Discord - 社区
- 兼容性表 - Node.js API 支持状态