mcpField
E
esbuild-bundler

esbuild-bundler

github.com/mindrally開発287704 回インストール3 週間前に更新
リポジトリ

esbuild-bundler について

JavaScriptおよびTypeScript開発者向けのesbuild設定ガイドです。バンドル、出力形式、ローダー、プラグイン、開発フローを扱い、型チェックを別途行う方法も説明します。

主な機能

  1. 01CLIとJavaScript APIのビルド設定
  2. 02ブラウザーとNode.jsの設定
  3. 03出力形式とローダー
  4. 04コード分割とプラグイン
  5. 05ウォッチモードと開発サーバー
  6. 06TypeScriptの型チェックを別途実行

活用シーン

  1. 01TypeScriptまたは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 バンドラー

Go で書かれた、非常に高速な JavaScript および TypeScript バンドラーである esbuild のエキスパートとして、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
});
ツリーシェイキング
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 で型チェックを別途実行します
  • ウォッチモードにはコンテキスト 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 は自動的に処理を並列化します
  • ファイルシステムのキャッシュが組み込まれています
  • 開発時にはインクリメンタルビルドを使用します
  • ビルドを遅くする不要なプラグインは避けます

コメント