Bun: 运行JavaScript 和TypeScript 应用程序的集成工具包
Bun 发布于 2022 年(1.0 版本于 2023 年发布),由 Jarred Sumner 开发。它的目标是替代 Node.js,并解决 Node.js 长期以来的性能瓶颈和工具链碎片化问题。
介绍
bun 核心特点
- 极速(Performance): 启动速度和运行速度通常比 Node.js 快几倍。
- 核心技术:
- 使用 Zig 语言编写(更底层的内存控制)。
- 使用 Apple Safari 的 JavaScriptCore 引擎(启动速度比 V8 更快)。
- All-in-One(多合一): Bun 不仅仅是运行时,它内置了打包器(Bundler)、测试工具(Test Runner)、包管理器(Package Manager)。
- 原生支持 TypeScript: 不需要配置
tsconfig.json或安装ts-node,直接运行.ts文件。
Bun 的优势
- 包安装速度极其恐怖:
bun install通常比npm install快 20-100 倍。它利用了全局缓存和极快的系统调用。 - 开发体验(DX)拉满:
在 Node.js 中,开始一个现代项目通常需要配置:
package.json+prettier+eslint+jest+typescript+nodemon。 在 Bun 中,很多工具是内置的。比如你可以直接bun test跑测试,bun run index.ts跑项目,还内置了热重载(--hot)。 - 内置 API 更现代化:
Bun 内置了高性能的
Bun.serve(HTTP 服务器)、Bun.file(文件操作)和bun:sqlite(原生 SQLite 支持),性能远超 Node 原生模块。
为什么要慎用 Bun?
- 兼容性陷阱: 虽然 Bun 宣称兼容 Node.js,但在某些特定的、底层的 API 或极个别的 npm 包上,Bun 可能会报错或行为不一致。
- Windows 支持: Bun 最初主要针对 Linux/macOS 优化,Windows 版本虽已发布但相对较新,稳定性不如 Node.js。
- 生态惯性: 很多企业级框架(如 NestJS)虽然能跑在 Bun 上,但官方文档和最佳实践依然是基于 Node.js 的。
- V8 的优化: 对于长时间运行的计算密集型任务,V8 的 JIT(即时编译)优化有时会比 JavaScriptCore 更好。
Node.js vs Bun:核心对比
| 特性 | Node.js | Bun |
|---|---|---|
| JS 引擎 | V8 (Chrome) | JavaScriptCore (Safari) |
| 开发语言 | C++ | Zig |
| 包管理器 | npm / yarn / pnpm (需单独安装) | bun install (内置,速度极快) |
| TypeScript | 需要编译或加载器 (tsx/ts-node) | 开箱即用 (零配置) |
| 打包工具 | Webpack / Rollup / Vite (需外部) | bun build (内置) |
| 测试工具 | Jest / Mocha / Vitest (需外部) | bun test (内置,兼容 Jest) |
| 兼容性 | 标准制定者 | 旨在完全兼容 Node.js API (已完成 90%+) |
| 启动速度 | 较慢 | 极快 (适合 Serverless/CLI) |
Bun 快速上手
安装 Bun
Mac, Linux, WSL (Windows Subsystem for Linux):
curl -fsSL https://bun.sh/install | bashWindows (原生 PowerShell):
powershell -c "irm bun.sh/install.ps1 | iex"初始化项目 (bun init)
Bun 提供了一个非常方便的脚手架工具。
mkdir my-bun-app
cd my-bun-app
bun initbun init 会自动做以下事情:
- 生成
package.json。 - 生成
bun.lockb(二进制锁文件)。 - 生成
index.ts(默认支持 TypeScript)。 - 生成
tsconfig.json(配置好了最佳实践)。
Bun 如何管理依赖 (bun install)
Bun 的包管理器是其最大的杀手锏,速度极快。它兼容 package.json,所以你可以无缝迁移 Node.js 项目。
核心命令
| 操作 | 命令 | 说明 |
|---|---|---|
| 安装所有依赖 | bun install (或 bun i) |
根据 package.json 安装依赖 |
| 添加生产依赖 | bun add <包名> |
等同于 npm install <包名> |
| 添加开发依赖 | bun add -d <包名> |
等同于 npm install -D <包名> |
| 移除依赖 | bun remove <包名> |
移除包并更新 package.json |
| 全局安装 | bun add -g <包名> |
安装到系统全局 |
| 更新依赖 | bun update <包名> |
更新到最新版本 |
为什么 Bun 安装依赖这么快?
- 全局缓存(Global Cache): Bun 下载的包会缓存在全局目录中。如果你在项目 A 用过 React,在项目 B 再安装 React 时,它直接从磁盘读取,无需再次下载。
- 硬链接(Hard Links): Bun 使用操作系统的硬链接将包从缓存
复制到你的node_modules,这比单纯的文件复制快得多,而且节省磁盘空间。 - 二进制锁文件 (
bun.lockb):- Bun 默认生成二进制格式的
bun.lockb,而不是文本格式的yarn.lock或package-lock.json。 - 优点: 解析速度极快,安装依赖时读取效率更高。
- 缺点: 无法直接用文本编辑器查看 diff(差异)。
- 解决: 如果你想看 diff,可以运行
bun install --yarn生成 yarn.lock,或者使用命令bun bun.lockb > bun.lock.txt将其转为文本查看。
- Bun 默认生成二进制格式的
运行脚本 (bun run)
Bun 可以替代 npm run。
bun run start
bun run dev
bun run build优势: 启动耗时几乎为零(省去了 npm 启动时的几百毫秒开销)。
Bun 常用功能示例
Bun 提供了很多内置 API(以 Bun. 开头),性能远超 Node.js 原生模块。
启动 HTTP 服务器 (无需 Express/Koa)
Bun 内置了基于 Web 标准(Request/Response)的高性能服务器。
代码 (http.ts):
const server = Bun.serve({
port: 3000,
// 处理请求
fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/') {
return new Response('Hello from Bun!');
}
if (url.pathname === '/json') {
return Response.json({ message: 'Bun is fast', speed: '100x' });
}
return new Response('404 Not Found', { status: 404 });
}
});
console.log(`Listening on localhost:${server.port}`);运行:
bun http.ts
# 或者开启热更新(修改文件自动重启)
bun --hot http.ts文件读写 (Bun.file)
比 Node.js 的 fs 模块快且 API 更简单。
代码 (file.ts):
// 写入文件
await Bun.write('output.txt', '这是由 Bun 写入的内容');
// 读取文件
const file = Bun.file('output.txt');
// 像操作 Promise 一样操作文件
const text = await file.text();
console.log(text); // 输出: "这是由 Bun 写入的内容"
// 直接检查文件是否存在
const exists = await file.exists();
console.log(`文件存在吗? ${exists}`);运行 TypeScript (零配置)
你不需要安装 ts-node,也不需要配置 tsc。
直接写 index.ts:
// index.ts
interface User {
name: string;
age: number;
}
const user: User = {
name: 'Bun User',
age: 1
};
console.log(user);运行:
bun index.ts内置测试运行器 (Bun Test)
Bun 内置了类似 Jest 的测试框架,速度极快。
代码 (math.test.ts):
import { expect, test, describe } from 'bun:test';
describe('数学运算', () => {
test('1 + 1 应该等于 2', () => {
expect(1 + 1).toBe(2);
});
});运行:
bun test读取环境变量 (.env)
Bun 开箱即用支持 .env 文件,无需安装 dotenv 库。
.env 文件:
API_KEY=secret_123代码:
console.log(process.env.API_KEY); // 输出: secret_123
// 或者使用 Bun 专有 API
console.log(Bun.env.API_KEY);常用命令速查表
| 场景 | Node.js / npm 命令 | Bun 命令 |
|---|---|---|
| 安装依赖 | npm install |
bun install |
| 运行 JS/TS | node app.js / ts-node app.ts |
bun app.ts |
| 运行脚本 | npm run dev |
bun run dev |
| 运行测试 | npx jest |
bun test |
| 热更新运行 | nodemon app.ts |
bun --hot app.ts |
| 打包构建 | webpack / rollup |
bun build ./index.ts --outdir ./dist |