第三章 有什么用

第三章 有什么用

3.1 设计目标(官方五大设计原则)

Bun 团队在设计 Bun 时有五大核心原则,这些原则指导着 Bun 的每一次迭代。

💡 想象一下,如果厨房里只能有一把刀,这把刀要能切菜、切肉、削水果、开罐头——Bun 就是 JavaScript 世界的这把"瑞士军刀"。

速度压倒一切

Bun 的首要目标就是。JavaScript 工具链的每一个环节——安装包、运行脚本、打包代码、跑测试——都要比现有工具快一个数量级。

JavaScriptCore 引擎 + Zig 语言优化的组合拳,让 Bun 在多个维度都显著快于 Node.js:进程启动快 4 倍HTTP 吞吐量高 2-3 倍包安装快 30 倍。这三个数字来自 Bun 官方 benchmark,不是我们拍脑袋编的。

TypeScript & JSX 无需配置

在 Bun 之前,你运行 TypeScript 需要:装 ts-node 或 tsx、配置 tsconfig.json、可能还要装一堆类型声明包。好不容易配好了,ESLint 又报一堆奇奇怪怪的错。

Bun 不需要。你写一个 .ts 文件,直接 bun run 就跑起来了。JSX 也是,写 .tsx,直接运行,不需要 webpack 配 loader,不需要 babel 配插件,不需要对着报错信息怀疑人生。

1
2
3
4
5
6
7
8
// index.tsx - 直接运行,不需要任何配置!
import React from "react";

const App = () => {
  return <h1>Hello, Bun!</h1>;
};

console.log(App);

ESM & CommonJS 兼容

JavaScript 有两套模块系统:老的 CommonJS(require())和新潮的 ES Modules(import/export)。在 Node.js 里这两者经常打架,各种奇怪问题让你头疼——比如明明有这个包,require 就是找不到;或者 import 了半天,报一个不知所云的循环引用错误。

Bun 两者都原生支持,而且支持得很好。你可以混着用,Bun 会自动处理模块系统的转换。这对迁移项目特别友好——你不需要一次性把所有 require 改成 import,慢慢来就行。

Web 标准 API 原生实现

Bun 基于 JavaScriptCore 实现了大量 Web 标准 API,比如 fetchResponseRequestHeadersWebSocket 等。

这意味着你在浏览器里怎么写 HTTP 请求,在 Bun 里几乎一样的代码:

1
2
3
4
5
// 浏览器里
const res = await fetch("https://api.example.com/data");

// Bun 里——完全一样的代码!
const res = await fetch("https://api.example.com/data");

写一次,到处跑(当然,跨平台还是要测一下的)。

Node.js 兼容性

Bun 的终极目标是 100% 兼容 Node.js。这意味着你把 node 换成 bun,你的项目大概率能直接跑起来。

当然,“100%“是目标,目前还在路上。但对于大部分项目来说,兼容性已经非常好了——你不需要把所有依赖都检查一遍才知道能不能迁移。


3.2 Built-in Core Features(内置核心能力)

Bun 官网有一个对比表,列出了 Bun 内置的、而 Node.js 需要额外安装包才能有的功能。

数据库驱动

Bun 内置了以下数据库驱动,不需要 npm install:

  • SQLite:通过 bun:sqlite,高性能,比 better-sqlite3 快 3-6 倍
  • PostgreSQL / MySQL:通过统一的 sql 标签模板 API(v1.3+),从 bun 导入

⚠️ 注意:MariaDB 暂时还不是 Bun 内置的,建议使用传统 mysql2 包。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// SQLite - 直接导入,无需安装
import { Database } from "bun:sqlite";
const db = new Database("my.db");

// PostgreSQL / MySQL - 统一使用 sql 模板 API(v1.3+)
import { sql, SQL } from "bun";

// PostgreSQL(默认)
const pgUsers = await sql`SELECT * FROM users WHERE id = ${1}`;

// MySQL(显式指定连接字符串)
const mysql = new SQL("mysql://user:pass@localhost:3306/mydb");
const mysqlUsers = await mysql`SELECT * FROM users LIMIT 10`;

对象存储

Bun 内置了 S3 客户端(v1.2+),上传下载文件、生成预签名 URL、配置存储类(GLACIER_IR 等)全部搞定:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { s3, write } from "bun";

// 创建一个指向 S3 文件的"懒引用"(此时不发起网络请求)
const fileRef = s3.file("my-bucket/hello.txt");

// 上传文件
await write(fileRef, "Hello World");

// 下载文件(以文本形式)
const content = await fileRef.text();

// 生成预签名 URL,有效期 1 天
const url = fileRef.presign({ expiresIn: 60 * 60 * 24 });

WebSocket 服务器

Bun 内置了 WebSocket 服务器,基于 uWebSockets 实现,性能比 Node.js + ws快 7 倍

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Bun.serve({
  fetch(req, server) {
    server.upgrade(req); // 升级为 WebSocket
    return;
  },
  websocket: {
    open(ws) { console.log("连接来了!"); },
    message(ws, msg) { ws.send(msg); },
  },
});

单文件可执行文件

Bun 可以把应用打包成单个二进制可执行文件,直接拷贝到服务器上运行,不需要 Node.js,不需要任何运行时——Bun 本身就是运行时。

1
2
bun build --target=bun --outfile myapp myapp.ts
./myapp  # 直接运行!

加密密钥存储

Bun 内置了加密密钥安全存储(Encrypted Secrets Storage),再也不用把密钥硬编码在代码里了。


3.3 运行时:替代 Node.js

Bun 的运行时是它最核心的部分。

直接运行 TS/JS 文件

不需要编译,不需要配置,直接跑:

1
2
3
bun run index.ts
bun run index.tsx
bun index.js  # 裸命令,等价于 bun run

内置 Transpiler

Bun 自带了一个超快的转译器(Transpiler),在你运行代码之前,自动把 TypeScript 转成 JavaScript、把 JSX 转成 React.createElement。

你感知不到这个过程——它发生在后台,瞬间完成。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// index.ts - TypeScript + JSX,Bun 直接运行
import React from "react";

interface Props {
  name: string;
}

const greet = (name: string): string => {
  return `Hello, ${name}!`;
};

const element = <h1>{greet("Bun")}</h1>;
console.log(element);

内置 .env 加载

Bun 自动加载 .env 文件,不需要额外安装 dotenv

1
2
3
4
5
6
# .env 文件
DB_PASSWORD=secret123
API_KEY=hello-world

# 代码中直接用(无需任何 import!)
console.log(process.env.DB_PASSWORD); // secret123

内置 HTTP 服务器(Bun.serve)

Bun 内置了高性能 HTTP 服务器,直接使用 Bun.serve() 创建,无需任何第三方依赖:

1
2
3
4
5
6
7
8
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello from Bun!");
  },
});
// 运行:bun run server.ts
// 访问:http://localhost:3000

内置 WebSocket 服务器

Bun.servewebsocket 配置项让你快速搭建 WebSocket 服务,支持 openmessageclose 等生命周期钩子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Bun.serve({
  fetch(req, server) {
    // 如果是 WebSocket 请求,升级它
    if (server.upgrade(req)) return;
    return new Response("这不是 WebSocket");
  },
  websocket: {
    open(ws) { console.log("新连接:", ws.remoteAddress); },
    message(ws, msg) { ws.send(`你发了: ${msg}`); },
    close(ws) { console.log("连接断开"); },
  },
});

内置 Shell

Bun 的 $ 语法让你在 JavaScript 里写 Shell 脚本:

1
2
3
4
import { $ } from "bun";

const result = await $`ls -la`.text();
console.log(result);

内置 FFI

FFI(Foreign Function Interface)让你在 JavaScript 里直接调用 C 类库:

1
2
3
4
5
6
7
8
import { dlopen } from "bun:ffi";

// 加载一个 C 库(Linux 示例,macOS 上是 libSystem.dylib,Windows 上是 libm.lib)
const lib = dlopen("libm.so.6", {
  abs: { returns: "int", args: ["int"] },
});

console.log(lib.symbols.abs(-42)); // 42

内置文件监听与热重载

--watch 模式让 Bun 自动监听文件变化,重启服务:

1
2
bun --watch run server.ts
# 修改 server.ts 后,Bun 自动重启

常用文件操作 API

Bun 的文件 API 比 Node.js 的 fs 模块更快:

1
2
3
4
5
6
7
8
9
// 读取文件
const content = Bun.file("data.txt").text();
const json = Bun.file("data.json").json();

// 写入文件
await Bun.write("output.txt", "Hello Bun!");

// 高性能文件复制
await Bun.write("dest.txt", Bun.file("source.txt"));

3.4 打包器:替代 webpack / Vite / esbuild

Bun 的内置打包器适合轻量到中型打包场景。

Bun.build() JavaScript API

1
2
3
4
5
6
7
8
import { build } from "bun";

await build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./dist",
  target: "browser",
  minify: true,
});

CLI 方式

1
bun build ./src/index.tsx --outdir=dist --target=browser

代码分割(Code Splitting)

1
bun build ./src/index.tsx --outdir=dist --splitting

Tree Shaking

Bun 自动删除没有用到的代码,减少包体积:

1
bun build ./src/index.tsx --outdir=dist --minify

多平台目标

1
2
3
4
5
6
7
8
# 浏览器
bun build ./src/app.ts --target=browser --outdir=dist

# Node.js
bun build ./src/app.ts --target=node --outdir=dist

# Bun 运行时
bun build ./src/app.ts --target=bun --outdir=dist

HTML 入口打包

Bun 可以直接打包包含 HTML 的项目:

1
bun build ./public/index.html --outdir=dist

Bun 会自动处理 HTML 里引用的 JS/CSS/图片资源。

单文件可执行文件

1
2
bun build --target=bun --outfile myapp ./myapp.ts
./myapp  # 直接运行,不需要 Bun 运行时!

3.5 测试框架:替代 Jest / Vitest

Bun 的测试框架 bun test 完全兼容 Jest API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { test, expect, describe } from "bun:test";

describe("数学运算", () => {
  test("加法", () => {
    expect(1 + 1).toBe(2);
  });

  test("乘法", () => {
    expect(3 * 4).toBe(12);
  });
});

运行测试:

1
bun test

并发测试

1
2
3
test("并发测试", async () => {
  // 多个测试并行执行
}, { concurrent: true });

Mock 函数

1
2
3
4
5
6
7
import { mock } from "bun:test";

test("Mock 函数", () => {
  const fn = mock(() => 42);
  expect(fn()).toBe(42);
  expect(fn).toHaveBeenCalled();
});

覆盖率报告

1
bun test --coverage

3.6 内置 API 与工具

bun init - 快速初始化项目

1
2
3
bun init              # 空白项目
bun init --react      # React 项目
bun init --library    # 类库项目

bun fmt - 代码格式化

1
2
bun fmt              # 格式化当前目录
bun fmt ./src         # 格式化指定目录

bun lint - 代码检查

1
bun lint

3.7 内置工具(Builtin Utilities)

密码与哈希 API

1
2
3
4
5
6
7
import { hash, verify } from "bun:password";

const hash1 = await hash("my-secret-password");
// $argon2id$v=19...

const isValid = await verify(hash1, "my-secret-password");
console.log(isValid); // true

String Width API

1
2
3
4
5
import { stringWidth } from "bun";

console.log(stringWidth("Hello"));    // 5
console.log(stringWidth("你好"));      // 4(中文字符宽度为2)
console.log(stringWidth("🍌"));         // 2(emoji宽度为2)

CSS 颜色转换 API

1
2
3
4
import { cssColor } from "bun";

const colorObj = cssColor("#ff0000");
console.log(colorObj); // { r: 255, g: 0, b: 0, a: 1 }

3.8 脚本工具

跨平台 Shell 脚本

1
2
3
4
import { $ } from "bun";

await $`mkdir -p dist && cp src/* dist/`;
await $`git status`;

3.9 运行时与打包器的内置 Loader

Bun 自动识别文件扩展名来决定用什么"加载器"处理文件。

扩展名Loader说明
.ts / .mts / .ctstsTypeScript(转译 + 类型剥离)
.tsxtsxTypeScript + JSX
.js / .mjsesmJavaScript(作为 ES Module)
.jsxjsxJavaScript + JSX
.cjscjsJavaScript(作为 CommonJS)
.jsonjsonJSON,导入时作为对象
.jsoncjsoncJSON with Comments
.tomltomlTOML
.yaml / .ymlyamlYAML
.csscssCSS
.htmlhtmlHTML 及资产打包
.wasmwasmWebAssembly
.shshBun Shell 脚本

自定义 Loader

1
bun run --loader .myext:myLoader ./file.myext

本章小结

本章系统介绍了 Bun 的用途和核心内置能力。

设计目标上:Bun 追求速度、TypeScript 开箱即用、ESM/CommonJS 兼容、Web 标准 API 原生实现、Node.js 高度兼容。

内置核心能力上:Bun 内置了 SQLite(bun:sqlite)、PostgreSQL/MySQL(sql 统一 API,v1.3+)、S3(s3.file + write)、Redis(redis 全局单例,v1.3+)、WebSocket、单文件打包等重量级功能,全部不需要 npm install。MariaDB 暂时还没内置,老老实实用 mysql2 包吧。

运行时方面:Bun 可以直接运行 TS/JS 文件,内置 Transpiler、.env 加载、HTTP 服务器、WebSocket、Shell、FFI、文件操作等丰富能力。

打包器方面:bun build 适合轻量打包场景,支持代码分割、Tree Shaking、多平台目标、HTML 入口打包、单文件可执行文件。

测试框架bun test 兼容 Jest API,支持并发测试、Mock、覆盖率报告。

🎯 总结一句话:装一个 Bun,省一堆包。

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