Bun Node.js 兼容性
Bun 设计目标之一是与 Node.js 生态系统兼容。本章介绍 Bun 对 Node.js 的兼容性以及迁移指南。
兼容性概述
支持的 Node.js API
Bun 支持大部分 Node.js 核心模块:
| 模块 | 兼容性 | 说明 |
|---|---|---|
fs | ✅ 完整 | 文件系统 |
path | ✅ 完整 | 路径操作 |
http | ✅ 大部分 | HTTP 服务器和客户端 |
https | ✅ 大部分 | HTTPS 支持 |
crypto | ✅ 大部分 | 加密功能 |
buffer | ✅ 完整 | Buffer 操作 |
stream | ✅ 大部分 | 流处理 |
events | ✅ 完整 | 事件发射器 |
util | ✅ 大部分 | 工具函数 |
os | ✅ 完整 | 操作系统信息 |
child_process | ✅ 大部分 | 子进程 |
worker_threads | ✅ 大部分 | 工作线程 |
net | ✅ 大部分 | 网络套接字 |
dns | ✅ 大部分 | DNS 解析 |
url | ✅ 完整 | URL 处理 |
querystring | ✅ 完整 | 查询字符串 |
zlib | ✅ 大部分 | 压缩 |
assert | ✅ 完整 | 断言 |
部分支持的 API
| 模块 | 状态 | 说明 |
|---|---|---|
cluster | ⚠️ 部分 | 集群模式有限支持 |
vm | ⚠️ 部分 | 虚拟机模块有限支持 |
inspector | ⚠️ 部分 | 调试器支持 |
trace_events | ❌ 不支持 | 追踪事件 |
v8 | ❌ 不支持 | V8 特定 API |
使用 Node.js API
导入方式
typescript
// 推荐:使用 node: 前缀
import fs from "node:fs";
import path from "node:path";
import { EventEmitter } from "node:events";
// 也支持:不带前缀
import crypto from "crypto";
import http from "http";文件系统
typescript
import fs from "node:fs";
import { readFile, writeFile } from "node:fs/promises";
// 同步读取
const content = fs.readFileSync("./file.txt", "utf-8");
// 异步读取
const asyncContent = await readFile("./file.txt", "utf-8");
// 写入文件
await writeFile("./output.txt", "Hello, Bun!");
// 流式读取
const stream = fs.createReadStream("./large-file.txt");
for await (const chunk of stream) {
console.log(chunk);
}HTTP 服务器
typescript
import http from "node:http";
// Node.js 风格的 HTTP 服务器
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello from Node.js API!");
});
server.listen(3000, () => {
console.log("服务器运行在 http://localhost:3000");
});子进程
typescript
import { spawn, exec } from "node:child_process";
// 使用 spawn
const child = spawn("ls", ["-la"]);
child.stdout.on("data", (data) => {
console.log(`stdout: ${data}`);
});
// 使用 exec
exec("echo 'Hello'", (error, stdout, stderr) => {
if (error) {
console.error(`错误: ${error}`);
return;
}
console.log(`输出: ${stdout}`);
});
// 使用 Promise(推荐)
import { execSync } from "node:child_process";
const result = execSync("echo 'Hello'").toString();加密
typescript
import crypto from "node:crypto";
// 哈希
const hash = crypto.createHash("sha256")
.update("Hello, World!")
.digest("hex");
console.log("SHA256:", hash);
// HMAC
const hmac = crypto.createHmac("sha256", "secret")
.update("message")
.digest("hex");
// 随机字节
const randomBytes = crypto.randomBytes(16);
console.log("随机字节:", randomBytes.toString("hex"));
// UUID
const uuid = crypto.randomUUID();
console.log("UUID:", uuid);从 Node.js 迁移
第一步:安装 Bun
bash
# 安装 Bun
curl -fsSL https://bun.sh/install | bash
# 验证安装
bun --version第二步:切换包管理器
bash
# 删除旧的依赖
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml
# 使用 Bun 安装
bun install第三步:更新 package.json
json
{
"scripts": {
"start": "bun src/index.ts",
"dev": "bun --watch src/index.ts",
"build": "bun build src/index.ts --outdir dist",
"test": "bun test"
}
}第四步:检查兼容性
bash
# 尝试运行
bun src/index.ts
# 检查是否有错误常见迁移问题
问题 1:找不到模块
typescript
// ❌ 可能报错
import { something } from "obscure-package";
// ✅ 检查包是否兼容
bun pm ls obscure-package问题 2:原生模块
typescript
// 某些原生 Node.js 模块可能不兼容
// 需要找替代方案或等待 Bun 支持
// 例如:sharp 图片处理
// 检查 Bun 是否支持: https://bun.sh/docs/ecosystem问题 3:Node.js 特定 API
typescript
// ❌ 某些 Node.js 特定 API 可能不存在
process.binding("buffer");
// ✅ 使用标准 API 替代
import { Buffer } from "node:buffer";问题 4:__dirname 和 __filename
typescript
// 在 ESM 中 __dirname 和 __filename 不可用
// ✅ Bun 支持这些
console.log(__dirname); // 可用
console.log(__filename); // 可用
// 或使用 import.meta
console.log(import.meta.dir); // 目录
console.log(import.meta.path); // 文件路径Bun vs Node.js API 对照
文件操作
typescript
// Node.js
import { readFile } from "fs/promises";
const content = await readFile("./file.txt", "utf-8");
// Bun(更简洁)
const content = await Bun.file("./file.txt").text();HTTP 服务器
typescript
// Node.js
import http from "http";
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end("Hello");
});
server.listen(3000);
// Bun(更简洁)
Bun.serve({
port: 3000,
fetch: () => new Response("Hello"),
});环境变量
typescript
// Node.js
require("dotenv").config();
const value = process.env.MY_VAR;
// Bun(自动加载 .env)
const value = Bun.env.MY_VAR;
// 或
const value = process.env.MY_VAR;运行 TypeScript
bash
# Node.js
npx ts-node app.ts
# 或
npx tsx app.ts
# Bun(直接运行)
bun app.ts使用 Bun 替代品
替代 Express
typescript
// 使用 Elysia(Bun 专用框架)
import { Elysia } from "elysia";
const app = new Elysia()
.get("/", () => "Hello Elysia")
.get("/user/:id", ({ params: { id } }) => `User ${id}`)
.post("/user", ({ body }) => body)
.listen(3000);
console.log(`运行在 http://localhost:${app.server?.port}`);替代 Jest
typescript
// Bun 内置测试
import { test, expect } from "bun:test";
test("addition", () => {
expect(1 + 1).toBe(2);
});替代 webpack/esbuild
typescript
// Bun 内置打包
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
minify: true,
});渐进式迁移
策略 1:部分使用 Bun
json
{
"scripts": {
"start": "node dist/index.js",
"dev": "bun --watch src/index.ts",
"test": "bun test",
"build": "bun build src/index.ts --outdir dist"
}
}策略 2:条件使用
typescript
// 检测运行时
const isBun = typeof Bun !== "undefined";
if (isBun) {
// 使用 Bun API
const content = await Bun.file("./data.txt").text();
} else {
// 使用 Node.js API
const { readFile } = await import("fs/promises");
const content = await readFile("./data.txt", "utf-8");
}策略 3:抽象层
typescript
// file-utils.ts
export async function readTextFile(path: string): Promise<string> {
if (typeof Bun !== "undefined") {
return Bun.file(path).text();
}
const { readFile } = await import("fs/promises");
return readFile(path, "utf-8");
}兼容性检查工具
检查包兼容性
bash
# 查看包的兼容性状态
# 访问 https://bun.sh/ecosystem测试运行
bash
# 运行项目并观察错误
bun run start 2>&1 | head -50
# 运行测试
bun test已知限制
不完全支持的功能
- cluster 模块:有限支持
- vm 模块:部分功能
- 某些 Node.js 内部 API
- 特定的原生模块
解决方案
typescript
// 如果遇到不支持的功能
// 1. 检查 Bun 文档是否有替代方案
// 2. 使用 polyfill
// 3. 条件加载
// 4. 等待 Bun 更新
// 示例:条件使用 cluster
if (typeof Bun !== "undefined") {
// 使用 Bun 的多进程方案
} else {
// 使用 Node.js cluster
const cluster = require("cluster");
// ...
}小结
本章介绍了:
- ✅ Bun 对 Node.js API 的兼容性
- ✅ 如何使用 Node.js 模块
- ✅ 从 Node.js 迁移的步骤
- ✅ 常见迁移问题和解决方案
- ✅ Bun 替代方案
- ✅ 渐进式迁移策略
下一步
继续阅读 学习资源 获取更多学习资料。