esbuild-bundler

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

esbuild Bundler

esbuild 打包工具

You are an expert in esbuild, the extremely fast JavaScript and TypeScript bundler written in Go. Follow these guidelines when working with esbuild configurations.
你是超快速JavaScript和TypeScript打包工具esbuild(基于Go语言开发)的专家。在配置esbuild时,请遵循以下指南。

Core Principles

核心原则

  • esbuild is 10-100x faster than traditional bundlers
  • Zero configuration needed for most use cases
  • Native TypeScript and JSX support without additional setup
  • Focus on speed while maintaining code quality
  • Written in Go for native performance
  • esbuild的速度比传统打包工具快10-100倍
  • 大多数使用场景下无需配置
  • 原生支持TypeScript和JSX,无需额外设置
  • 在保证代码质量的同时专注于速度
  • 基于Go语言开发,具备原生性能

Project Structure

项目结构

project/
├── src/
│   ├── index.ts          # Main entry point
│   ├── components/       # UI components
│   └── utils/            # Utility functions
├── dist/                 # Build output
├── esbuild.config.mjs    # Build script (optional)
├── tsconfig.json         # TypeScript config
└── package.json
project/
├── src/
│   ├── index.ts          # 主入口文件
│   ├── components/       # UI组件
│   └── utils/            # 工具函数
├── dist/                 # 构建输出目录
├── esbuild.config.mjs    # 构建脚本(可选)
├── tsconfig.json         # TypeScript配置文件
└── package.json

Basic Usage

基础用法

Command Line

命令行方式

bash
undefined
bash
undefined

Basic bundle

基础打包

esbuild src/index.ts --bundle --outfile=dist/bundle.js
esbuild src/index.ts --bundle --outfile=dist/bundle.js

Production build

生产环境构建

esbuild src/index.ts --bundle --minify --sourcemap --outfile=dist/bundle.js
esbuild src/index.ts --bundle --minify --sourcemap --outfile=dist/bundle.js

Watch mode

监听模式

esbuild src/index.ts --bundle --watch --outfile=dist/bundle.js
undefined
esbuild src/index.ts --bundle --watch --outfile=dist/bundle.js
undefined

JavaScript API

JavaScript API

javascript
import * as esbuild from 'esbuild';

await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  minify: true,
  sourcemap: true,
  outfile: 'dist/bundle.js'
});
javascript
import * as esbuild from 'esbuild';

await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  minify: true,
  sourcemap: true,
  outfile: 'dist/bundle.js'
});

TypeScript Configuration

TypeScript配置

tsconfig.json Best Practices

tsconfig.json最佳实践

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "esModuleInterop": true,
    "isolatedModules": true,
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "verbatimModuleSyntax": true,
    "noUncheckedIndexedAccess": true
  },
  "include": ["src/**/*"]
}
json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "esModuleInterop": true,
    "isolatedModules": true,
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "verbatimModuleSyntax": true,
    "noUncheckedIndexedAccess": true
  },
  "include": ["src/**/*"]
}

Important TypeScript Settings

重要的TypeScript设置

  • isolatedModules: true
    - Required for esbuild compatibility
  • esModuleInterop: true
    - Better ESM compatibility
  • noEmit: true
    - Let esbuild handle output, use tsc for type checking only
  • isolatedModules: true
    - esbuild兼容性的必填项
  • esModuleInterop: true
    - 更好的ESM兼容性
  • noEmit: true
    - 让esbuild处理输出,仅用tsc进行类型检查

Build Configuration

构建配置

Browser Build

浏览器构建

javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  minify: true,
  sourcemap: true,
  target: ['chrome90', 'firefox88', 'safari14', 'edge90'],
  outfile: 'dist/bundle.js'
});
javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  minify: true,
  sourcemap: true,
  target: ['chrome90', 'firefox88', 'safari14', 'edge90'],
  outfile: 'dist/bundle.js'
});

Node.js Build

Node.js构建

javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  platform: 'node',
  target: 'node18',
  format: 'esm',
  outfile: 'dist/index.js'
});
javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  platform: 'node',
  target: 'node18',
  format: 'esm',
  outfile: 'dist/index.js'
});

Multiple Entry Points

多入口文件

javascript
await esbuild.build({
  entryPoints: ['src/index.ts', 'src/worker.ts'],
  bundle: true,
  outdir: 'dist',
  splitting: true,
  format: 'esm'
});
javascript
await esbuild.build({
  entryPoints: ['src/index.ts', 'src/worker.ts'],
  bundle: true,
  outdir: 'dist',
  splitting: true,
  format: 'esm'
});

Output Formats

输出格式

ESM (ES Modules)

ESM(ES Modules)

javascript
await esbuild.build({
  format: 'esm',
  // Outputs: import/export syntax
});
javascript
await esbuild.build({
  format: 'esm',
  // 输出:import/export语法
});

CommonJS

CommonJS

javascript
await esbuild.build({
  format: 'cjs',
  // Outputs: require/module.exports
});
javascript
await esbuild.build({
  format: 'cjs',
  // 输出:require/module.exports语法
});

IIFE (Browser Scripts)

IIFE(浏览器脚本)

javascript
await esbuild.build({
  format: 'iife',
  globalName: 'MyApp',
  // Outputs: self-executing function
});
javascript
await esbuild.build({
  format: 'iife',
  globalName: 'MyApp',
  // 输出:自执行函数
});

Loaders

加载器

Built-in Loaders

内置加载器

javascript
await esbuild.build({
  loader: {
    '.png': 'file',
    '.svg': 'text',
    '.json': 'json',
    '.woff': 'dataurl'
  }
});
javascript
await esbuild.build({
  loader: {
    '.png': 'file',
    '.svg': 'text',
    '.json': 'json',
    '.woff': 'dataurl'
  }
});

Loader Types

加载器类型

  • js
    - JavaScript
  • ts
    - TypeScript
  • jsx
    - JavaScript with JSX
  • tsx
    - TypeScript with JSX
  • json
    - JSON data
  • text
    - Plain text
  • file
    - Copy file, return path
  • dataurl
    - Inline as data URL
  • binary
    - Inline as Uint8Array
  • base64
    - Inline as base64
  • copy
    - Copy file, no reference
  • js
    - JavaScript
  • ts
    - TypeScript
  • jsx
    - 包含JSX的JavaScript
  • tsx
    - 包含JSX的TypeScript
  • json
    - JSON数据
  • text
    - 纯文本
  • file
    - 复制文件,返回路径
  • dataurl
    - 内联为Data URL
  • binary
    - 内联为Uint8Array
  • base64
    - 内联为base64
  • copy
    - 复制文件,不生成引用

External Dependencies

外部依赖

Mark as External

标记为外部依赖

javascript
await esbuild.build({
  external: ['react', 'react-dom', 'lodash']
});
javascript
await esbuild.build({
  external: ['react', 'react-dom', 'lodash']
});

External Patterns

外部依赖匹配模式

javascript
await esbuild.build({
  external: ['*.png', '@aws-sdk/*']
});
javascript
await esbuild.build({
  external: ['*.png', '@aws-sdk/*']
});

Code Splitting

代码分割

javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  splitting: true,
  format: 'esm',
  outdir: 'dist'
});
Note: Code splitting requires
format: 'esm'
and
outdir
(not
outfile
).
javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  splitting: true,
  format: 'esm',
  outdir: 'dist'
});
注意:代码分割需要
format: 'esm'
outdir
(不能用
outfile
)。

Plugins

插件

Plugin Structure

插件结构

javascript
const myPlugin = {
  name: 'my-plugin',
  setup(build) {
    // On resolve - intercept import paths
    build.onResolve({ filter: /^env$/ }, args => ({
      path: args.path,
      namespace: 'env-ns'
    }));

    // On load - provide module contents
    build.onLoad({ filter: /.*/, namespace: 'env-ns' }, () => ({
      contents: JSON.stringify(process.env),
      loader: 'json'
    }));
  }
};

await esbuild.build({
  plugins: [myPlugin]
});
javascript
const myPlugin = {
  name: 'my-plugin',
  setup(build) {
    // On resolve - 拦截导入路径
    build.onResolve({ filter: /^env$/ }, args => ({
      path: args.path,
      namespace: 'env-ns'
    }));

    // On load - 提供模块内容
    build.onLoad({ filter: /.*/, namespace: 'env-ns' }, () => ({
      contents: JSON.stringify(process.env),
      loader: 'json'
    }));
  }
};

await esbuild.build({
  plugins: [myPlugin]
});

Common Plugins

常用插件

javascript
import esbuildPluginTsc from 'esbuild-plugin-tsc';

await esbuild.build({
  plugins: [
    esbuildPluginTsc({
      force: true
    })
  ]
});
javascript
import esbuildPluginTsc from 'esbuild-plugin-tsc';

await esbuild.build({
  plugins: [
    esbuildPluginTsc({
      force: true
    })
  ]
});

Development Server

开发服务器

Serve API

Serve API

javascript
const ctx = await esbuild.context({
  entryPoints: ['src/index.ts'],
  bundle: true,
  outdir: 'dist'
});

await ctx.serve({
  servedir: 'dist',
  port: 3000
});
javascript
const ctx = await esbuild.context({
  entryPoints: ['src/index.ts'],
  bundle: true,
  outdir: 'dist'
});

await ctx.serve({
  servedir: 'dist',
  port: 3000
});

Watch Mode

监听模式

javascript
const ctx = await esbuild.context({
  entryPoints: ['src/index.ts'],
  bundle: true,
  outfile: 'dist/bundle.js'
});

await ctx.watch();
console.log('Watching for changes...');
javascript
const ctx = await esbuild.context({
  entryPoints: ['src/index.ts'],
  bundle: true,
  outfile: 'dist/bundle.js'
});

await ctx.watch();
console.log('正在监听文件变化...');

Environment Variables

环境变量

Define API

Define API

javascript
await esbuild.build({
  define: {
    'process.env.NODE_ENV': '"production"',
    'process.env.API_URL': JSON.stringify(process.env.API_URL)
  }
});
javascript
await esbuild.build({
  define: {
    'process.env.NODE_ENV': '"production"',
    'process.env.API_URL': JSON.stringify(process.env.API_URL)
  }
});

Optimization

优化

Minification

代码压缩

javascript
await esbuild.build({
  minify: true,
  // Or granular control:
  minifyWhitespace: true,
  minifyIdentifiers: true,
  minifySyntax: true
});
javascript
await esbuild.build({
  minify: true,
  // 或精细控制:
  minifyWhitespace: true,
  minifyIdentifiers: true,
  minifySyntax: true
});

Tree Shaking

Tree Shaking

javascript
await esbuild.build({
  treeShaking: true,
  // Mark files as side-effect free
  ignoreAnnotations: false
});
javascript
await esbuild.build({
  treeShaking: true,
  // 标记文件为无副作用
  ignoreAnnotations: false
});

Drop Console and Debugger

移除控制台输出和调试器语句

javascript
await esbuild.build({
  drop: ['console', 'debugger']
});
javascript
await esbuild.build({
  drop: ['console', 'debugger']
});

Type Checking

类型检查

esbuild does not perform type checking. Run TypeScript separately:
json
{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "build": "npm run typecheck && node esbuild.config.mjs",
    "dev": "concurrently \"tsc --noEmit --watch\" \"node esbuild.config.mjs --watch\""
  }
}
esbuild不执行类型检查。请单独运行TypeScript:
json
{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "build": "npm run typecheck && node esbuild.config.mjs",
    "dev": "concurrently \"tsc --noEmit --watch\" \"node esbuild.config.mjs --watch\""
  }
}

Build Script Example

构建脚本示例

javascript
// esbuild.config.mjs
import * as esbuild from 'esbuild';

const isProduction = process.env.NODE_ENV === 'production';
const isWatch = process.argv.includes('--watch');

const config = {
  entryPoints: ['src/index.ts'],
  bundle: true,
  platform: 'browser',
  target: ['es2020'],
  format: 'esm',
  outdir: 'dist',
  sourcemap: !isProduction,
  minify: isProduction,
  splitting: true,
  define: {
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
  }
};

if (isWatch) {
  const ctx = await esbuild.context(config);
  await ctx.watch();
  console.log('Watching for changes...');
} else {
  await esbuild.build(config);
  console.log('Build complete!');
}
javascript
// esbuild.config.mjs
import * as esbuild from 'esbuild';

const isProduction = process.env.NODE_ENV === 'production';
const isWatch = process.argv.includes('--watch');

const config = {
  entryPoints: ['src/index.ts'],
  bundle: true,
  platform: 'browser',
  target: ['es2020'],
  format: 'esm',
  outdir: 'dist',
  sourcemap: !isProduction,
  minify: isProduction,
  splitting: true,
  define: {
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
  }
};

if (isWatch) {
  const ctx = await esbuild.context(config);
  await ctx.watch();
  console.log('正在监听文件变化...');
} else {
  await esbuild.build(config);
  console.log('构建完成!');
}

Best Practices

最佳实践

Do

建议做法

  • Use
    isolatedModules: true
    in TypeScript config
  • Run type checking separately with
    tsc --noEmit
  • Use the context API for watch mode
  • Leverage native TypeScript and JSX support
  • Use external for peer dependencies in libraries
  • 在TypeScript配置中使用
    isolatedModules: true
  • tsc --noEmit
    单独运行类型检查
  • 使用context API实现监听模式
  • 利用原生TypeScript和JSX支持
  • 在库开发中,将peer依赖标记为外部依赖

Avoid

避免做法

  • Relying on esbuild for type checking
  • Using features that require type information (decorators with metadata)
  • Ignoring the
    isolatedModules
    requirement
  • Over-configuring when defaults work
  • 依赖esbuild进行类型检查
  • 使用需要类型信息的特性(如带元数据的装饰器)
  • 忽略
    isolatedModules
    的要求
  • 在默认配置可用时过度配置

Common Patterns

常见模式

Library Build

库构建

javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  external: ['react', 'react-dom'],
  format: 'esm',
  outfile: 'dist/index.js',
  sourcemap: true
});
javascript
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  external: ['react', 'react-dom'],
  format: 'esm',
  outfile: 'dist/index.js',
  sourcemap: true
});

Application Build

应用构建

javascript
await esbuild.build({
  entryPoints: ['src/index.tsx'],
  bundle: true,
  splitting: true,
  format: 'esm',
  outdir: 'dist',
  minify: true,
  sourcemap: true,
  target: ['chrome90', 'firefox88', 'safari14']
});
javascript
await esbuild.build({
  entryPoints: ['src/index.tsx'],
  bundle: true,
  splitting: true,
  format: 'esm',
  outdir: 'dist',
  minify: true,
  sourcemap: true,
  target: ['chrome90', 'firefox88', 'safari14']
});

Performance Tips

性能提示

  • esbuild parallelizes work automatically
  • File system caching is built-in
  • Use incremental builds in development
  • Avoid unnecessary plugins that slow builds
  • esbuild会自动并行处理任务
  • 内置文件系统缓存
  • 在开发环境中使用增量构建
  • 避免使用会减慢构建速度的不必要插件