编程 Bun 1.3 深度实战:当 JavaScript 运行时进化为全栈平台——从 HTML 文件运行到统一 SQL API、路由系统与生产级部署的完全指南(2026)

2026-06-18 15:24:38 +0800 CST views 4

Bun 1.3 深度实战:当 JavaScript 运行时进化为全栈平台

从 HTML 文件运行到统一 SQL API、路由系统与生产级部署的完全指南(2026)


引言:一个运行时的「全栈野心」

2025年10月10日,Bun 团队发布了 1.3 版本。这不是一次常规的版本迭代——这是 Bun 从「更快的 Node.js」向「完整的 JavaScript 开发平台」的战略转型。

如果你还停留在「Bun 就是跑得快」的认知,这篇文章会颠覆你的世界观。Bun 1.3 带来的不仅是性能数字,更是一套完整的全栈开发解决方案:直接运行 HTML 文件、内置多数据库客户端、原生路由系统、Cookie 管理、企业级包管理特性、跨平台可执行文件编译……甚至还有密钥管理和 CSRF 防护。

这不是「功能堆砌」,这是一个经过深思熟虑的工程体系。让我们深入剖析 Bun 1.3 的每一个核心特性,理解其设计哲学,并掌握生产级落地技巧。


第一部分:从运行时到全栈平台——设计哲学的演变

1.1 为什么要做「全栈」?

传统 JavaScript 开发的工作流是这样的:

前端开发服务器 (Vite/Webpack, port 5173)
    ↓
后端 API 服务器 (Express/Fastify, port 3000)
    ↓
数据库连接 (pg/mysql2/redis)
    ↓
代理服务器 (Nginx/Caddy)

这个架构有几个显而易见的痛点:

  1. CORS 地狱:前后端分离端口导致跨域问题,开发环境要配置代理,生产环境要配置 CORS 头
  2. 工具碎片化:包管理用 npm/yarn/pnpm,打包用 Webpack/Vite/esbuild,测试用 Jest/Vitest,运行时用 Node.js
  3. 冷启动开销:每个工具都是独立进程,启动时间叠加
  4. 依赖爆炸:一个全栈项目可能有上百个 devDependencies

Bun 1.3 的回答是:把这些都塞进一个进程里

# 传统方式
npm install express pg redis cors
npm install -D typescript @types/node @types/express @types/pg
npx tsc --watch  # 终端 1
node dist/server.js  # 终端 2

# Bun 1.3 方式
bun run index.ts  # 就这一个命令

这不是「省几行命令」,而是从根本上改变了开发体验。

1.2 架构演进:从「一体化」到「原生集成」

Bun 的架构可以概括为四个层次:

┌─────────────────────────────────────────────────────────┐
│                    工具链层                              │
│  Package Manager │ Bundler │ Test Runner │ Dev Server   │
├─────────────────────────────────────────────────────────┤
│                  JavaScript 运行时层                     │
│            JavaScriptCore (JIT + GC)                    │
├─────────────────────────────────────────────────────────┤
│                    原生模块层                            │
│   HTTP Server │ SQL Client │ Crypto │ WebSocket │ YAML  │
├─────────────────────────────────────────────────────────┤
│                  底层系统接口层                          │
│              Zig + Native System Calls                  │
└─────────────────────────────────────────────────────────┘

这个架构的核心优势是原生集成——不是通过 FFI 调用外部库,而是直接在运行时层面实现功能。这意味着:

  • HTTP 服务器不依赖 Node.js 的 http 模块,性能更高
  • SQL 客户端不依赖 pgmysql2,没有跨进程通信开销
  • 打包器不依赖外部工具,共享运行时的代码缓存

这就是为什么 Bun 能在某些场景下比 Node.js 快 10 倍——不是因为 JavaScript 执行更快,而是因为减少了跨边界调用。


第二部分:HTML 文件运行——前端开发的一级支持

2.1 这意味着什么?

Bun 1.3 最引人注目的特性是:

bun ./**/*.html

执行这个命令后,Bun 会自动识别项目中的 HTML 文件,启动一个功能完整的开发服务器,包括:

  • 热模块替换 (HMR):修改代码后浏览器自动刷新
  • React Fast Refresh:React 组件状态保持
  • TypeScript 转译:直接在 <script> 标签中使用 TS
  • JSX 处理:无需配置,自动编译

让我们看一个具体例子:

<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Bun 全栈示例</title>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="./App.tsx"></script>
</body>
</html>
// App.tsx
import { useState } from "react";
import { render } from "react-dom/client";

function App() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <h1>Bun + React</h1>
      <p>点击次数: {count}</p>
      <button onClick={() => setCount(c => c + 1)}>+1</button>
    </div>
  );
}

render(<App />, document.getElementById("root")!);

运行 bun index.html,浏览器打开 http://localhost:3000,你会看到一个可交互的 React 应用——零配置

2.2 技术实现:不是静态服务器

Bun 的 HTML 运行时不是简单的静态文件服务器,而是一个智能转译管道

请求 HTML 文件
    ↓
解析 HTML 结构
    ↓
识别 <script> 和 <link> 标签
    ↓
对于 TS/TSX 文件:
  - TypeScript 编译
  - JSX 转换
  - HMR 注入
    ↓
对于 CSS 文件:
  - PostCSS 处理(如果配置)
  - Source Map 生成
    ↓
返回处理后的响应

关键代码(简化版):

// Bun 内部的 HTML 处理逻辑
async function handleHTML(request: Request, filePath: string) {
  const html = await Bun.file(filePath).text();
  
  // 解析 HTML,提取脚本引用
  const scripts = extractScripts(html);
  
  // 为每个脚本添加 HMR 客户端代码
  const hmrClient = `
    new EventSource("/__bun_hmr").addEventListener("message", (e) => {
      if (e.data === "reload") location.reload();
    });
  `;
  
  // 注入 HMR 代码
  const processedHTML = injectScript(html, hmrClient);
  
  return new Response(processedHTML, {
    headers: { "Content-Type": "text/html; charset=utf-8" }
  });
}

2.3 实战场景:快速原型开发

这个特性最适合的场景是快速原型开发小型项目

# 创建一个新项目
mkdir my-app && cd my-app

# 写一个简单的 HTML + TSX
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
  <div id="app"></div>
  <script type="module" src="./app.ts"></script>
</body>
</html>
EOF

cat > app.ts << 'EOF'
// 直接使用 TypeScript,无需配置
const greeting: string = "Hello, Bun 1.3!";
document.getElementById("app")!.textContent = greeting;
EOF

# 运行
bun index.html

对于大型项目,你仍然应该使用 Vite 或 Next.js——但 Bun 的 HTML 运行时填补了一个空白:在「Hello World」和「企业级应用」之间的巨大鸿沟


第三部分:统一 SQL API——数据库访问的革命

3.1 问题:npm 里的「数据库驱动地狱」

传统的 Node.js 数据库访问是这样的:

// PostgreSQL
import pg from "pg";
const pgPool = new pg.Pool({ connectionString: process.env.DATABASE_URL });

// MySQL
import mysql from "mysql2/promise";
const mysqlPool = mysql.createPool(process.env.MYSQL_URL);

// SQLite(是的,这是另一个库)
import Database from "better-sqlite3";
const sqlite = new Database("./data.db");

// Redis(又是另一个库)
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL);

每个库都有自己的 API、连接池实现、错误处理方式。如果你需要在同一个项目中使用多种数据库,代码会变得非常混乱。

3.2 Bun 的解决方案:统一 API

Bun 1.3 提供了统一的 Bun.SQL API:

import { sql, SQL } from "bun";

// 连接不同数据库——相同的 API
const postgres = new SQL("postgres://localhost/mydb");
const mysql = new SQL("mysql://localhost/mydb");
const sqlite = new SQL("sqlite://data.db");

// 自动从环境变量读取
// DATABASE_URL 或 BUN_DATABASE_URL
const users = await sql`SELECT * FROM users LIMIT 10`;

// 参数化查询——防止 SQL 注入
const userId = 123;
const user = await sql`SELECT * FROM users WHERE id = ${userId}`;

// 插入数据
const newUser = { name: "张三", email: "zhang@example.com" };
const [inserted] = await sql`
  INSERT INTO users ${sql(newUser)}
  RETURNING *
`;

// 更新数据
await sql`
  UPDATE users 
  SET last_login = NOW() 
  WHERE id = ${userId}
`;

3.3 性能数据:原生实现的优势

Bun 的 SQL 客户端是用 Zig 编写的原生实现,绕过了 Node.js 的 C++ 绑定层。官方基准测试显示:

操作Bun SQLpg 库提升
简单查询0.3ms0.8ms2.6x
带参数查询0.4ms1.1ms2.75x
批量插入 (1000 行)12ms45ms3.75x
连接获取0.01ms0.05ms5x

更重要的是,Redis 客户端的性能达到了 ioredis 的 7.9 倍

3.4 高级特性:连接池和事务

// 连接池配置
const db = new SQL("postgres://localhost/mydb", {
  max: 20,           // 最大连接数
  idle: 10000,       // 空闲超时 (ms)
  timeout: 30000,    // 查询超时 (ms)
});

// 事务
await sql.begin(async (tx) => {
  // 在事务中执行多个操作
  await tx`INSERT INTO orders (user_id, total) VALUES (1, 99.99)`;
  await tx`UPDATE users SET order_count = order_count + 1 WHERE id = 1`;
  
  // 如果任何操作失败,整个事务回滚
});

// 流式查询——处理大数据集
for await (const row of sql`SELECT * FROM large_table`) {
  processRow(row);
}

3.5 实战建议

何时使用 Bun SQL:

  • 新项目,没有历史包袱
  • 需要高性能数据库访问
  • 项目需要多种数据库支持

何时仍用传统库:

  • 项目已深度依赖 ORM(Prisma、Drizzle)
  • 需要特定的数据库特性(如 PostgreSQL 的 LISTEN/NOTIFY)
  • 团队已有成熟的数据库抽象层

第四部分:路由系统——优雅的全栈应用架构

4.1 问题:Express 的「路由文件」

传统 Express 项目的主文件往往是这样的:

// app.js
const express = require("express");
const app = express();

// 导入各种路由
const userRoutes = require("./routes/users");
const authRoutes = require("./routes/auth");
const apiRoutes = require("./routes/api");

// 挂载路由
app.use("/users", userRoutes);
app.use("/auth", authRoutes);
app.use("/api", apiRoutes);

// 静态文件
app.use(express.static("public"));

app.listen(3000);

然后你还需要多个路由文件,静态文件目录,前端构建配置……这是「框架地狱」的雏形。

4.2 Bun 的解决方案:路由优先

Bun 1.3 为 Bun.serve() 引入了内置路由:

import { serve, sql } from "bun";
import App from "./myReactSPA.html";

serve({
  port: 3000,
  routes: {
    // 前端应用——通配符匹配所有未定义的路由
    "/*": App,
    
    // API 路由——GET 请求
    "/api/users": {
      GET: async () => {
        const users = await sql`SELECT * FROM users LIMIT 10`;
        return Response.json(users);
      },
      
      // POST 请求
      POST: async (req) => {
        const { name, email } = await req.json();
        const [user] = await sql`
          INSERT INTO users ${sql({ name, email })}
          RETURNING *
        `;
        return Response.json(user, { status: 201 });
      },
    },
    
    // 参数化路由
    "/api/users/:id": async (req) => {
      const { id } = req.params;
      const [user] = await sql`
        SELECT * FROM users WHERE id = ${id} LIMIT 1
      `;
      
      if (!user) {
        return new Response("User not found", { status: 404 });
      }
      
      return Response.json(user);
    },
    
    // 健康检查
    "/health": () => new Response("OK"),
  },
});

console.log("Server running at http://localhost:3000");

4.3 架构优势:同进程全栈

这个设计的精妙之处在于:前端和后端在同一个进程中运行

传统架构:
┌─────────────────┐     HTTP      ┌─────────────────┐
│  Vite Dev Server│──────────────→│  Express Server │
│   (port 5173)   │               │   (port 3000)   │
└─────────────────┘               └─────────────────┘
        │                                 │
        └───── 需要配置 CORS/代理 ─────────┘

Bun 架构:
┌───────────────────────────────────────────────────┐
│                  Bun Server (port 3000)            │
│  ┌─────────────┐  ┌─────────────┐  ┌───────────┐  │
│  │ HTML/React  │  │  API Routes │  │  SQL 查询 │  │
│  └─────────────┘  └─────────────┘  └───────────┘  │
└───────────────────────────────────────────────────┘
        │
        └───── 无 CORS 问题,共享内存空间 ─────

4.4 实战:构建一个完整的全栈应用

// server.ts
import { serve, sql, randomUUIDv7 } from "bun";

// 创建会话表(首次运行时)
await sql`
  CREATE TABLE IF NOT EXISTS sessions (
    id TEXT PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    created_at TIMESTAMP DEFAULT NOW(),
    expires_at TIMESTAMP
  )
`;

serve({
  port: 3000,
  
  // 错误处理
  error(error) {
    return new Response(`Error: ${error.message}`, { status: 500 });
  },
  
  routes: {
    // 静态文件
    "/static/*": async (req) => {
      const path = new URL(req.url).pathname.replace("/static", "");
      const file = Bun.file(`./public${path}`);
      
      if (!(await file.exists())) {
        return new Response("Not Found", { status: 404 });
      }
      
      return new Response(file);
    },
    
    // API: 登录
    "/api/auth/login": {
      POST: async (req) => {
        const { email, password } = await req.json();
        
        const [user] = await sql`
          SELECT * FROM users 
          WHERE email = ${email} AND password = crypt(${password}, password)
        `;
        
        if (!user) {
          return Response.json(
            { error: "Invalid credentials" }, 
            { status: 401 }
          );
        }
        
        // 创建会话
        const sessionId = randomUUIDv7();
        await sql`
          INSERT INTO sessions (id, user_id, expires_at)
          VALUES (${sessionId}, ${user.id}, NOW() + INTERVAL '7 days')
        `;
        
        return Response.json(
          { user: { id: user.id, name: user.name } },
          {
            headers: {
              "Set-Cookie": `session_id=${sessionId}; HttpOnly; Secure; SameSite=Strict; Max-Age=604800`
            }
          }
        );
      },
    },
    
    // API: 获取当前用户
    "/api/me": async (req) => {
      const sessionId = req.cookies.get("session_id");
      
      if (!sessionId) {
        return Response.json({ error: "Not authenticated" }, { status: 401 });
      }
      
      const [session] = await sql`
        SELECT s.*, u.name, u.email 
        FROM sessions s
        JOIN users u ON s.user_id = u.id
        WHERE s.id = ${sessionId} AND s.expires_at > NOW()
      `;
      
      if (!session) {
        return Response.json({ error: "Session expired" }, { status: 401 });
      }
      
      return Response.json({
        user: { id: session.user_id, name: session.name, email: session.email }
      });
    },
    
    // 前端应用
    "/*": Bun.file("./dist/index.html"),
  },
});

5.1 传统方式:第三方库的困扰

在 Node.js 中处理 Cookie 通常需要:

// 方案 1:使用 cookie-parser 中间件
const cookieParser = require("cookie-parser");
app.use(cookieParser());

// 方案 2:使用 tough-cookie 库
const { CookieJar } = require("tough-cookie");
const jar = new CookieJar();

// 方案 3:手动解析(容易出错)
const cookies = req.headers.cookie?.split(";").reduce((acc, c) => {
  const [k, v] = c.trim().split("=");
  acc[k] = v;
  return acc;
}, {});

每个方案都有问题:

  • 中间件增加依赖
  • 第三方库 API 复杂
  • 手动解析不安全

Bun 1.3 提供了零依赖的 Cookie 管理:

import { serve, randomUUIDv7 } from "bun";

serve({
  routes: {
    "/api/login": (req) => {
      // 设置 Cookie
      req.cookies.set("sessionId", randomUUIDv7(), {
        httpOnly: true,      // 防止 XSS
        secure: true,        // 仅 HTTPS
        sameSite: "strict",  // 防止 CSRF
        maxAge: 60 * 60 * 24 * 7, // 7 天
        path: "/",
      });
      
      return new Response("Logged in");
    },
    
    "/api/check": (req) => {
      // 读取 Cookie
      const sessionId = req.cookies.get("sessionId");
      
      if (!sessionId) {
        return new Response("Not logged in", { status: 401 });
      }
      
      return new Response(`Session: ${sessionId}`);
    },
    
    "/api/logout": (req) => {
      // 删除 Cookie
      req.cookies.delete("sessionId");
      return new Response("Logged out");
    },
  },
});

5.3 性能优化:延迟解析

Bun 的 Cookie 实现有一个精妙的优化:零开销延迟解析

// 只有在访问 req.cookies 时才会解析 Cookie 头
serve({
  routes: {
    "/api/data": (req) => {
      // 如果这个路由不需要 Cookie,解析就不会发生
      return Response.json({ data: "public" });
    },
    
    "/api/private": (req) => {
      // 只有在这里才会解析
      const session = req.cookies.get("session");
      return Response.json({ session });
    },
  },
});

这个设计避免了每个请求都解析 Cookie 头的开销。


第六部分:包管理器的企业级特性

6.1 隔离安装:解决「幽灵依赖」

在传统的提升安装模式下,所有依赖都平铺在根目录的 node_modules 中:

node_modules/
├── express/
├── lodash/        ← 你的代码可以直接访问
├── body-parser/   ← 这是 express 的依赖
└── debug/         ← 你的代码「意外」可以访问

问题在于:你的代码可能访问到未在 package.json 中声明的依赖。这在 monorepo 中是常见问题。

Bun 1.3 将隔离模式设为默认:

packages/web/node_modules/
├── react/         ← 只有 web 包可以访问
└── lodash/        ← 只有 web 包可以访问

packages/api/node_modules/
├── express/       ← 只有 api 包可以访问
└── pg/            ← 只有 api 包可以访问

配置方式:

# bunfig.toml
[install]
isolated = true  # 默认已启用

6.2 依赖目录 (Catalogs):集中版本管理

// 根目录 package.json
{
  "name": "my-monorepo",
  "workspaces": ["packages/*"],
  "catalog": {
    "react": "^18.3.0",
    "typescript": "^5.5.0",
    "zod": "^3.23.0"
  }
}
// packages/web/package.json
{
  "name": "web",
  "dependencies": {
    "react": "catalog:"  // 自动使用根目录定义的版本
  }
}
// packages/admin/package.json
{
  "name": "admin",
  "dependencies": {
    "react": "catalog:"  // 同样使用 ^18.3.0
  }
}

这解决了「同一个 monorepo 中不同包使用不同版本」的问题。

6.3 安全扫描:拦截恶意包

Bun 1.3 引入了安装时安全扫描 API:

# bunfig.toml
[install.security]
scanner = "@socketsecurity/bun-security-scanner"

[install]
minimumReleaseAge = 604800  # 包必须发布至少 7 天

这个配置实现:

  1. 每个包安装前进行安全扫描
  2. 检测已知的恶意包和漏洞
  3. 拦截刚发布可能含有恶意代码的包

6.4 交互式更新

bun update --interactive

输出:

📦 Found 12 outdated packages

  react              18.2.0  →  18.3.0   (patch)
  typescript         5.4.0   →  5.5.0    (minor)
  next               14.0.0  →  15.0.0   (major) ⚠️
  tailwindcss        3.3.0   →  4.0.0    (major) ⚠️

? Select packages to update: (Press <space> to select)
❯◯ react
 ◯ typescript
 ◯ next (breaking changes possible)
 ◯ tailwindcss (breaking changes possible)

这让你可以逐个选择要更新的包,而不是一次性升级所有依赖。


第七部分:测试框架的成熟化

7.1 并发测试

import { test, expect, describe } from "bun:test";

// 并发运行所有测试
test.concurrent("fetch user 1", async () => {
  const res = await fetch("/api/users/1");
  expect(res.status).toBe(200);
});

test.concurrent("fetch user 2", async () => {
  const res = await fetch("/api/users/2");
  expect(res.status).toBe(200);
});

// 整个 describe 块并发
describe.concurrent("API tests", () => {
  test("endpoint A", async () => { /* ... */ });
  test("endpoint B", async () => { /* ... */ });
  test("endpoint C", async () => { /* ... */ });
});

// 控制并发数
test("with custom concurrency", async () => { /* ... */ }, {
  concurrency: 10  // 最多 10 个测试同时运行
});

对于 I/O 密集型测试,这可以显著减少总运行时间。

7.2 类型测试

import { expectTypeOf, test } from "bun:test";

test("API returns correct types", () => {
  // 验证返回类型
  expectTypeOf(getUser()).resolves.toMatchTypeOf<{
    id: number;
    name: string;
    email: string;
  }>();
  
  // 验证函数参数类型
  expectTypeOf(createUser).parameter(0).toMatchTypeOf<{
    name: string;
    email: string;
  }>();
  
  // 验证数组元素类型
  expectTypeOf<Promise<number[]>>().resolves.toEqualTypeOf<number[]>();
});

类型断言通过 bunx tsc --noEmit 在 CI 中验证。

7.3 VS Code 集成

安装 Bun 扩展后:

  1. 测试资源管理器显示所有测试
  2. 点击运行/调试单个测试
  3. 内联显示失败原因
  4. 支持测试覆盖率高亮

第八部分:打包器与构建系统

8.1 跨平台可执行文件

Bun 1.3 支持将应用打包成单一可执行文件:

# 构建 Linux 可执行文件
bun build --compile --target=linux-x64 ./app.ts --outfile myapp-linux

# 构建 macOS (Apple Silicon)
bun build --compile --target=darwin-arm64 ./app.ts --outfile myapp-macos

# 构建 Windows
bun build --compile --target=windows-x64 ./app.ts --outfile myapp.exe

这对于以下场景特别有用:

  • CLI 工具分发
  • 微服务部署
  • 边缘计算应用
  • 无需安装 Node.js 的环境

8.2 Windows 元数据

bun build --compile --target=windows-x64 \
  --title="我的应用" \
  --publisher="我的公司" \
  --version="1.0.0" \
  --icon=./icon.ico \
  ./app.ts --outfile myapp.exe

生成的 EXE 文件会显示正确的文件属性。

8.3 代码签名

# macOS 代码签名
codesign --sign "Developer ID Application: Your Name" myapp-macos

# Windows Authenticode 签名
signtool sign /f certificate.pfx /p password myapp.exe

签名的可执行文件可以通过操作系统的安全验证。


第九部分:安全特性

9.1 Bun.secrets:原生密钥存储

import { secrets } from "bun";

// 存储密钥
await secrets.set({
  service: "my-app",
  name: "api-key",
  value: "super-secret-key",
});

// 读取密钥
const apiKey = await secrets.get({
  service: "my-app",
  name: "api-key",
});

// 删除密钥
await secrets.delete({
  service: "my-app",
  name: "api-key",
});

底层使用:

  • macOS: Keychain
  • Linux: libsecret
  • Windows: Credential Manager

密钥在静态时被加密,不会出现在环境变量或配置文件中。

9.2 Bun.CSRF:跨站请求伪造防护

import { CSRF } from "bun";

const secret = "your-secret-key";

// 生成 CSRF Token
const token = CSRF.generate({
  secret,
  encoding: "hex",
  expiresIn: 60 * 1000, // 1 分钟有效
});

// 验证 Token
const isValid = CSRF.verify(token, { secret });

if (!isValid) {
  return new Response("Invalid CSRF token", { status: 403 });
}

第十部分:Node.js 兼容性与迁移

10.1 兼容性数据

Bun 1.3 在每次提交时运行 Node.js 测试套件:

模块通过率
N-API98%+
timers98.4%
crypto95%+
fs94%+
http92%+

10.2 node:vm 模块支持

import vm from "node:vm";

// 创建沙箱环境
const context = vm.createContext({
  x: 1,
  console: { log: (...args) => console.log("[VM]", ...args) },
});

// 运行代码
vm.runInContext("console.log(x + 1)", context); // 输出: [VM] 2

// 创建模块
const module = new vm.SourceTextModule(`
  export const greeting = "Hello";
  export function greet(name) {
    return greeting + ", " + name;
  }
`);

// 链接依赖
await module.link(() => {});
await module.evaluate();

console.log(module.namespace.greet("World")); // Hello, World

10.3 迁移指南

从 Node.js 项目迁移到 Bun:

# 1. 安装 Bun
curl -fsSL https://bun.sh/install | bash

# 2. 迁移锁文件
bun import package-lock.json  # 从 npm
bun import yarn.lock          # 从 yarn
bun import pnpm-lock.yaml     # 从 pnpm

# 3. 安装依赖
bun install

# 4. 运行项目
bun run dev  # 替代 npm run dev

大部分项目可以零修改运行。


第十一部分:性能深度剖析

11.1 基准测试数据

操作Bun 1.3Node.js 22提升
HTTP 请求 (简单)35,000 req/s28,000 req/s1.25x
HTTP 请求 (带 JSON)22,000 req/s15,000 req/s1.47x
SQL 查询 (简单)50,000 qps18,000 qps2.78x
Redis GET180,000 ops/s23,000 ops/s7.8x
postMessage (字符串)500x faster-500x
启动时间5ms50ms10x
内存占用 (空闲)12MB35MB2.9x

11.2 为什么这么快?

  1. JavaScriptCore 引擎:启动快,内存低
  2. 原生模块:HTTP、SQL、Crypto 都是 Zig 实现
  3. 共享内存架构:打包器和运行时共享代码缓存
  4. 零拷贝 I/O:避免数据在 JS 和 C++ 之间复制
  5. 优化的 GC 调度:空闲时 CPU 占用极低

11.3 实战优化技巧

// 1. 使用流式处理大数据
for await (const chunk of Bun.file("large.txt").stream()) {
  process(chunk);
}

// 2. 利用 Worker 并行计算
const worker = new Worker("./heavy-calc.ts");
worker.postMessage(data);

// 3. 使用 Bun.sleep 代替 setTimeout
await Bun.sleep(1000);  // 更精确的延迟

// 4. 启用压缩
serve({
  routes: { /* ... */ },
  // WebSocket 自动启用 permessage-deflate
  websocket: { compress: true },
});

第十二部分:实战案例——构建一个全栈博客系统

12.1 项目结构

blog/
├── index.html           # 前端入口
├── components/
│   ├── Header.tsx
│   ├── PostList.tsx
│   └── PostEditor.tsx
├── server.ts            # 后端入口
├── migrations/
│   └── init.sql
└── bunfig.toml          # Bun 配置

12.2 完整代码

// server.ts
import { serve, sql } from "bun";

// 初始化数据库
await sql`
  CREATE TABLE IF NOT EXISTS posts (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT NOT NULL,
    author TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
  )
`;

serve({
  port: 3000,
  routes: {
    // API: 获取文章列表
    "/api/posts": {
      GET: async () => {
        const posts = await sql`
          SELECT * FROM posts ORDER BY created_at DESC
        `;
        return Response.json(posts);
      },
      
      POST: async (req) => {
        const { title, content, author } = await req.json();
        const [post] = await sql`
          INSERT INTO posts (title, content, author)
          VALUES (${title}, ${content}, ${author})
          RETURNING *
        `;
        return Response.json(post, { status: 201 });
      },
    },
    
    // API: 获取单篇文章
    "/api/posts/:id": async (req) => {
      const { id } = req.params;
      const [post] = await sql`
        SELECT * FROM posts WHERE id = ${id}
      `;
      
      if (!post) {
        return new Response("Not found", { status: 404 });
      }
      
      return Response.json(post);
    },
    
    // 前端
    "/*": Bun.file("./index.html"),
  },
});
// components/PostList.tsx
import { useState, useEffect } from "react";

interface Post {
  id: number;
  title: string;
  content: string;
  author: string;
  created_at: string;
}

export function PostList() {
  const [posts, setPosts] = useState<Post[]>([]);
  
  useEffect(() => {
    fetch("/api/posts")
      .then(res => res.json())
      .then(setPosts);
  }, []);
  
  return (
    <div className="post-list">
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>By {post.author} · {new Date(post.created_at).toLocaleDateString()}</p>
          <p>{post.content.slice(0, 200)}...</p>
        </article>
      ))}
    </div>
  );
}

12.3 运行

# 开发模式
bun server.ts

# 生产构建
bun build --compile ./server.ts --outfile blog-server

# 运行生产版本
./blog-server

第十三部分:生态系统与未来展望

13.1 企业采用

Midjourney 等公司已在生产环境中使用 Bun 进行前端开发。Socket 安全公司也与 Bun 团队合作,推出了官方安全扫描器。

13.2 未来规划

Bun 团队公布的路线图包括:

  1. Redis 集群支持
  2. 流式处理增强
  3. Lua 脚本支持(Redis 场景)
  4. WebAssembly 流式编译
  5. 更多 TC39 提案支持

13.3 与 Deno 的竞争

特性Bun 1.3Deno 2.x
启动速度5ms15ms
内存占用12MB25MB
npm 兼容原生兼容层
内置数据库
安全沙箱默认开启
前端开发原生 HTML需要框架

两者各有优势,Bun 更注重性能和开发体验,Deno 更注重安全性。


结语:Bun 的「全栈野心」

Bun 1.3 不是一个简单的版本更新,而是一次战略转型。从「更快的 Node.js」到「完整的 JavaScript 平台」,Bun 正在重新定义全栈开发的工作流。

这不是说 Bun 会取代所有现有工具:

  • 大型前端项目仍然需要 Vite/Next.js
  • 复杂后端服务仍然需要 NestJS/Fastify
  • 企业级 ORM 仍然需要 Prisma/Drizzle

但 Bun 填补了一个重要的空白:在「Hello World」和「企业级应用」之间,在「简单脚本」和「微服务架构」之间,提供一个开箱即用的解决方案

如果你正在启动一个新项目,或者想简化现有项目的工具链,Bun 1.3 值得一试。它可能不会改变你写代码的方式,但会改变你启动、运行、测试、部署的方式。

而这,正是「开发体验」的真正含义。


附录:常用命令速查

# 安装
curl -fsSL https://bun.sh/install | bash

# 运行
bun run app.ts
bun index.html

# 包管理
bun install
bun add package-name
bun remove package-name
bun update --interactive

# 测试
bun test
bun test --watch
bun test --coverage

# 构建
bun build ./app.ts --outfile dist/app.js
bun build --compile ./app.ts --outfile myapp

# 开发服务器
bun --hot server.ts
bun --watch server.ts

# 调试
bun --inspect server.ts

关键词: Bun 1.3, JavaScript 运行时, 全栈开发, SQL 客户端, 路由系统, Cookie 管理, 包管理器, 测试框架, 性能优化, TypeScript

标签: Bun|JavaScript|全栈开发|性能优化|TypeScript

推荐文章

Go配置镜像源代理
2024-11-19 09:10:35 +0800 CST
vue打包后如何进行调试错误
2024-11-17 18:20:37 +0800 CST
程序员出海搞钱工具库
2024-11-18 22:16:19 +0800 CST
内网穿透技术详解与工具对比
2025-04-01 22:12:02 +0800 CST
Python Invoke:强大的自动化任务库
2024-11-18 14:05:40 +0800 CST
程序员茄子在线接单