Skip to content

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

已知限制

不完全支持的功能

  1. cluster 模块:有限支持
  2. vm 模块:部分功能
  3. 某些 Node.js 内部 API
  4. 特定的原生模块

解决方案

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 替代方案
  • ✅ 渐进式迁移策略

下一步

继续阅读 学习资源 获取更多学习资料。

本站内容仅供学习和研究使用。