第四章 用在哪里

第四章 用在哪里

💡 如果你问"Bun 能干啥",这章就是答案。它不是万能药,但在 JavaScript 开发的大部分高频场景里,Bun 都能让你少加班、早下班。

4.1 前端项目依赖管理

Bun 的包管理器 bun install 是 npm/yarn/pnpm 的直接替代品,而且快 30 倍

前端项目通常有大量的 npm 依赖,第一次 npm install 可能要等几分钟。用 Bun 的话,同样的项目几十秒搞定。依赖少的话?十秒以内收工,喝口水的时间都省了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 替换 npm install
bun install

# 安装特定包
bun add react react-dom

# 安装开发依赖
bun add -d typescript @types/react

# 卸载
bun remove react

React / Vue / Svelte 项目的包安装

Bun 提供了开箱即用的官方项目模板,几秒钟拉起一个完整项目:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 创建 React 项目(使用 Next.js 模板)
bun create next my-app
cd my-app
bun install

# 创建 Svelte 项目
bun create svelte my-svelte-app

# 创建空项目(自行搭建)
bun create bun my-app

前端工具库的安装与更新

1
2
3
4
5
# 更新所有依赖
bun update

# 更新特定包
bun update vite

⚡ 有意思的是,bun update 比 npm 的 npm update 快得多,但很多人不知道 Bun 还有这个命令——大概是 npm 的习惯太根深蒂固了。


4.2 TypeScript / JavaScript 项目开发

Bun 对 TypeScript 的支持是原生级别的——不需要任何配置,开箱即用。不用装 ts-node,不用配 tsx,不需要任何 loader。.ts 文件直接跑,就像 Node.js 运行 .js 一样自然。

纯 TS 后端服务开发

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// server.ts
import { Hono } from "hono";
import { cors } from "hono/cors";

const app = new Hono();

app.use("*", cors());

app.get("/", (c) => c.json({ message: "Hello from Bun!" }));

app.post("/api/users", async (c) => {
  const body = await c.req.json();
  return c.json({ ok: true, user: body });
});

export default app;
1
2
bun run server.ts
# 服务启动,访问 http://localhost:3000

全栈项目

Bun 的真正魅力在于前后端统一技术栈——写一份配置,前后端都能用:

  • 前端:React / Vue / Svelte + Bun 的打包器(自动处理 JSX/TSX、CSS、图片)
  • 后端:Bun 原生 HTTP 服务器,性能比 Node.js 高出一大截
  • 数据:内置 SQLite、PostgreSQL、Redis,不用装一堆驱动
1
2
3
4
5
6
// api.ts - 后端 API 路由
export default {
  fetch(req) {
    return Response.json({ time: new Date().toISOString() });
  },
};

4.3 轻量级 HTTP 服务与 API 开发

Bun 的 HTTP 服务器性能极高,比 Node.js 快 2-3 倍(Express 框架场景可达 3 倍)。但光快没用,关键是写起来还简单。

Bun.serve 基础用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 最简单的 HTTP 服务
Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    if (url.pathname === "/") {
      return new Response("Hello Bun!");
    }
    return new Response("Not Found", { status: 404 });
  },
});

console.log("服务启动在 http://localhost:3000");

与 Hono 框架结合

Hono 是一个轻量、快速的 Web 框架,和 Bun 是绝配——它比 Express 轻,快比 Fastify,而且天然支持所有 Bun 的好东西:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { Hono } from "hono";
import { logger } from "hono/logger";

const app = new Hono();

app.use(logger());

app.get("/", (c) => c.text("Hello Hono + Bun!"));

app.get("/api/:name", (c) => {
  const name = c.req.param("name");
  return c.json({ greeting: `Hello, ${name}!` });
});

app.post("/data", async (c) => {
  const body = await c.req.json();
  return c.json({ received: body });
});

export default app;

与 Express / Fastify 兼容

Express 和 Fastify 的中间件在 Bun 里大部分可以正常工作,不用重写就能迁移:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import express from "express";

const app = express();

app.get("/", (req, res) => {
  res.json({ message: "Hello from Express on Bun!" });
});

app.listen(3000, () => {
  console.log("Express 服务运行在 Bun 上!");
});

💡 虽然 Express 能在 Bun 上跑,但如果追求极致性能,还是推荐用 Bun 原生的 Bun.serve 或者 Hono/Fastify 等更现代的框架。毕竟用着 Bun 再套一层 Express,就像开着跑车去菜市场——有点憋屈。


4.4 前端构建与打包

Bun 的打包器是真正的多面手:处理 JSX/TSX、代码分割、CSS 加载、插件系统,统统在行。而且它比 Vite 快,比 Webpack 配置简单。

开发服务器

1
2
3
4
5
# 启动开发服务器(带 HMR)
bun --watch ./index.html

# 启动生产服务
bun ./index.html

Bun 的开发服务器有一个独特能力:支持直接导入 HTML 文件作为入口。它会自动扫描 <script><link> 标签,帮你打包所有前端资源,零配置。

1
2
3
4
5
6
7
8
// app.ts
import homepage from "./index.html";

Bun.serve({
  routes: {
    "/": homepage,
  },
});

HMR(热模块替换)

Bun 的 HMR 在开发时保留应用状态,修改代码后不需要刷新页面,页面内容直接更新——React 的 state 不会丢,表单内容不会清空,体验接近现代前端框架的 Hot Reload 水准。

1
2
3
4
5
6
7
8
9
<!-- index.html -->
<!DOCTYPE html>
<html>
<head><title>Bun HMR Demo</title></head>
<body>
  <h1 id="title">Hello</h1>
  <script type="module" src="./app.ts"></script>
</body>
</html>
1
2
3
// app.ts - 修改这行文字,浏览器里直接看到变化,无需刷新
const title = document.getElementById("title")!;
title.textContent = "Hello, HMR!";

生产环境打包

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 生产构建(压缩 + 优化)
bun build ./src/index.tsx \
  --outdir=dist \
  --target=browser \
  --minify

# 代码分割(自动拆包)
bun build ./src/index.tsx \
  --outdir=dist \
  --target=browser \
  --splitting

# 生成单文件可执行包
bun build ./src/cli.ts \
  --outfile=my-app \
  --target=bun

插件系统

Bun 支持用插件扩展打包和运行时的行为,比如加载 .scss.yaml 等非标准文件类型:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import type { BunPlugin } from "bun";

const myPlugin: BunPlugin = {
  name: "Custom loader",
  setup(build) {
    build.onLoad({ filter: /\.yaml$/ }, (args) => {
      return { loader: "text", contents: "..." };
    });
  },
};

await Bun.build({
  entrypoints: ["./app.ts"],
  outdir: "./out",
  plugins: [myPlugin],
});

4.5 自动化脚本与 CLI 工具

跨平台 Shell 脚本

Bun 的 $ 语法让你写脚本完全不需要 bash/powershell 的兼容性问题——写一次,哪都能跑:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { $ } from "bun";

async function buildProject() {
  console.log("开始构建...");

  // 并行执行多个任务
  await Promise.all([
    $`bun run build:css`,
    $`bun run build:js`,
    $`bun run build:html`,
  ]);

  console.log("构建完成!");
}

await buildProject();

数据处理脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { readFileSync, writeFileSync } from "fs";

// 读取 CSV
const csv = readFileSync("data.csv", "utf8");
const rows = csv.split("\n").slice(1); // 跳过表头

// 处理数据
const total = rows
  .filter(row => row.length > 0)
  .map(row => {
    const [name, age, city] = row.split(",");
    return { name, age: Number(age), city };
  })
  .filter(person => person.age > 30)
  .length;

writeFileSync("result.json", JSON.stringify({ count: total }));
console.log(`30岁以上人数:${total}`);

💡 $ 模板字符串里的命令会通过 Bun 内置的 Shell 执行,在 Windows 上自动使用 bun shell(兼容 bash 语法),再也不用写两份脚本了。


4.6 Serverless 函数

Cloudflare Workers

Cloudflare Workers 是 Bun 官方支持的 Serverless 平台,写好的 Bun 代码可以直接部署到全球 300+ 个边缘节点:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/api/hello") {
      return Response.json({ message: "Hello from Cloudflare Workers!" });
    }

    return new Response("Not Found", { status: 404 });
  },
} satisfies ExportedHandler;

Vercel Edge Functions

1
2
3
4
5
6
7
8
export const config = { runtime: "edge" };

export default function handler(req: Request) {
  return Response.json({
    message: "Hello from Vercel Edge!",
    timestamp: Date.now(),
  });
}

🌍 Bun 的 Serverless 支持不只是"能跑"——它对启动速度的优化让冷启动时间大幅缩短,在讲究毫秒必争的边缘计算场景里,这可不是小事。


4.7 数据库与存储操作

SQLite(bun:sqlite)

SQLite 是本地开发和小规模项目的神器,Bun 内置了 SQLite 驱动,不需要安装任何包。插入就能用,快得像 in-memory 数据库:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { Database } from "bun:sqlite";

const db = new Database("myapp.db");

// 创建表
db.run(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL
  )
`);

// 插入数据(参数化查询,防 SQL 注入)
const insert = db.query(
  "INSERT INTO users (name, email) VALUES ($name, $email)"
);
insert.run({ $name: "张三", $email: "zhangsan@example.com" });

// 查询
const users = db.query("SELECT * FROM users").all();
console.log(users);

// 事务
db.run("BEGIN TRANSACTION");
try {
  db.run("INSERT INTO users (name, email) VALUES ($n, $e)", {
    $n: "李四",
    $e: "lisi@example.com",
  });
  db.run("COMMIT");
} catch {
  db.run("ROLLBACK");
}

PostgreSQL / MySQL

Bun 内置了统一 SQL 客户端(v1.3+),支持 PostgreSQL 和 MySQL,不需要额外的 npm 包:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { sql, SQL } from "bun";

// PostgreSQL(默认,或显式指定连接字符串)
const pgResult = await sql`SELECT * FROM products LIMIT 10`;
console.log(pgResult.rows);

// MySQL(显式指定)
const mysql = new SQL("mysql://admin:secret@localhost:3306/myapp");
const mysqlResult = await mysql`SELECT * FROM products WHERE id = ${42}`;
console.log(mysqlResult.rows);

💡 v1.2 引入 PostgreSQL 客户端(Bun.sql 模板 API),MySQL 在 v1.3 才加入。v1.3 进一步统一为 sql/SQL 导入接口,并同时支持 PostgreSQL 和 MySQL。

Redis

Bun 内置了 Redis 客户端(v1.3+),不需要安装 ioredis 或其他第三方库:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { redis } from "bun";

// 字符串操作
await redis.set("token", "abc123", { EX: 3600 }); // 1小时过期
const token = await redis.get("token");
console.log(token); // abc123

// Hash 操作
await redis.hset("user:1", { name: "张三", age: "28" });
const user = await redis.hgetall("user:1");
console.log(user); // { name: "张三", age: "28" }

// 列表操作
await redis.lpush("queue", "任务1", "任务2", "任务3");
const first = await redis.lpop("queue");
console.log(first); // 任务3(最后 push 的)

💡 Bun 的 Redis 客户端使用环境变量 REDIS_URL 自动读取连接信息,部署到 Serverless 环境时完全不用改代码。

S3 对象存储

Bun 内置了 S3 客户端(v1.2+),兼容 AWS S3、Cloudflare R2、DigitalOcean Spaces、MinIO 等所有 S3 协议存储:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { S3Client, s3, write } from "bun";

// s3 是全局单例,自动读取环境变量
// 也可以显式创建客户端
const client = new S3Client({
  region: "us-east-1",
  credentials: {
    accessKeyId: "YOUR_KEY",
    secretAccessKey: "YOUR_SECRET",
  },
});

// 上传文件:先获取 S3File 引用,再用 write() 写入
const s3file = client.file("my-bucket/hello.txt");
await write(s3file, "Hello World!");

// 下载文件:S3File 继承自 Blob,可用 .text()/.json() 等方法读取
const content = await s3file.text();
console.log(content); // Hello World!

// 生成预签名 URL(30分钟有效)
const signedUrl = await s3file.presign({
  expiresIn: 1800,
});
console.log(signedUrl);

// 删除文件
await s3file.delete();

Bun.KV(轻量级键值存储)

Bun.KV 是 Bun 内置的轻量键值存储,适合简单的持久化需求,和 SQLite 是兄弟关系,但用起来更简单:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Bun } from "bun";
const kv = await Bun.KV.open("my-data");

// 存储(永久)
await kv.set("name", "Bun Fan");
const name = await kv.get("name");
console.log(name); // Bun Fan

// 带过期时间(秒)
await kv.set("token", "abc123", { expireIn: 3600 }); // 1小时

// 删除
await kv.delete("name");

// 批量操作
await kv.setMany([
  ["key1", "value1"],
  ["key2", "value2"],
]);

const all = await kv.getMany(["key1", "key2"]);
console.log(all); // ["value1", "value2"]

本章小结

本章介绍了 Bun 的主要应用场景——从安装包到写后端,从打包前端到部署 Serverless,基本覆盖了 JavaScript 开发的全流程。

场景核心能力关键命令
前端依赖管理包安装快 30 倍bun install / bun add
TS/JS 开发TypeScript 开箱即用bun run
HTTP 服务比 Node.js 快 2-3 倍Bun.serve
前端构建极速打包 + HMRbun build
自动化脚本跨平台 $ 语法$ 模板字符串
ServerlessCloudflare / Vercel 支持零配置部署
数据库SQLite/PostgreSQL/MySQL(v1.3)/Redis(v1.3)/S3/KV内置驱动,无需安装
测试Jest 兼容,TypeScript 原生bun test

总的来说,Bun 覆盖了 JavaScript 开发中绝大多数高频场景,而且每个场景都比传统工具更快、更简单。你不需要换掉所有工具,只需要在任何一个环节试试 Bun——大概率就回不去了。

最后修改 March 29, 2026: 新增 bun 教程 (8f450cb)