mcpField
E
esbuild-bundler

esbuild-bundler

github.com/mindrally开发287704 次安装3 周前更新
代码仓库

关于 esbuild-bundler

面向 JavaScript 和 TypeScript 开发者的 esbuild 配置指南,介绍打包、输出格式、加载器、插件和开发流程,并说明类型检查需单独处理。

主要功能

  1. 01命令行与 JavaScript API 构建配置
  2. 02浏览器与 Node.js 配置
  3. 03输出格式与加载器
  4. 04代码拆分与插件
  5. 05监听模式与开发服务器
  6. 06单独进行 TypeScript 类型检查

适用场景

  1. 01打包 TypeScript 或 JSX 项目
  2. 02构建浏览器或 Node.js 产物
  3. 03配置监听与增量构建
  4. 04生成库和应用程序包

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mindrally/skills --skill esbuild-bundler

安装后在 Claude Code 中输入/esbuild-bundler确认已加载。

详细介绍

esbuild 打包器

你是 esbuild 方面的专家。esbuild 是一款使用 Go 编写、速度极快的 JavaScript 和 TypeScript 打包器。使用 esbuild 配置时,请遵循以下指南。

核心原则

  • esbuild 的速度比传统打包器快 10–100 倍
  • 大多数使用场景无需任何配置
  • 原生支持 TypeScript 和 JSX,无需额外设置
  • 在保持代码质量的同时注重速度
  • 使用 Go 编写,实现原生性能

项目结构

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

基本用法

命令行
# Basic bundle
esbuild src/index.ts --bundle --outfile=dist/bundle.js

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

# Watch mode
esbuild src/index.ts --bundle --watch --outfile=dist/bundle.js
JavaScript API
import * as esbuild from 'esbuild';

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

TypeScript 配置

tsconfig.json 最佳实践
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "esModuleInterop": true,
    "isolatedModules": true,
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "verbatimModuleSyntax": true,
    "noUncheckedIndexedAccess": true
  },
  "include": ["src/**/*"]
}
重要的 TypeScript 设置
  • isolatedModules: true - esbuild 兼容性所必需
  • esModuleInterop: true - 提高 ESM 兼容性
  • noEmit: true - 让 esbuild 处理输出,tsc 仅用于类型检查

构建配置

浏览器构建
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  minify: true,
  sourcemap: true,
  target: ['chrome90', 'firefox88', 'safari14', 'edge90'],
  outfile: 'dist/bundle.js'
});
Node.js 构建
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  platform: 'node',
  target: 'node18',
  format: 'esm',
  outfile: 'dist/index.js'
});
多个入口点
await esbuild.build({
  entryPoints: ['src/index.ts', 'src/worker.ts'],
  bundle: true,
  outdir: 'dist',
  splitting: true,
  format: 'esm'
});

输出格式

ESM(ES 模块)
await esbuild.build({
  format: 'esm',
  // Outputs: import/export syntax
});
CommonJS
await esbuild.build({
  format: 'cjs',
  // Outputs: require/module.exports
});
IIFE(浏览器脚本)
await esbuild.build({
  format: 'iife',
  globalName: 'MyApp',
  // Outputs: self-executing function
});

加载器

内置加载器
await esbuild.build({
  loader: {
    '.png': 'file',
    '.svg': 'text',
    '.json': 'json',
    '.woff': 'dataurl'
  }
});
加载器类型
  • js - JavaScript
  • ts - TypeScript
  • jsx - 带 JSX 的 JavaScript
  • tsx - 带 JSX 的 TypeScript
  • json - JSON 数据
  • text - 纯文本
  • file - 复制文件并返回路径
  • dataurl - 内联为数据 URL
  • binary - 内联为 Uint8Array
  • base64 - 内联为 base64
  • copy - 复制文件,不生成引用

外部依赖

标记为外部依赖
await esbuild.build({
  external: ['react', 'react-dom', 'lodash']
});
外部匹配模式
await esbuild.build({
  external: ['*.png', '@aws-sdk/*']
});

代码拆分

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

注意:代码拆分需要 format: 'esm' 和 outdir(而非 outfile)。

插件

插件结构
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]
});
常见插件
import esbuildPluginTsc from 'esbuild-plugin-tsc';

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

开发服务器

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

await ctx.serve({
  servedir: 'dist',
  port: 3000
});
监视模式
const ctx = await esbuild.context({
  entryPoints: ['src/index.ts'],
  bundle: true,
  outfile: 'dist/bundle.js'
});

await ctx.watch();
console.log('Watching for changes...');

环境变量

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

优化

压缩
await esbuild.build({
  minify: true,
  // Or granular control:
  minifyWhitespace: true,
  minifyIdentifiers: true,
  minifySyntax: true
});
Tree Shaking
await esbuild.build({
  treeShaking: true,
  // Mark files as side-effect free
  ignoreAnnotations: false
});
移除 Console 和 Debugger
await esbuild.build({
  drop: ['console', 'debugger']
});

类型检查

esbuild 不执行类型检查。请单独运行 TypeScript:

{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "build": "npm run typecheck && node esbuild.config.mjs",
    "dev": "concurrently \"tsc --noEmit --watch\" \"node esbuild.config.mjs --watch\""
  }
}

构建脚本示例

// 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!');
}

最佳实践

建议
  • 在 TypeScript 配置中使用 isolatedModules: true
  • 使用 tsc --noEmit 单独运行类型检查
  • 在监视模式下使用 context API
  • 利用原生的 TypeScript 和 JSX 支持
  • 在库中将同级依赖设为 external
避免
  • 依赖 esbuild 进行类型检查
  • 使用需要类型信息的功能(例如带元数据的装饰器)
  • 忽略 isolatedModules 要求
  • 默认配置已满足需求时,避免过度配置

常见模式

库构建
await esbuild.build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  external: ['react', 'react-dom'],
  format: 'esm',
  outfile: 'dist/index.js',
  sourcemap: true
});
应用构建
await esbuild.build({
  entryPoints: ['src/index.tsx'],
  bundle: true,
  splitting: true,
  format: 'esm',
  outdir: 'dist',
  minify: true,
  sourcemap: true,
  target: ['chrome90', 'firefox88', 'safari14']
});

性能提示

  • esbuild 会自动并行处理任务
  • 内置文件系统缓存
  • 在开发过程中使用增量构建
  • 避免使用会拖慢构建速度的不必要插件

评论

支持 Markdown