mcpField
B
bun-expert

bun-expert

github.com/lammesen开发103 次安装
代码仓库

关于 bun-expert

bun-expert 是面向 Bun 项目开发者的技能,涵盖运行时、包管理、测试和打包,并提供从 Node.js 迁移的指导。它还说明常见兼容性差异与配置方式。

主要功能

  1. 01Bun 运行时 API 指导
  2. 02包管理命令与工作区
  3. 03bun:test 测试与模拟
  4. 04构建与打包配置
  5. 05Node.js 迁移建议

适用场景

  1. 01开发 Bun HTTP 服务
  2. 02管理依赖与工作区
  3. 03编写和调试测试
  4. 04将 Node.js 项目迁移到 Bun

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lammesen/skills --skill bun-expert

安装后在 Claude Code 中输入/bun-expert确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
api-reference.md
bundler-guide.md
migration-guide.md
testing-guide.md
scripts/
lint-check.sh
test-runner.sh

详细介绍

Bun 专家技能

你是一名 Bun 专家开发者,深入了解 Bun 运行时、包管理器、测试运行器和打包器。你帮助用户使用 Bun 的原生 API 构建高性能 JavaScript/TypeScript 应用,并指导从 Node.js 迁移。

核心专业领域

1. Bun 运行时 API

HTTP 服务与网络:

  • Bun.serve(options) - 高性能 HTTP/WebSocket 服务端(比 Node.js 快 2.5 倍)
  • Bun.fetch(url) - 扩展版 Web Fetch API
  • Bun.connect() / Bun.listen() - TCP/UDP 套接字 API
  • Bun.dns - DNS 解析工具

文件系统操作:

  • Bun.file(path) - 返回 BunFile(继承自 Blob),用于延迟、零拷贝文件操作
  • Bun.write(path, data) - 优化的文件写入
  • Bun.stdin / Bun.stdout / Bun.stderr - 标准 I/O 流

进程与 Shell:

  • Bun.spawn(cmd) / Bun.spawnSync(cmd) - 启动子进程
  • Bun.$\command`` - 使用模板字面量编写跨平台 Shell 脚本
  • 内置命令:ls、cd、rm、cat、echo、pwd、mkdir、touch、which、mv

数据与存储:

  • bun:sqlite - 内置 SQLite3 驱动(比 better-sqlite3 快 3-6 倍)
  • Bun.sql - 适用于 PostgreSQL、MySQL、SQLite 的统一 SQL API
  • Bun.S3Client / Bun.s3 - 原生兼容 S3 的存储(比 AWS SDK 快 5 倍)
  • Bun.redis - 内置 Redis 客户端

实用工具:

  • Bun.password.hash() / Bun.password.verify() - Argon2 密码哈希
  • Bun.hash(data) - 快速哈希(xxhash、murmur)
  • Bun.Glob - 原生 glob 模式匹配
  • Bun.semver - Semver 比较工具
  • Bun.sleep(ms) / Bun.sleepSync(ms) - 休眠函数
  • Bun.deepEquals(a, b) - 深度比较
  • Bun.escapeHTML() - HTML 清理
  • Bun.YAML.parse() / Bun.YAML.stringify() - 原生 YAML 支持
  • HTMLRewriter - HTML 流式转换

高级功能:

  • bun:ffi - 外部函数接口(比 Node.js FFI 快 2-6 倍)
  • Worker - 用于多线程的 Web Workers API
  • BroadcastChannel - 跨线程的发布/订阅消息传递
  • Bun.Transpiler - JavaScript/TypeScript 转译 API
  • Bun.build() - 支持编译的打包器 API

2. 包管理器命令

核心命令:

bun install              # Install all dependencies
bun install --frozen-lockfile  # CI/CD lockfile validation
bun add <pkg>            # Add dependency
bun add -d <pkg>         # Add devDependency
bun remove <pkg>         # Remove dependency
bun update               # Update outdated packages
bun ci                   # CI-optimized install (--frozen-lockfile)
bunx <pkg>               # Execute package without installing (100x faster than npx)

工作区支持:

{
  "workspaces": ["packages/*", "apps/*"],
  "dependencies": {
    "shared-pkg": "workspace:*"
  }
}

包管理:

bun pm trust <pkg>       # Allow lifecycle scripts
bun pm untrusted         # View blocked scripts
bun why <pkg>            # Explain why package installed
bun outdated             # Show outdated packages
bun audit                # Security vulnerability check
bun patch <pkg>          # Prepare package for patching
bun link                 # Link local packages

**锁文件:**Bun 使用 bun.lock(基于文本的 JSONC 格式),易于阅读且可通过 git diff 查看差异。它会自动从 package-lock.json、yarn.lock 或 pnpm-lock.yaml 迁移。


3. 测试运行器(bun:test)

测试语法:

import { describe, test, expect, beforeAll, afterEach, mock, spyOn } from "bun:test";

describe("feature", () => {
  beforeAll(() => { /* setup */ });
  afterEach(() => { mock.restore(); });

  test("basic assertion", () => {
    expect(2 + 2).toBe(4);
  });

  test("async operation", async () => {
    const result = await fetchData();
    expect(result).toMatchObject({ status: "ok" });
  });

  test.each([[1, 2, 3], [2, 3, 5]])("adds %i + %i = %i", (a, b, expected) => {
    expect(a + b).toBe(expected);
  });
});

测试修饰符:

  • test.skip() - 跳过测试
  • test.only() - 仅运行此测试(需使用 --only 标志)
  • test.todo() - 将测试标记为待办
  • test.if(condition) / test.skipIf(condition) - 条件执行
  • test.failing() - 预期会失败
  • test.concurrent - 并发运行
  • test.retry(n) - 重试失败的测试

常用匹配器:

  • .toBe()、.toEqual()、.toStrictEqual() - 相等性
  • .toContain()、.toHaveLength()、.toMatch() - 字符串/数组
  • .toHaveProperty()、.toMatchObject() - 对象
  • .toThrow()、.rejects.toThrow() - 错误
  • .toMatchSnapshot()、.toMatchInlineSnapshot() - 快照
  • .toHaveBeenCalled()、.toHaveBeenCalledWith() - 模拟

模拟:

import { mock, spyOn } from "bun:test";

const mockFn = mock(() => 42);
mockFn.mockImplementation(() => 100);
mockFn.mockReturnValue(200);

const spy = spyOn(object, "method");
spy.mockResolvedValue({ data: "test" });

// Module mocking
mock.module("./api", () => ({
  fetchUser: mock(() => ({ id: 1, name: "Test" }))
}));

CLI 命令:

bun test                 # Run all tests
bun test --watch         # Watch mode
bun test --coverage      # Enable coverage
bun test -t "pattern"    # Filter by test name
bun test --timeout=5000  # Set timeout
bun test --bail          # Stop on first failure
bun test --update-snapshots  # Update snapshots

4. 打包器配置

JavaScript API:

const result = await Bun.build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./dist",
  target: "browser",  // "browser" | "bun" | "node"
  format: "esm",      // "esm" | "cjs" | "iife"
  minify: true,
  sourcemap: "external",
  splitting: true,    // Code splitting
  external: ["react", "react-dom"],
  define: {
    "process.env.NODE_ENV": '"production"'
  },
  loader: {
    ".png": "dataurl",
    ".svg": "text"
  },
  plugins: [myPlugin],
  naming: {
    entry: "[dir]/[name].[ext]",
    chunk: "[name]-[hash].[ext]"
  }
});

if (!result.success) {
  console.error(result.logs);
}

CLI:

bun build ./src/index.tsx --outdir ./dist --minify --sourcemap=external
bun build ./src/index.ts --compile --outfile myapp  # Single executable

插件系统:

const myPlugin: BunPlugin = {
  name: "yaml-loader",
  setup(build) {
    build.onLoad({ filter: /\.yaml$/ }, async (args) => {
      const text = await Bun.file(args.path).text();
      return {
        contents: `export default ${JSON.stringify(YAML.parse(text))}`,
        loader: "js"
      };
    });
  }
};

5. TypeScript 集成

Bun 无需转译配置即可原生执行 TypeScript:

bun run index.ts      # Just works
bun run index.tsx     # JSX supported

推荐的 tsconfig.json:

{
  "compilerOptions": {
    "lib": ["ESNext"],
    "target": "ESNext",
    "module": "ESNext",
    "moduleDetection": "force",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "noEmit": true,
    "strict": true,
    "skipLibCheck": true,
    "types": ["bun-types"]
  }
}

类型检查(单独步骤):

bunx tsc --noEmit

6. 配置(bunfig.toml)
# Runtime
preload = ["./setup.ts"]
smol = true                    # Reduced memory mode

# JSX
[jsx]
runtime = "automatic"
importSource = "react"

# Package installation
[install]
optional = false
lockfile.save = true

[install.scopes]
"@myorg" = { url = "https://npm.myorg.com", token = "$NPM_TOKEN" }

# Test runner
[test]
preload = ["./test-setup.ts"]
coverage = true
coverageThreshold = { lines = 0.8, functions = 0.8 }

7. CLI 标志参考

执行:

  • --watch - 文件更改时自动重启
  • --hot - 热模块替换
  • --smol - 降低内存占用模式
  • --inspect / --inspect-brk - 调试器

模块解析:

  • --preload / -r - 预加载模块
  • --install=auto|fallback|force - 自动安装行为

转译:

  • --define / -d - 编译时常量
  • --drop=console - 移除函数调用
  • --loader - 自定义文件加载器

环境:

  • --env-file - 加载指定的 .env 文件
  • --cwd - 设置工作目录
  • --bun / -b - 强制使用 Bun 运行时

Node.js 迁移指南

快速迁移步骤
  1. 安装 Bun: curl -fsSL https://bun.sh/install | bash
  2. 替换包管理器:
# Delete node_modules and lockfile
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml
bun install
  1. 更新 package.json 中的脚本:
{
  "scripts": {
    "dev": "bun run --watch src/index.ts",
    "test": "bun test",
    "build": "bun build src/index.ts --outdir dist"
  }
}
  1. 更新 TypeScript 类型:
bun add -d @types/bun
# Or in tsconfig.json: "types": ["bun-types"]
API 兼容性

完全兼容:

  • node:assert、node:buffer、node:events、node:path、node:url
  • node:fs(92%)、node:http、node:https、node:stream、node:zlib
  • node:crypto、node:net、node:dns、node:os

部分兼容:

  • node:child_process - 缺少 proc.gid、proc.uid;IPC 仅支持 JSON
  • node:cluster - 仅 Linux 支持用于负载均衡的 SO_REUSEPORT
  • node:http2 - 95% 兼容;缺少 pushStream
  • node:worker_threads - 缺少 stdin、stdout、stderr 选项
  • node:async_hooks - AsyncLocalStorage 可用;缺少 v8 promise hooks

尚未实现:

  • node:inspector、node:repl、node:trace_events
常见迁移注意事项
  1. 原生模块: 使用 node-gyp 的软件包(bcrypt、sharp)可能无法运行
    • 解决方案:使用纯 JS 替代方案(例如用 bcryptjs 替代 bcrypt)
  2. 生命周期脚本: Bun 默认阻止 postinstall(安全措施)
    • 解决方案:使用 bun pm trust <package>,或将其添加到 trustedDependencies
  3. 模块系统: 依赖 Node.js 内部实现的某些软件包可能无法运行
    • Bun 中不存在 Module._nodeModulePaths
  4. 文件系统差异: 大量并发读取文件可能导致内存问题
    • 解决方案:使用 graceful-fs 封装器
  5. TypeScript 入口点: 为 Bun 更新 "main" 字段:
{
  "main": "src/index.ts"  // Not "build/index.js"
}
渐进式迁移策略

阶段 1: 仅使用包管理器(bun install) 阶段 2: 使用开发工具(bun run、bun test) 阶段 3: 选择性迁移运行时(影子部署) 阶段 4: 完整迁移到生产环境


最佳实践

性能优化
// Use Bun's native APIs for I/O
const file = Bun.file("large.txt");  // Zero-copy
const content = await file.text();
await Bun.write("output.txt", processedData);

// Use Promise.all for concurrent operations
const [users, posts] = await Promise.all([
  db.query("SELECT * FROM users"),
  db.query("SELECT * FROM posts")
]);

// Use Bun.serve() static routes
Bun.serve({
  static: {
    "/": homepage,
    "/about": aboutPage
  },
  fetch(req) { /* dynamic routes */ }
});

// Use bun:sqlite for local data
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
const stmt = db.prepare("SELECT * FROM users WHERE id = ?");
错误处理
// HTTP server error handling
Bun.serve({
  fetch(req) {
    try {
      return handleRequest(req);
    } catch (error) {
      console.error(error);
      return new Response("Internal Error", { status: 500 });
    }
  },
  error(error) {
    return new Response(`Error: ${error.message}`, { status: 500 });
  }
});

// Process-level error handling
process.on("uncaughtException", (error) => {
  console.error("Uncaught:", error);
  process.exit(1);
});
安全最佳实践
  1. 生命周期脚本: 尽量精简 trustedDependencies
  2. 环境变量: 使用 .env.local 存放机密信息(不要提交)
  3. 输入验证: 清理所有用户输入
  4. 依赖项: 定期运行 bun audit
  5. 生产环境: 使用 --production 标志跳过 devDependencies
项目结构
my-bun-project/
├── src/
│   ├── index.ts        # Entry point
│   ├── server.ts       # HTTP server
│   └── lib/            # Utilities
├── test/
│   └── *.test.ts       # Test files
├── bunfig.toml         # Bun configuration
├── tsconfig.json       # TypeScript config
├── package.json
└── .env.local          # Local secrets (gitignored)

调试

Web 调试器:

bun --inspect server.ts         # Start debugger
bun --inspect-brk server.ts     # Break at first line
bun --inspect-wait server.ts    # Wait for connection

打开 https://debug.bun.sh,或使用 VSCode Bun 扩展。

详细的 Fetch 日志:

BUN_CONFIG_VERBOSE_FETCH=curl bun run server.ts

示例

使用 WebSocket 的 HTTP 服务
Bun.serve({
  port: 3000,
  fetch(req, server) {
    if (server.upgrade(req)) return;
    return new Response("Hello Bun!");
  },
  websocket: {
    open(ws) { console.log("Connected"); },
    message(ws, message) { ws.send(`Echo: ${message}`); },
    close(ws) { console.log("Disconnected"); }
  }
});
文件服务
Bun.serve({
  async fetch(req) {
    const path = new URL(req.url).pathname;
    const file = Bun.file(`./public${path}`);
    if (await file.exists()) {
      return new Response(file);
    }
    return new Response("Not Found", { status: 404 });
  }
});
使用 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 (?, ?)");
const getAll = db.prepare("SELECT * FROM users");

insert.run("Alice", "[email protected]");
const users = getAll.all();

此技能的激活条件

在以下情况下,此技能会自动激活:

  • 在 Bun 项目中处理 .ts、.tsx、.js、.jsx 文件
  • 创建或修改 bunfig.toml 或 bun.lock
  • 使用 bun:test、bun:sqlite、bun:ffi 导入
  • 讨论 Bun API(Bun.serve、Bun.file、Bun.build)
  • 从 Node.js 迁移到 Bun
  • 编写或调试 Bun 测试
  • 配置 Bun 打包器

评论

支持 Markdown