esbuild 基础使用 #
安装 esbuild #
使用 npm 安装 #
bash
# 全局安装
npm install -g esbuild
# 项目本地安装(推荐)
npm install esbuild --save-dev
使用 yarn 安装 #
bash
# 全局安装
yarn global add esbuild
# 项目本地安装
yarn add esbuild --dev
使用 pnpm 安装 #
bash
# 全局安装
pnpm add -g esbuild
# 项目本地安装
pnpm add esbuild -D
验证安装 #
bash
# 检查版本
esbuild --version
# 输出示例
# 0.20.0
快速开始 #
最简单的打包 #
创建一个简单的项目:
javascript
// src/index.js
import { greet } from './greet.js';
const message = greet('World');
console.log(message);
javascript
// src/greet.js
export function greet(name) {
return `Hello, ${name}!`;
}
运行打包:
bash
esbuild src/index.js --bundle --outfile=dist/bundle.js
输出结果:
javascript
// dist/bundle.js
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/greet.js
function greet(name) {
return `Hello, ${name}!`;
}
// src/index.js
var message = greet("World");
console.log(message);
项目结构 #
text
my-project/
├── src/
│ ├── index.js
│ └── greet.js
├── dist/
│ └── bundle.js
├── package.json
└── node_modules/
命令行基本操作 #
基本语法 #
bash
esbuild [入口文件] [选项]
常用选项 #
入口和输出 #
bash
# 指定入口文件
esbuild src/index.js --bundle
# 指定输出文件
esbuild src/index.js --bundle --outfile=dist/bundle.js
# 指定输出目录
esbuild src/index.js src/admin.js --bundle --outdir=dist
输出格式 #
bash
# IIFE 格式(浏览器直接使用)
esbuild src/index.js --bundle --format=iife --outfile=dist/bundle.js
# ESM 格式
esbuild src/index.js --bundle --format=esm --outfile=dist/bundle.mjs
# CommonJS 格式
esbuild src/index.js --bundle --format=cjs --outfile=dist/bundle.cjs
# UMD 格式
esbuild src/index.js --bundle --format=umd --global-name=MyLib --outfile=dist/bundle.umd.js
平台目标 #
bash
# 浏览器环境
esbuild src/index.js --bundle --platform=browser --outfile=dist/bundle.js
# Node.js 环境
esbuild src/index.js --bundle --platform=node --outfile=dist/bundle.js
# 中性平台(不使用任何平台特定功能)
esbuild src/index.js --bundle --platform=neutral --outfile=dist/bundle.js
压缩和优化 #
bash
# 压缩代码
esbuild src/index.js --bundle --minify --outfile=dist/bundle.min.js
# 压缩并生成 Source Map
esbuild src/index.js --bundle --minify --sourcemap --outfile=dist/bundle.min.js
# 移除 console
esbuild src/index.js --bundle --drop:console --outfile=dist/bundle.js
# 移除 debugger
esbuild src/index.js --bundle --drop:debugger --outfile=dist/bundle.js
目标环境 #
bash
# 指定 ES 版本
esbuild src/index.js --bundle --target=es2020 --outfile=dist/bundle.js
# 指定浏览器版本
esbuild src/index.js --bundle --target=chrome80,firefox78,safari14 --outfile=dist/bundle.js
# 指定 Node.js 版本
esbuild src/index.js --bundle --platform=node --target=node18 --outfile=dist/bundle.js
完整选项列表 #
text
┌─────────────────────────────────────────────────────────────┐
│ esbuild 命令行选项 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 入口/输出 │
│ ├── --bundle 启用打包模式 │
│ ├── --outfile=... 输出文件路径 │
│ ├── --outdir=... 输出目录路径 │
│ ├── --metafile=... 生成元数据文件 │
│ └── --sourcemap 生成 Source Map │
│ │
│ 格式/平台 │
│ ├── --format=... 输出格式 (iife/cjs/esm/umd) │
│ ├── --platform=... 目标平台 (browser/node/neutral) │
│ ├── --global-name=... UMD 全局变量名 │
│ └── --target=... 目标环境 │
│ │
│ 优化 │
│ ├── --minify 压缩代码 │
│ ├── --minify-whitespace 压缩空白 │
│ ├── --minify-identifiers 压缩标识符 │
│ ├── --minify-syntax 压缩语法 │
│ ├── --drop:console 移除 console │
│ └── --drop:debugger 移除 debugger │
│ │
│ 模块 │
│ ├── --external:... 排除模块 │
│ ├── --packages=... 包处理方式 │
│ └── --conditions=... 条件导出 │
│ │
│ 开发 │
│ ├── --watch 监听文件变化 │
│ ├── --serve=... 启动开发服务器 │
│ └── --servedir=... 服务静态文件目录 │
│ │
└─────────────────────────────────────────────────────────────┘
JavaScript API #
同步 API #
javascript
const esbuild = require('esbuild');
const result = esbuild.buildSync({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
minify: true,
sourcemap: true,
});
console.log('构建完成:', result);
异步 API #
javascript
const esbuild = require('esbuild');
async function build() {
const result = await esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
minify: true,
sourcemap: true,
});
console.log('构建完成:', result);
}
build().catch(() => process.exit(1));
内联代码转换 #
javascript
const esbuild = require('esbuild');
const result = esbuild.transformSync(
'const x = () => { return 1 + 2; };',
{
loader: 'js',
minify: true,
target: 'es2015',
}
);
console.log(result.code);
// var x=()=>{return 1+2};
异步转换 #
javascript
const esbuild = require('esbuild');
async function transform() {
const result = await esbuild.transform(
'const x = () => { return 1 + 2; };',
{
loader: 'js',
minify: true,
target: 'es2015',
}
);
console.log(result.code);
}
transform();
TypeScript 支持 #
esbuild 原生支持 TypeScript,无需额外配置:
typescript
// src/index.ts
interface User {
name: string;
age: number;
}
function greet(user: User): string {
return `Hello, ${user.name}! You are ${user.age} years old.`;
}
const user: User = { name: 'Alice', age: 30 };
console.log(greet(user));
打包 TypeScript:
bash
esbuild src/index.ts --bundle --outfile=dist/bundle.js
TypeScript 配置 #
esbuild 会读取 tsconfig.json 中的部分配置:
json
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
类型检查 #
esbuild 不进行类型检查,需要配合 tsc:
bash
# 类型检查
tsc --noEmit
# 使用 esbuild 打包
esbuild src/index.ts --bundle --outfile=dist/bundle.js
在 package.json 中配置脚本:
json
{
"scripts": {
"typecheck": "tsc --noEmit",
"build": "esbuild src/index.ts --bundle --outfile=dist/bundle.js",
"prebuild": "npm run typecheck"
}
}
JSX 支持 #
esbuild 原生支持 JSX 语法:
jsx
// src/App.jsx
function App() {
return (
<div className="app">
<h1>Hello, esbuild!</h1>
<p>This is a JSX example.</p>
</div>
);
}
export default App;
打包 JSX:
bash
esbuild src/App.jsx --bundle --outfile=dist/bundle.js
JSX 配置 #
javascript
// 使用 esbuild API
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/App.jsx'],
bundle: true,
outfile: 'dist/bundle.js',
loader: {
'.jsx': 'jsx',
},
jsxFactory: 'React.createElement',
jsxFragment: 'React.Fragment',
});
命令行配置:
bash
esbuild src/App.jsx --bundle \
--loader:.jsx=jsx \
--jsx-factory=h \
--jsx-fragment=Fragment \
--outfile=dist/bundle.js
JSX 自动导入 #
javascript
esbuild.build({
entryPoints: ['src/App.jsx'],
bundle: true,
outfile: 'dist/bundle.js',
jsx: 'automatic', // React 17+ 自动导入
jsxImportSource: 'react',
});
CSS 支持 #
esbuild 支持 CSS 打包:
css
/* src/styles.css */
body {
margin: 0;
padding: 0;
font-family: system-ui;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
javascript
// src/index.js
import './styles.css';
console.log('App started');
打包:
bash
esbuild src/index.js --bundle --outfile=dist/bundle.js
CSS 模块 #
javascript
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
loader: {
'.css': 'css',
'.module.css': 'local-css',
},
});
单独输出 CSS #
javascript
esbuild.build({
entryPoints: ['src/styles.css'],
bundle: true,
outfile: 'dist/styles.css',
loader: {
'.css': 'css',
},
});
文件加载器 #
esbuild 支持多种文件类型:
javascript
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
loader: {
'.js': 'js',
'.jsx': 'jsx',
'.ts': 'ts',
'.tsx': 'tsx',
'.css': 'css',
'.json': 'json',
'.txt': 'text',
'.png': 'dataurl',
'.svg': 'file',
'.woff': 'file',
'.woff2': 'file',
},
});
加载器类型 #
| 加载器 | 说明 | 使用场景 |
|---|---|---|
js |
JavaScript | .js 文件 |
jsx |
JavaScript + JSX | .jsx 文件 |
ts |
TypeScript | .ts 文件 |
tsx |
TypeScript + JSX | .tsx 文件 |
css |
CSS | .css 文件 |
local-css |
CSS Modules | .module.css |
json |
JSON | .json 文件 |
text |
文本字符串 | .txt, .md |
dataurl |
Base64 内联 | 小图片、字体 |
file |
复制文件 | 大图片、字体 |
binary |
二进制数据 | 二进制文件 |
copy |
复制到输出目录 | 静态资源 |
开发模式 #
Watch 模式 #
bash
esbuild src/index.js --bundle --outfile=dist/bundle.js --watch
使用 API:
javascript
const esbuild = require('esbuild');
const ctx = await esbuild.context({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
});
await ctx.watch();
console.log('Watching...');
开发服务器 #
bash
esbuild src/index.js --bundle --outfile=dist/bundle.js --servedir=dist
使用 API:
javascript
const esbuild = require('esbuild');
const ctx = await esbuild.context({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
});
const { host, port } = await ctx.serve({
servedir: 'dist',
});
console.log(`Server running at http://${host}:${port}`);
完整开发配置 #
javascript
const esbuild = require('esbuild');
async function start() {
const ctx = await esbuild.context({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
sourcemap: true,
loader: {
'.js': 'js',
'.jsx': 'jsx',
'.css': 'css',
'.png': 'dataurl',
},
});
await ctx.watch();
const { host, port } = await ctx.serve({
servedir: 'dist',
port: 3000,
});
console.log(`Development server: http://${host}:${port}`);
}
start().catch(() => process.exit(1));
package.json 脚本配置 #
json
{
"name": "my-project",
"version": "1.0.0",
"scripts": {
"dev": "esbuild src/index.js --bundle --outfile=dist/bundle.js --watch --servedir=dist",
"build": "esbuild src/index.js --bundle --outfile=dist/bundle.js --minify",
"build:analyze": "esbuild src/index.js --bundle --outfile=dist/bundle.js --metafile=meta.json",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"esbuild": "^0.20.0",
"typescript": "^5.0.0"
}
}
常见问题解决 #
1. 模块解析问题 #
bash
# 排除 node_modules
esbuild src/index.js --bundle --external:lodash --outfile=dist/bundle.js
javascript
// API 方式
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
external: ['lodash', 'react', 'react-dom'],
});
2. 路径别名 #
javascript
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
alias: {
'@': './src',
'@components': './src/components',
'@utils': './src/utils',
},
});
3. 环境变量 #
javascript
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
define: {
'process.env.NODE_ENV': '"production"',
'process.env.API_URL': '"https://api.example.com"',
},
});
4. Node.js 内置模块 #
javascript
// 浏览器环境需要 polyfill
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
platform: 'browser',
nodePaths: ['node_modules'],
define: {
global: 'globalThis',
},
});
下一步 #
现在你已经掌握了 esbuild 的基础使用方法,接下来学习 配置详解 深入了解 esbuild 的配置选项!
最后更新:2026-03-28