# 通知設計書 29-BuildCycleError

## 概要

本ドキュメントは、Webpackにおける `BuildCycleError` の通知仕様を定義する。モジュール依存の循環参照（ビルドサイクル）が検出された場合に発行されるエラークラスである。

### 本通知の処理概要

BuildCycleErrorは、Webpackのモジュールビルドフェーズにおいて、モジュール間の循環的なビルド依存関係が検出された場合に発行されるエラー通知である。ビルド中のモジュールが別のモジュールのビルド完了を待ち、そのモジュールが最初のモジュールのビルド完了を待つようなデッドロック状態を検出する。

**業務上の目的・背景**：モジュールのビルド処理中に別のモジュールのビルドを要求し、その要求が循環する場合、デッドロックが発生してビルドが永久に完了しなくなる。この状態を検出してデッドロックを解消し、開発者に循環依存の存在を通知するためのエラーである。通常のimport/exportの循環参照とは異なり、ビルド処理レベルの循環（ローダー処理やビルド時依存解決の循環）を対象とする。

**通知の送信タイミング**：Compilation._buildModule処理の前段階で、creatingModuleDuringBuild Map を使ったビルド依存の循環検出アルゴリズムが実行され、循環が見つかった時点でcallbackにエラーが渡される。

**通知の受信者**：Webpackビルドを実行する開発者。callbackを通じてエラーが伝播し、最終的にcompilation.errorsに蓄積される。

**通知内容の概要**：循環的なビルド依存関係の存在を示す固定メッセージ。循環の起点となるモジュールへの参照を保持する。

**期待されるアクション**：開発者は、循環的なビルド依存を解消する。ローダーの設定を見直すか、モジュール構造を変更して循環を断ち切る。

## 通知種別

ビルドエラー（Webpack Compilation Error）。コンソール出力およびStats APIを通じて開発者に通知される。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（callbackを通じてエラー伝播） |
| 優先度 | 高（エラーレベル） |
| リトライ | なし（循環検出時に即座にエラー） |

### 送信先決定ロジック

Compilation._handleModuleBuildAndDependencies（またはその前段処理）内で、creatingModuleDuringBuild MapからBFS（幅優先探索）で循環を検出した場合にcallbackにBuildCycleErrorを渡す。

## 通知テンプレート

### メール通知の場合

該当なし。本通知はメール通知ではなく、Webpackビルド出力として表示される。

### 本文テンプレート

```
ERROR in There is a circular build dependency, which makes it impossible to create this module
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| module | 循環の起点モジュール | コンストラクタ引数 | Yes |
| name | エラー名 | 固定値 "BuildCycleError" | Yes |

本クラスのメッセージは固定文字列であり、動的な変数は含まれない。

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| モジュールビルド | Compilation内のモジュールビルド前処理 | creatingModuleDuringBuildから循環依存が検出された場合 | BFSで循環パスを探索 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 循環なし | creatingModuleDuringBuild上で循環パスが見つからない場合 |
| blockReasonsがundefined | ビルド中にブロックされているモジュールがない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[モジュールビルド開始] --> B[creatingModuleDuringBuildSet に追加]
    B --> C{blockReasonsが存在?}
    C -->|No| D[通常ビルド処理へ]
    C -->|Yes| E[blockReasons の Set を作成]
    E --> F[Set内の各モジュールを走査]
    F --> G{循環検出?（m === module）}
    G -->|No| H[blockReasonsのモジュールをSetに追加]
    H --> F
    G -->|Yes| I[BuildCycleError生成]
    I --> J[callback(error)でエラー伝播]
    J --> K[ビルド処理キャンセル]
    D --> L[buildModule実行]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし。Webpackはデータベースを使用しない。

### 更新テーブル一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ビルドサイクル検出 | creatingModuleDuringBuild上で循環パスが検出された場合 | ビルドをキャンセルし、callback経由でエラーを伝播 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。ビルド実行時に即座にエラーが生成される。

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

固定メッセージのみであり、モジュールパス等の動的情報はメッセージに含まれない。ただしmoduleプロパティからモジュール情報にアクセスは可能。

## 備考

- WebpackErrorを基底クラスとして継承している
- moduleプロパティに循環の起点モジュールへの参照を保持
- メッセージは固定文字列で、循環パスの詳細は含まれない
- creatingModuleDuringBuild は Map<Module, Set<Module>> 構造で、ビルド中のモジュール間のブロック関係を追跡
- BFS探索により直接的な循環だけでなく、間接的な循環（A->B->C->A）も検出可能
- デッドロック防止の仕組みとして機能する

---

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

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

### 推奨読解順序

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

BuildCycleErrorクラスと循環検出に使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebpackError.js | `lib/WebpackError.js` | 基底クラス |
| 1-2 | BuildCycleError.js | `lib/errors/BuildCycleError.js` | moduleを受け取る固定メッセージのエラークラス |

**読解のコツ**: クラス自体は非常にシンプル（全30行）。重要なのはCompilation.js側の循環検出アルゴリズム。

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

Compilation.jsでの循環検出ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Compilation.js | `lib/Compilation.js` | 2313-2330行目の循環検出アルゴリズム |

**主要処理フロー**:
1. **2311行目**: creatingModuleDuringBuildSetにモジュールを追加
2. **2316行目**: this.creatingModuleDuringBuild.get(module) でブロック理由を取得
3. **2318行目**: blockReasonsの新しいSetを作成
4. **2319行目**: Setの各項目をループ（BFS）
5. **2320行目**: 各項目のblockReasonsを取得
6. **2322-2323行目**: blockReasonsの各モジュールmが元のmoduleと一致するか確認
7. **2324行目**: 一致した場合、`callback(new BuildCycleError(module))` で循環エラーを返す
8. **2326行目**: 一致しない場合、Setに追加してBFS探索を拡張

#### Step 3: creatingModuleDuringBuildの管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Compilation.js | `lib/Compilation.js` | creatingModuleDuringBuild Mapの更新箇所 |

**主要処理フロー**:
- creatingModuleDuringBuildはモジュールのビルド開始時にエントリが追加され、ビルド完了後に削除される
- 値のSetにはビルドをブロックしているモジュール（ビルド完了待ちのモジュール）が含まれる

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

```
Compilation._handleModuleBuildAndDependencies (またはビルド前処理)
    |
    +-- creatingModuleDuringBuildSet.add(module) (2311行目)
    |
    +-- this.creatingModuleDuringBuild.get(module) (2316行目)
    |
    +-- BFS循環検出 (2318-2329行目)
    |       |
    |       +-- Set作成・走査
    |       +-- blockReasons取得・拡張
    |       +-- m === module 判定 (2323行目)
    |               |
    |               +-- callback(new BuildCycleError(module)) (2324行目)
    |
    +-- this.buildModule(module, callback) (2333行目) ← 循環なしの場合
```

### データフロー図

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

module (ビルド対象) ---------------> creatingModuleDuringBuild
                                     から blockReasons 取得
                                        |
                                        v
                                     BFS循環探索 -----------> BuildCycleError
                                        |                        |
                                        v                        v
                                     m === module判定      callback(error)
                                                                 |
                                                                 v
                                                         compilation.errors[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BuildCycleError.js | `lib/errors/BuildCycleError.js` | ソース | エラークラス本体 |
| Compilation.js | `lib/Compilation.js` | ソース | 循環検出アルゴリズムとエラー発行 |
| WebpackError.js | `lib/WebpackError.js` | ソース | 基底エラー/警告クラス |
