Advanced

Optimizing Tree Shaking with Claude Code

Learn about optimizing tree shaking using Claude Code. Includes practical code examples.

ツリーシェイキングで不要コードを自動除去

ツリーシェイキングは、使われていないコードをバンドルから自動的に除去する最適化技術です。Claude Codeを使えば、ツリーシェイキングが効果的に動作するコード構造への改善を効率的に実施できます。

ツリーシェイキングが効く書き方

> ツリーシェイキングが最大限効くように、ユーティリティモジュールをリファクタリングして。
// ❌ ツリーシェイキングが効かない書き方
// utils/index.ts
export default {
  formatDate(date: Date) { /* ... */ },
  formatCurrency(amount: number) { /* ... */ },
  formatPhoneNumber(phone: string) { /* ... */ },
  truncateText(text: string, max: number) { /* ... */ },
};

// ✅ ツリーシェイキングが効く書き方
// utils/formatDate.ts
export function formatDate(date: Date): string {
  return new Intl.DateTimeFormat('en-US').format(date);
}

// utils/formatCurrency.ts
export function formatCurrency(amount: number): string {
  return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'JPY' }).format(amount);
}

// utils/index.ts(再エクスポート)
export { formatDate } from './formatDate';
export { formatCurrency } from './formatCurrency';
export { formatPhoneNumber } from './formatPhoneNumber';
export { truncateText } from './truncateText';

sideEffectsの設定

// package.json
{
  "name": "my-library",
  "sideEffects": false
}
// CSSインポートがある場合
{
  "sideEffects": [
    "*.css",
    "*.scss",
    "./src/polyfills.ts",
    "./src/global-setup.ts"
  ]
}

バレルファイルの最適化

// ❌ 巨大なバレルファイル(全モジュールを読み込む)
// components/index.ts
export { Button } from './Button';
export { Card } from './Card';
export { Modal } from './Modal';
export { Table } from './Table';
export { Tabs } from './Tabs';
// ... 100個のコンポーネント

// ❌ このインポートは全コンポーネントを読み込む可能性がある
import { Button } from './components';

// ✅ 直接インポート(確実にツリーシェイキングされる)
import { Button } from './components/Button';

ライブラリのツリーシェイキング対応確認

// scripts/check-tree-shaking.ts
import { build } from 'esbuild';
import { readFileSync } from 'fs';

async function checkTreeShaking(pkg: string, importName: string) {
  const entry = `import { ${importName} } from '${pkg}'; console.log(${importName});`;
  
  const result = await build({
    stdin: { contents: entry, resolveDir: process.cwd() },
    bundle: true,
    write: false,
    minify: true,
    treeShaking: true,
    format: 'esm',
    metafile: true,
  });

  const size = result.outputFiles[0].contents.length;
  console.log(`${pkg} → ${importName}: ${(size / 1024).toFixed(1)}kB`);
  
  return size;
}

// Usage example:lodash-esのツリーシェイキングを確認
await checkTreeShaking('lodash-es', 'debounce');
await checkTreeShaking('lodash-es', 'merge');

CommonJSからESModulesへの移行

// ❌ CommonJS(ツリーシェイキング不可)
const { pick, omit } = require('lodash');
module.exports = { myFunction };

// ✅ ESModules(ツリーシェイキング可能)
import { pick, omit } from 'lodash-es';
export function myFunction() { /* ... */ }
// tsconfig.json
{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "bundler",
    "target": "ES2020"
  }
}

動的インポートとの組み合わせ

// 条件付きで重いライブラリを読み込む
async function processMarkdown(content: string) {
  // 必要なときだけインポート
  const { unified } = await import('unified');
  const remarkParse = (await import('remark-parse')).default;
  const remarkHtml = (await import('remark-html')).default;

  const result = await unified()
    .use(remarkParse)
    .use(remarkHtml)
    .process(content);

  return result.toString();
}

Viteでの設定最適化

// vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    target: 'es2020',
    minify: 'terser',
    terserOptions: {
      compress: {
        dead_code: true,
        drop_console: true, // console.logを除去
        pure_funcs: ['console.debug'], // 特定関数を除去
      },
    },
    rollupOptions: {
      treeshake: {
        moduleSideEffects: false,
        propertyReadSideEffects: false,
      },
    },
  },
});

ツリーシェイキングの効果を測定

# バンドルサイズの比較
npx vite build -- --mode analyze

# 特定のインポートのサイズ確認
npx import-cost

Summary

ツリーシェイキングはバンドル分析と組み合わせることで最大の効果を発揮します。Claude Codeを使えば、CommonJSからESModulesへの移行やバレルファイルの最適化など、地道なリファクタリング作業を効率化できます。コード分割と併用して、アプリ全体のロード時間を短縮しましょう。ツリーシェイキングの仕組みについてはwebpack公式ドキュメントも参考になります。

#Claude Code #tree shaking #バンドル #ESModules #optimization