# 機能設計書 32-コード分割

## 概要

本ドキュメントは、Bunバンドラーにおけるコード分割（Code Splitting）機能の設計仕様を記載する。コード分割は、動的インポート（`import()`）によるモジュールの遅延読み込みを実現し、初期読み込み時間の短縮とリソースの効率的な配信を可能にする機能である。

### 本機能の処理概要

コード分割は、JavaScriptバンドルを複数のチャンク（chunk）に自動分割し、必要なタイミングで必要なコードのみを読み込むことを可能にする機能である。

**業務上の目的・背景**：大規模なWebアプリケーションでは、すべてのコードを単一のバンドルにまとめると、初期読み込み時間が長くなりユーザー体験を損なう。コード分割により、初期表示に必要なコードのみを先に読み込み、それ以外は必要に応じて遅延読み込みすることで、アプリケーションの体感速度を向上させることができる。SPAやルートベースの遅延読み込みを実現する上で不可欠な機能である。

**機能の利用シーン**：SPAのルート別コード分割、大きなライブラリの遅延読み込み、ユーザーインタラクションに応じた機能の動的読み込み時に利用される。`bun build --splitting`オプションで有効化する。

**主要な処理内容**：
1. 動的インポート（`import()`）の検出と解析
2. エントリーポイントからの依存関係グラフ構築
3. 共有モジュールの識別とチャンク境界の決定
4. 複数エントリーポイント間の共通コード抽出
5. チャンク間の依存関係（cross-chunk imports）の管理
6. チャンクごとの出力ファイル生成

**関連システム・外部連携**：ツリーシェイキング機能と連携して、各チャンク内の未使用コードを除去する。

**権限による制御**：特になし。CLI/APIオプションでコード分割の有効/無効を切り替え可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | build | 主画面 | バンドル処理実行時のコード分割適用 |

## 機能種別

計算処理 / バンドル処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code_splitting | bool | No | コード分割の有効/無効 | デフォルト: false |
| chunk_naming | string | No | チャンクファイルの命名パターン | デフォルト: "[name]-[hash].[ext]" |
| outdir | string | Yes(splitting有効時) | 出力ディレクトリ | コード分割有効時は必須 |

### 入力データソース

- JavaScript/TypeScriptソースファイル
- 動的インポート（`import()`）文
- CLI/APIオプション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| エントリーチャンク | ファイル | エントリーポイントごとのメインバンドル |
| 共有チャンク | ファイル | 複数エントリーから参照される共通コード |
| 動的チャンク | ファイル | 動的インポートで読み込まれるコード |
| ソースマップ | ファイル | 各チャンクに対応するソースマップ（オプション） |

### 出力先

ファイルシステム（指定された出力ディレクトリ）

## 処理フロー

### 処理シーケンス

```
1. エントリーポイント解析
   └─ 各エントリーポイントから依存関係グラフを構築
2. 動的インポート検出
   └─ import()文を検出し、動的エントリーポイントとして登録
3. 到達可能ファイル特定
   └─ findReachableFiles()で到達可能ファイルを特定、動的インポート先も追跡
4. エントリービット計算
   └─ 各ファイルがどのエントリーポイントから到達可能かをビットセットで管理
5. チャンク計算
   └─ computeChunks()でエントリービットに基づきチャンクを決定
6. クロスチャンク依存関係計算
   └─ computeCrossChunkDependencies()でチャンク間の依存関係を解決
7. チャンク生成
   └─ 各チャンクのコードを並列で生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始: エントリーポイント] --> B[依存関係グラフ構築]
    B --> C[動的インポート検出]
    C --> D[到達可能ファイル特定]
    D --> E[エントリービット計算]
    E --> F{ファイルを解析}
    F --> G[ビットセット更新]
    G --> H{次のファイルあり?}
    H -->|Yes| F
    H -->|No| I[チャンク計算]
    I --> J[同一ビットのファイルをグループ化]
    J --> K[クロスチャンク依存関係計算]
    K --> L[チャンク並列生成]
    L --> M[終了: 複数チャンク出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-001 | outdir必須 | コード分割有効時は--outdirオプションが必須 | code_splitting=true |
| BR-32-002 | 共有チャンク生成 | 複数エントリーから参照されるモジュールは共有チャンクに配置 | 複数エントリーポイント存在時 |
| BR-32-003 | 動的チャンク | import()で参照されるモジュールは別チャンクとして生成 | 動的インポート検出時 |
| BR-32-004 | ハッシュ付き命名 | 出力ファイル名にはコンテンツハッシュを含む | デフォルト設定時 |

### 計算ロジック

**エントリービット計算**: 各ファイルに対して、どのエントリーポイントから到達可能かをAutoBitSet（ビットセット）で管理。同一のビットパターンを持つファイルは同一チャンクに配置される。

**チャンクキー生成**: エントリービットのバイト表現をキーとしてチャンクをグループ化。これにより、同じエントリーポイントセットから参照されるファイルが自動的に同一チャンクにまとまる。

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | outdir未指定でcode_splitting有効 | エラーメッセージを出力し終了 |
| - | 警告 | 循環動的インポートの検出 | 警告を出力、処理は継続 |

### リトライ仕様

リトライは行わない。

## トランザクション仕様

該当なし（ファイル処理のみ）

## パフォーマンス要件

- チャンク生成は並列処理で実行
- エントリービット計算は効率的なビットセット演算を使用
- 大規模プロジェクトでも合理的な時間で完了すること

## セキュリティ考慮事項

- 出力ファイルにはコンテンツハッシュを含めることで、キャッシュ破壊を適切に管理
- チャンク間の依存関係は適切に解決され、不正なコード実行を防止

## 備考

- CSSチャンキング（`--css-chunking`）と組み合わせることで、CSS も同様に分割可能
- 動的インポート先が静的に解決できない場合（変数を使った動的パス）は対応不可

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、コード分割で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Chunk.zig | `src/bundler/Chunk.zig` | Chunk構造体、entry_bits（AutoBitSet）、cross_chunk_importsの定義 |
| 1-2 | LinkerGraph.zig | `src/bundler/LinkerGraph.zig` | code_splittingフラグ、entry_pointsの管理 |

**読解のコツ**: Chunk構造体の`entry_bits`フィールドがコード分割の核心。各ファイルがどのエントリーポイントから到達可能かをビットで表現する。

#### Step 2: エントリーポイントを理解する

処理の起点となる関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bundle_v2.zig | `src/bundler/bundle_v2.zig` | findReachableFiles()での動的インポート追跡（422-428行目） |

**主要処理フロー**:
1. **293-302行目**: ReachableFileVisitorでの動的インポートチェック
2. **352-370行目**: 動的インポート先を動的エントリーポイントとして登録
3. **422-428行目**: code_splitting有効時のみ動的インポートをチェック

#### Step 3: チャンク計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | computeChunks.zig | `src/bundler/linker_context/computeChunks.zig` | チャンク計算のメイン処理 |

**主要処理フロー**:
- **1-50行目**: computeChunks()関数、JSチャンクとCSSチャンクのマップ初期化
- **35-139行目**: エントリーポイントごとのチャンク作成
- **43-61行目**: code_splitting時のエントリービット計算
- **217-268行目**: 各ファイルをエントリービットに基づいてチャンクに振り分け

#### Step 4: クロスチャンク依存関係を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | computeCrossChunkDependencies.zig | `src/bundler/linker_context/computeCrossChunkDependencies.zig` | チャンク間依存関係の計算 |

**主要処理フロー**:
- チャンク間のインポート関係を解決
- 必要なシンボルのエクスポート/インポート文を生成

### プログラム呼び出し階層図

```
BundleV2.bundle()
    │
    ├─ findReachableFiles()
    │      └─ ReachableFileVisitor.visit()
    │             ├─ 静的インポートの走査
    │             └─ 動的インポートの検出（code_splitting時）
    │
    └─ LinkerContext
           ├─ computeChunks()
           │      ├─ エントリーポイントチャンク作成
           │      ├─ エントリービット計算
           │      └─ ファイルのチャンク振り分け
           │
           ├─ computeCrossChunkDependencies()
           │      └─ チャンク間依存関係の解決
           │
           └─ generateChunksInParallel()
                  └─ 各チャンクのコード生成（並列）
```

### データフロー図

```
[入力]                        [処理]                              [出力]

エントリーポイント ───▶ 依存関係グラフ構築 ───▶ ファイルリスト
       │
       ▼
動的インポート ───────▶ 動的エントリー登録 ───▶ 追加エントリー
       │
       ▼
全ファイル ──────────▶ エントリービット計算 ───▶ ビットセット
       │
       ▼
ビットセット ────────▶ チャンク計算 ───────────▶ チャンクリスト
       │
       ├─────────────────▶ エントリーチャンク
       ├─────────────────▶ 共有チャンク
       └─────────────────▶ 動的チャンク
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Chunk.zig | `src/bundler/Chunk.zig` | ソース | チャンク構造体定義、entry_bits管理 |
| computeChunks.zig | `src/bundler/linker_context/computeChunks.zig` | ソース | チャンク計算のメイン処理 |
| computeCrossChunkDependencies.zig | `src/bundler/linker_context/computeCrossChunkDependencies.zig` | ソース | チャンク間依存関係計算 |
| bundle_v2.zig | `src/bundler/bundle_v2.zig` | ソース | 動的インポート検出、到達可能ファイル特定 |
| LinkerContext.zig | `src/bundler/LinkerContext.zig` | ソース | リンカーコンテキスト |
| build_command.zig | `src/cli/build_command.zig` | ソース | CLIオプション処理 |
| generateChunksInParallel.zig | `src/bundler/linker_context/generateChunksInParallel.zig` | ソース | 並列チャンク生成 |
