7.1 命令行用法
$ bun build src/index.ts --outdir dist
$ bun build src/index.ts --outfile dist/bundle.js
$ bun build src/index.ts \
--target=browser \
--minify \
--sourcemap=linked \
--splitting \
--outdir dist
7.2 三种 target
- browser(默认)
- 产物面向浏览器——bundle 所有依赖(含 node_modules),不含 Node.js 专属 API。
- bun
- 面向 Bun 运行时——保留 Bun 专属 API(Bun.file 等),externals 不 bundle 本地依赖。
- node
- 面向 Node.js——产物兼容 Node,external 所有
node:*内置模块。
$ bun build src/cli.ts --target=node --outfile dist/cli.cjs
$ bun build src/app.ts --target=bun --outfile dist/app.js
$ bun build src/main.ts --target=browser --outfile dist/main.js
7.3 JS API
import { $ } from "bun";
const r = await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser",
format: "esm", // esm | cjs(仅 node target)| iife
splitting: true,
minify: true,
sourcemap: "linked",
external: ["react", "react-dom"],
define: { "process.env.NODE_ENV": '"production"' },
});
if (!r.success) for (const e of r.logs) console.error(e);
7.4 code splitting
加 --splitting 或 splitting: true 启用——每个动态 import() 会切成独立 chunk:
// src/main.ts
document.getElementById("btn").addEventListener("click", async () => {
const { bigFeature } = await import("./bigFeature");
bigFeature();
});
产物:
dist/
├── main.js # 主 chunk(首屏需要)
└── bigFeature-xxx.js # 按需加载
7.5 插件(bun build plugin)
API 和 esbuild 插件类似:
import type { BunPlugin } from "bun";
const yamlPlugin: BunPlugin = {
name: "yaml",
setup(build) {
build.onLoad({ filter: /\.ya?ml$/ }, async (args) => {
const text = await Bun.file(args.path).text();
const yaml = await import("yaml");
return {
contents: `export default ${JSON.stringify(yaml.parse(text))}`,
loader: "js",
};
});
},
};
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "dist",
plugins: [yamlPlugin],
});
运行时注册插件
插件也可注册到运行时 loader——让 import config from "./config.yaml" 直接工作:
// preload.ts
import { plugin } from "bun";
plugin(yamlPlugin);
# bunfig.toml
preload = ["./preload.ts"]
7.6 naming:自定义输出文件名
Bun.build({
entrypoints: ["src/a.ts", "src/b.ts"],
outdir: "dist",
naming: {
entry: "[dir]/[name].[ext]",
chunk: "chunks/[name]-[hash].[ext]",
asset: "assets/[name]-[hash].[ext]",
},
});
7.7 loader 类型
Bun 对常见资源内置 loader:
| 扩展名 | loader | 产物 |
|---|---|---|
| .ts/.tsx/.js/.jsx | 默认 | 编译后 JS |
| .json | json | JSON 对象 |
| .txt/.html | text | 字符串 |
| .toml | toml | 对象 |
| .png/.jpg/.webp/.svg | file | URL + 哈希文件 |
| .wasm | wasm | WebAssembly.Module |
7.8 bun build vs Vite / esbuild / tsup
| bun build | esbuild | Vite | tsup | |
|---|---|---|---|---|
| dev server | ❌ | ❌ | ✅ | ❌ |
| HMR | ❌ | ❌ | ✅ | ❌ |
| 打包速度 | 极快 | 极快 | 快(Rollup) | 中 |
| 库打包 | ✅ | ✅ | ✅ | ✅ |
| --compile 单文件 | ✅ | ❌ | ❌ | ❌ |
适用场景:
- 前端应用:仍推荐 Vite(HMR/dev server 生态更成熟)
- 后端库、CLI、Lambda 函数:
bun build够用 - 分发单文件可执行:
bun build --compile(第 9 章详讲)
7.9 常见配方
打包一个 npm 库(ESM + CJS + .d.ts)
# ESM
bun build src/index.ts --outdir dist --target=node --format=esm --external '*'
# CJS
bun build src/index.ts --outdir dist --target=node --format=cjs --external '*'
# 类型声明(tsc 生成)
tsc --emitDeclarationOnly --outDir dist
打包 CLI(shebang)
bun build src/cli.ts --target=node --outfile dist/cli.js --banner='#!/usr/bin/env node'
7.10 小结
bun build是内置打包器——命令行或 JS API 都能用。- 三种 target:browser(浏览器)/ bun(Bun 服务端)/ node(Node 兼容)。
- 支持 code splitting、minify、sourcemap、external、define、插件系统。
- 前端应用仍首选 Vite;后端库/CLI/单文件分发首选 bun build。