Bun开发技能Skill bun

Bun是一个快速的JavaScript运行时,用于构建和运行JavaScript/TypeScript应用程序的全栈开发工具链。它集成了包管理、HTTP服务器、SQLite数据库、密码哈希、进程管理、加密、捆绑和测试等功能,旨在替代Node.js,显著提升开发效率和性能。关键词:Bun, JavaScript, TypeScript, 运行时, 快速开发, 全栈工具, 包管理, 测试框架, 性能优化。

后端开发 0 次安装 0 次浏览 更新于 3/22/2026

名称: bun 描述: 使用Bun JavaScript运行时构建快速应用程序。适用于创建Bun项目、使用Bun API、捆绑、测试或优化Node.js替代方案。触发词:Bun, Bun runtime, bun.sh, bunx, Bun serve, Bun test, JavaScript runtime。

Bun - 快速的JavaScript运行时

使用Bun的一体化工具包构建和运行JavaScript/TypeScript应用程序。

快速开始

# 安装Bun(macOS、Linux、WSL)
curl -fsSL https://bun.sh/install | bash

# Windows
powershell -c "irm bun.sh/install.ps1 | iex"

# 创建新项目
bun init

# 直接运行TypeScript(无需构建步骤!)
bun run index.ts

# 安装包(比npm更快)
bun install

# 运行脚本
bun run dev

包管理

# 安装依赖
bun install              # 从package.json安装所有
bun add express          # 添加依赖
bun add -d typescript    # 添加开发依赖
bun add -g serve         # 添加全局包

# 移除包
bun remove express

# 更新包
bun update

# 运行包二进制文件
bunx prisma generate     # 类似npx但更快
bunx create-next-app

# 锁文件
bun install --frozen-lockfile  # CI模式

bun.lockb vs package-lock.json

# Bun使用二进制锁文件(bun.lockb)- 更快
# 为兼容性生成yarn.lock:
bun install --yarn

# 从其他锁文件导入
bun install  # 自动检测package-lock.json、yarn.lock

Bun运行时

运行文件

# 运行任何文件
bun run index.ts         # TypeScript
bun run index.js         # JavaScript
bun run index.jsx        # JSX

# 监视模式
bun --watch run index.ts

# 热重载
bun --hot run server.ts

内置API

// 文件I/O(超快)
const file = Bun.file('data.json');
const content = await file.text();
const json = await file.json();
const bytes = await file.arrayBuffer();

// 写入文件
await Bun.write('output.txt', 'Hello, Bun!');
await Bun.write('data.json', JSON.stringify({ key: 'value' }));
await Bun.write('image.png', await fetch('https://example.com/img.png'));

// 文件元数据
const file = Bun.file('data.json');
console.log(file.size);       // 字节
console.log(file.type);       // MIME类型
console.log(file.lastModified);

// 全局文件
const glob = new Bun.Glob('**/*.ts');
for await (const file of glob.scan('.')) {
  console.log(file);
}

HTTP服务器

// 简单服务器
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!' });
    }
    
    return new Response('Not Found', { status: 404 });
  },
});

console.log(`服务器运行在 http://localhost:${server.port}`);

高级服务器

Bun.serve({
  port: 3000,
  
  // 主请求处理程序
  async fetch(req, server) {
    const url = new URL(req.url);
    
    // WebSocket升级
    if (url.pathname === '/ws') {
      const upgraded = server.upgrade(req, {
        data: { userId: '123' },  // 附加数据到socket
      });
      if (upgraded) return undefined;
    }
    
    // 静态文件
    if (url.pathname.startsWith('/static/')) {
      const filePath = `./public${url.pathname}`;
      const file = Bun.file(filePath);
      if (await file.exists()) {
        return new Response(file);
      }
    }
    
    // JSON API
    if (url.pathname === '/api/data' && req.method === 'POST') {
      const body = await req.json();
      return Response.json({ received: body });
    }
    
    return new Response('Not Found', { status: 404 });
  },
  
  // WebSocket处理程序
  websocket: {
    open(ws) {
      console.log('客户端连接:', ws.data.userId);
      ws.subscribe('chat');  // 发布/订阅
    },
    message(ws, message) {
      // 广播给所有订阅者
      ws.publish('chat', message);
    },
    close(ws) {
      console.log('客户端断开连接');
    },
  },
  
  // 错误处理
  error(error) {
    return new Response(`错误:${error.message}`, { status: 500 });
  },
});

WebSocket客户端

const ws = new WebSocket('ws://localhost:3000/ws');

ws.onopen = () => {
  ws.send('Hello, server!');
};

ws.onmessage = (event) => {
  console.log('收到:', event.data);
};

Bun API

SQLite(内置)

import { Database } from 'bun:sqlite';

const db = new Database('mydb.sqlite');

// 创建表
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('Alice', 'alice@example.com');

// 查询
const query = db.prepare('SELECT * FROM users WHERE id = ?');
const user = query.get(1);

// 所有结果
const allUsers = db.prepare('SELECT * FROM users').all();

// 事务
const insertMany = db.transaction((users) => {
  for (const user of users) {
    insert.run(user.name, user.email);
  }
});

insertMany([
  { name: 'Bob', email: 'bob@example.com' },
  { name: 'Charlie', email: 'charlie@example.com' },
]);

密码哈希(内置)

// 哈希密码
const hash = await Bun.password.hash('mypassword', {
  algorithm: 'argon2id',  // 或 'bcrypt'
  memoryCost: 65536,      // 64 MB
  timeCost: 2,
});

// 验证密码
const isValid = await Bun.password.verify('mypassword', hash);

生成进程

// 生成进程
const proc = Bun.spawn(['ls', '-la'], {
  cwd: '/home/user',
  env: { ...process.env, MY_VAR: 'value' },
  stdout: 'pipe',
});

const output = await new Response(proc.stdout).text();
console.log(output);

// 同步生成
const result = Bun.spawnSync(['echo', 'hello']);
console.log(result.stdout.toString());

// Shell命令
const { stdout } = Bun.spawn({
  cmd: ['sh', '-c', 'echo $HOME'],
  stdout: 'pipe',
});

哈希与加密

// 哈希字符串
const hash = Bun.hash('hello world');  // Wyhash(快速)

// 加密哈希
const sha256 = new Bun.CryptoHasher('sha256');
sha256.update('data');
const digest = sha256.digest('hex');

// 一行代码
const md5 = Bun.CryptoHasher.hash('md5', 'data', 'hex');

// HMAC
const hmac = Bun.CryptoHasher.hmac('sha256', 'secret-key', 'data', 'hex');

捆绑器

# 为浏览器打包
bun build ./src/index.ts --outdir ./dist

# 打包选项
bun build ./src/index.ts \
  --outdir ./dist \
  --minify \
  --sourcemap \
  --target browser \
  --splitting \
  --entry-naming '[dir]/[name]-[hash].[ext]'

构建API

const result = await Bun.build({
  entrypoints: ['./src/index.ts'],
  outdir: './dist',
  minify: true,
  sourcemap: 'external',
  target: 'browser',  // 'bun' | 'node' | 'browser'
  splitting: true,
  naming: {
    entry: '[dir]/[name]-[hash].[ext]',
    chunk: '[name]-[hash].[ext]',
    asset: '[name]-[hash].[ext]',
  },
  external: ['react', 'react-dom'],
  define: {
    'process.env.NODE_ENV': JSON.stringify('production'),
  },
  loader: {
    '.png': 'file',
    '.svg': 'text',
  },
});

if (!result.success) {
  console.error('构建失败:', result.logs);
}

测试

// test.ts
import { describe, test, expect, beforeAll, afterAll, mock } from 'bun:test';

describe('数学操作', () => {
  test('加法', () => {
    expect(1 + 1).toBe(2);
  });
  
  test('数组包含', () => {
    expect([1, 2, 3]).toContain(2);
  });
  
  test('对象匹配', () => {
    expect({ name: 'Alice', age: 30 }).toMatchObject({ name: 'Alice' });
  });
  
  test('异步测试', async () => {
    const result = await Promise.resolve(42);
    expect(result).toBe(42);
  });
  
  test('抛出错误', () => {
    expect(() => {
      throw new Error('fail');
    }).toThrow('fail');
  });
});

// 模拟
const mockFn = mock(() => '模拟');
mockFn();
expect(mockFn).toHaveBeenCalled();

// 模拟模块
mock.module('./database', () => ({
  query: mock(() => [{ id: 1 }]),
}));
# 运行测试
bun test

# 监视模式
bun test --watch

# 特定文件
bun test user.test.ts

# 覆盖率
bun test --coverage

Node.js兼容性

// 大多数Node.js API开箱即用
import fs from 'fs';
import path from 'path';
import { createServer } from 'http';
import express from 'express';

// Bun实现Node.js API
const data = fs.readFileSync('file.txt', 'utf-8');
const fullPath = path.join(__dirname, 'file.txt');

// Express有效!
const app = express();
app.get('/', (req, res) => res.send('Hello!'));
app.listen(3000);

Node.js vs Bun API

// Node.js方式
import { readFile } from 'fs/promises';
const content = await readFile('file.txt', 'utf-8');

// Bun方式(更快)
const content = await Bun.file('file.txt').text();

// Node.js加密
import crypto from 'crypto';
const hash = crypto.createHash('sha256').update('data').digest('hex');

// Bun方式(更快)
const hash = Bun.CryptoHasher.hash('sha256', 'data', 'hex');

环境变量

// .env文件支持(内置,无需dotenv!)
// .env
// DATABASE_URL=postgres://localhost/db
// API_KEY=secret

// 访问环境变量
const dbUrl = Bun.env.DATABASE_URL;
const apiKey = process.env.API_KEY;  // 同样有效

// bunfig.toml用于Bun配置
// [run]
// preload = ["./setup.ts"]

HTTP客户端

// Fetch(在Bun中优化)
const response = await fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token',
  },
  body: JSON.stringify({ key: 'value' }),
});

const data = await response.json();

// 流式响应
const response = await fetch('https://api.example.com/stream');
const reader = response.body?.getReader();

while (true) {
  const { done, value } = await reader!.read();
  if (done) break;
  console.log(new TextDecoder().decode(value));
}

项目结构

my-bun-project/
├── src/
│   ├── index.ts          # 入口点
│   ├── routes/
│   │   └── api.ts
│   └── lib/
│       └── database.ts
├── tests/
│   └── index.test.ts
├── public/
│   └── 静态文件
├── package.json
├── bunfig.toml           # Bun配置(可选)
├── tsconfig.json
└── .env

bunfig.toml

[install]
# 默认使用精确版本
exact = true

# 注册表
registry = "https://registry.npmjs.org"

[run]
# 在`bun run`之前运行的脚本
preload = ["./instrumentation.ts"]

[test]
# 测试配置
coverage = true
coverageDir = "coverage"

[bundle]
# 默认打包配置
minify = true
sourcemap = "external"

性能比较

操作 Node.js Bun 速度提升
启动时间 ~40ms ~7ms 5.7倍
包安装 ~10s ~1s 10倍
文件读取 基准 更快 10倍
HTTP服务器 基准 更快 4倍
SQLite 外部 内置 3倍
TypeScript 需要编译 原生

资源