Bun 打包工具完全指南:比 esbuild 快 2 倍的新一代打包神器
摘要:Bun 不仅是快速的 JavaScript 运行时,其内置打包器更是性能怪兽。本文从零开始讲解 Bun Bundler 的使用,包含 CLI 命令、API 调用、实战配置和性能对比,助你快速上手这个新一代打包神器。
一、为什么选择 Bun Bundler?
在 JavaScript 打包工具的世界里,我们经历过 Webpack 的配置复杂、Rollup 的学习曲线、Vite 的开发体验革新,以及 esbuild 的性能突破。而 Bun Bundler 的出现,再次刷新了性能天花板。
1.1 性能对比
根据官方基准测试(esbuild 的 three.js benchmark),Bun 在打包性能上表现惊人:
打包 10 份 three.js(含 sourcemap + 压缩):
- Bun: ~30ms
- esbuild: ~60ms
- Vite: ~200ms+
- Webpack: ~500ms+
Bun 的速度约为 esbuild 的 2 倍,Webpack 的 10 倍以上!
1.2 核心优势
| 特性 | Bun | esbuild | Vite | Webpack |
|---|---|---|---|---|
| 打包速度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| 配置复杂度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
| TypeScript 支持 | 原生 | 原生 | 原生 | 需配置 |
| JSX 支持 | 原生 | 原生 | 原生 | 需配置 |
| 热更新 | 支持 | 不支持 | 支持 | 支持 |
| 单文件打包 | 支持 | 支持 | 需配置 | 需配置 |
1.3 适用场景
- ✅ 快速原型开发:零配置,开箱即用
- ✅ Serverless 函数打包:生成单文件可执行文件
- ✅ TypeScript/JSX 项目:原生支持,无需转译
- ✅ 全栈应用:同时处理前端和后端代码
- ⚠️ 复杂代码分割:目前功能相对简单
- ⚠️ 旧项目迁移:可能需要适配
二、快速开始:5 分钟上手
2.1 安装 Bun
如果你还没有安装 Bun,一行命令搞定:
# macOS/Linux
curl -fsSL https://bun.sh/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1 | iex"
# npm 安装(不推荐,会失去性能优势)
npm install -g bun
验证安装:
bun --version
# 输出:1.3.11(或更高版本)
2.2 第一个打包示例
创建一个简单的项目:
# 创建项目目录
mkdir bun-demo && cd bun-demo
# 初始化项目
bun init -y
# 安装 React(示例用)
bun add react react-dom
创建入口文件 index.tsx:
import * as ReactDOM from "react-dom/client";
import { App } from "./App";
const root = ReactDOM.createRoot(document.getElementById("root")!);
root.render(<App message="Hello Bun!" />);
创建组件文件 App.tsx:
export function App(props: { message: string }) {
return <h1>{props.message}</h1>;
}
执行打包:
bun build ./index.tsx --outdir ./dist
完成!查看 ./dist 目录,你会看到打包好的文件。
三、CLI 命令详解
3.1 基础命令
# 基本用法
bun build <入口文件> --outdir <输出目录>
# 示例
bun build ./src/index.ts --outdir ./dist
3.2 常用参数
| 参数 | 说明 | 示例 |
|---|---|---|
--outdir | 输出目录 | --outdir ./dist |
--outfile | 输出文件名 | --outfile ./dist/bundle.js |
--target | 目标环境 | --target browser|bun|node |
--format | 输出格式 | --format esm|cjs|iife |
--minify | 压缩代码 | --minify |
--sourcemap | 生成 sourcemap | --sourcemap |
--watch | 监听模式 | --watch |
--define | 定义常量 | --define process.env.NODE_ENV="production" |
--external | 排除依赖 | --external react |
--splitting | 代码分割 | --splitting |
3.3 实战示例
3.3.1 打包浏览器应用
bun build ./src/index.tsx \
--outdir ./dist \
--target browser \
--format iife \
--minify \
--sourcemap
3.3.2 打包 Node.js 服务
bun build ./src/server.ts \
--outdir ./dist \
--target node \
--format esm \
--minify
3.3.3 打包为单文件可执行文件
# 生成可执行文件
bun build ./src/cli.ts \
--target bun \
--outfile ./my-app \
--minify
# 添加执行权限
chmod +x ./my-app
# 运行
./my-app
3.3.4 开发模式(监听)
# 监听文件变化,自动重建
bun build ./src/index.tsx \
--outdir ./dist \
--watch
3.3.5 排除外部依赖
# 排除 react 和 react-dom,使用 CDN 加载
bun build ./src/index.tsx \
--outdir ./dist \
--external react \
--external react-dom
四、JavaScript API 使用
除了 CLI,Bun 还提供了强大的 JavaScript API,适合集成到构建流程中。
4.1 基础用法
创建 build.js:
const result = await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
});
console.log('打包成功!', result);
运行:
bun run build.js
4.2 完整配置示例
// build.config.js
export default {
entrypoints: ['./src/index.tsx', './src/admin.tsx'],
outdir: './dist',
// 目标环境
target: 'browser',
// 输出格式
format: 'esm',
// 压缩
minify: true,
// Sourcemap
sourcemap: 'external', // 'external' | 'inline' | 'none'
// 代码分割
splitting: true,
// 排除的依赖
external: ['react', 'react-dom'],
// 定义常量
define: {
'process.env.NODE_ENV': JSON.stringify('production'),
'__VERSION__': JSON.stringify('1.0.0'),
},
// 根目录
root: '.',
// 入口文件命名
entryNaming: '[dir]/[name].[hash]',
// 资源文件处理
publicPath: '/assets/',
};
// build.js
import config from './build.config.js';
const result = await Bun.build(config);
if (!result.success) {
console.error('打包失败:');
for (const message of result.logs) {
console.error(message);
}
process.exit(1);
}
console.log('✅ 打包成功!');
console.log(`输出文件:${result.outputs.length} 个`);
4.3 监听模式 API
// watch.js
import config from './build.config.js';
async function build() {
const result = await Bun.build({
...config,
watch: true,
});
if (!result.success) {
console.error('❌ 打包失败');
return;
}
console.log('✅ 打包成功 - 监听中...');
}
build();
五、实战配置
5.1 React 项目配置
// build-react.js
await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
target: 'browser',
format: 'iife',
minify: true,
sourcemap: 'external',
// 定义 React 生产环境
define: {
'process.env.NODE_ENV': '"production"',
},
});
配合 index.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bun + React 应用</title>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="./dist/index.js"></script>
</body>
</html>
5.2 Vue 项目配置
// build-vue.js
await Bun.build({
entrypoints: ['./src/main.ts'],
outdir: './dist',
target: 'browser',
format: 'esm',
minify: true,
// Vue 3 生产环境
define: {
'__VUE_OPTIONS_API__': 'true',
'__VUE_PROD_DEVTOOLS__': 'false',
'__VUE_PROD_HYDRATION_MISMATCH_DETAILS__': 'false',
},
});
5.3 Node.js 服务端配置
// build-server.js
await Bun.build({
entrypoints: ['./src/server.ts'],
outdir: './dist',
target: 'node',
format: 'esm',
minify: true,
sourcemap: 'inline',
// 排除 node_modules(使用 Bun 运行时)
external: ['*'],
});
5.4 库打包配置
// build-lib.js
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
target: 'browser',
// 同时生成 ESM 和 CJS 格式
format: 'esm',
minify: false,
sourcemap: 'external',
// 库名称
naming: {
entry: '[name].js',
chunk: '[name].[hash].js',
},
});
六、高级技巧
6.1 多入口打包
await Bun.build({
entrypoints: [
'./src/index.tsx', // 主入口
'./src/admin.tsx', // 管理后台
'./src/vendor.ts', // 第三方库
],
outdir: './dist',
splitting: true, // 启用代码分割
});
6.2 条件编译
await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
// 根据条件编译不同代码
define: {
'__DEV__': 'false',
'__TEST__': 'false',
'__VERSION__': '"1.0.0"',
},
});
在代码中使用:
if (__DEV__) {
console.log('开发模式');
}
console.log(`版本:${__VERSION__}`);
6.3 资源文件处理
await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
// 资源文件处理
publicPath: '/assets/',
// 文件命名规则
entryNaming: '[name].[hash]',
assetNaming: 'assets/[name].[hash][ext]',
});
6.4 插件扩展(实验性)
const myPlugin = {
name: 'my-plugin',
setup(build) {
// 拦截特定文件
build.onLoad({ filter: /\.custom$/ }, async (args) => {
const content = await Bun.file(args.path).text();
return {
contents: `export default ${JSON.stringify(content)}`,
loader: 'js',
};
});
},
};
await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
plugins: [myPlugin],
});
七、性能优化建议
7.1 生产环境配置
bun build ./src/index.tsx \
--outdir ./dist \
--target browser \
--format iife \
--minify \
--sourcemap external \
--define process.env.NODE_ENV="production"
7.2 减少打包体积
await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
// 排除大型依赖,使用 CDN
external: [
'react',
'react-dom',
'lodash-es',
],
// 启用代码分割
splitting: true,
// 压缩
minify: true,
});
7.3 增量构建
# 使用 watch 模式
bun build ./src/index.tsx --outdir ./dist --watch
# 或使用 API
const result = await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
watch: true,
});
八、常见问题
Q1: Bun Bundler 和 Webpack/Vite 有什么区别?
答:Bun Bundler 更注重性能和简洁,零配置即可使用。Webpack 功能最强大但配置复杂,Vite 开发体验好但生产构建仍依赖 Rollup。
Q2: 可以完全替代 Webpack 吗?
答:对于大多数项目可以,但如果你的项目依赖复杂的 Webpack 插件或特殊的 loader,可能需要等待 Bun 的进一步支持。
Q3: TypeScript 类型检查怎么办?
答:Bun Bundler 只负责打包,不进行类型检查。建议配合 tsc --noEmit 或 bun run --bun tsc --noEmit 进行类型检查。
Q4: 如何处理 CSS 文件?
答:Bun 支持导入 CSS 文件,会自动打包到输出中:
import './styles.css';
Q5: 支持代码分割吗?
答:支持,使用 --splitting 参数或 splitting: true 配置。
九、总结
Bun Bundler 作为新一代打包工具,凭借极致的性能和零配置的易用性,正在成为越来越多开发者的首选。
核心优势回顾:
- 🚀 速度极快:比 esbuild 快 2 倍,比 Webpack 快 10 倍
- 📦 开箱即用:零配置,支持 TypeScript/JSX 原生
- 🔧 灵活配置:CLI 和 API 双支持
- 🌐 全栈支持:浏览器、Node.js、Bun 运行时全覆盖
推荐使用场景:
- ✅ 新项目快速启动
- ✅ Serverless 函数打包
- ✅ 简单的库打包
- ✅ 全栈应用构建
暂不推荐场景:
- ⚠️ 依赖复杂 Webpack 生态的老项目
- ⚠️ 需要精细代码分割的大型应用
参考资源
关于作者:前端程序员,专注 Electron、Vue、AI Coding 领域。欢迎关注我,获取更多前端技术干货!
互动:你用过 Bun 吗?体验如何?欢迎在评论区交流~