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