# 帳票設計書 4-Stats エラーレポート

## 概要

本ドキュメントは、webpackビルド時のエラー情報を構造化して出力する「Stats エラーレポート」の設計仕様を定義する。

### 本帳票の処理概要

Stats エラーレポートは、ビルド時に発生したエラー情報（メッセージ、モジュール、位置、スタックトレース、原因チェーン）を構造化して出力する帳票である。`EXTRACT_ERROR` 抽出関数と `SIMPLE_EXTRACTORS.compilation.errors` により生成される。

**業務上の目的・背景**：ビルドエラーの原因を迅速に特定し、修正するために必要である。エラーメッセージだけでなく、エラーが発生したモジュール、ファイル内の位置、依存チェーン（moduleTrace）、原因チェーン（cause）、集約エラー（AggregateError）を構造的に提供する。

**帳票の利用シーン**：ビルド失敗時のエラー診断、CI/CDパイプラインでのエラー報告、IDE連携でのエラー位置表示、エラーログの構造化分析に利用される。

**主要な出力内容**：
1. エラーメッセージ（message）
2. エラー発生モジュール（moduleIdentifier, moduleName）
3. エラー発生位置（loc）
4. エラー関連チャンク（chunkName, chunkId, chunkEntry, chunkInitial）
5. エラー関連ファイル（file）
6. エラー詳細（details）- 条件付き出力
7. スタックトレース（stack）- errorStack有効時
8. 原因チェーン（cause）- cause存在時
9. 集約エラー（errors）- AggregateError時
10. モジュールトレース（moduleTrace）- 依存チェーン

**帳票の出力タイミング**：`Stats.toJson()` または `Stats.toString()` 呼び出し時に、StatsFactoryの `compilation.errors` 抽出処理で生成される。

**帳票の利用者**：フロントエンド開発者、CI/CDシステム、エラー追跡ツール。

## 帳票種別

エラー情報構造化出力

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | CLI | `webpack` | ビルドエラー発生時に自動出力 |
| - | Node.js API | プログラム内 | `stats.toJson()` / `stats.toString()` |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON（toJson時）/ テキスト（toString時） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | StatsCompilation.errorsフィールドとして出力 |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

StatsError型の配列として出力される。各エラーは以下の構造を持つ。

```
{
    "message":           エラーメッセージ,
    "moduleIdentifier":  モジュール識別子,
    "moduleName":        モジュール名,
    "loc":              エラー位置,
    "chunkName":        関連チャンク名,
    "chunkId":          関連チャンクID,
    "chunkEntry":       エントリーチャンクか,
    "chunkInitial":     初期チャンクか,
    "file":             関連ファイル,
    "moduleId":         モジュールID,
    "details":          エラー詳細,
    "stack":            スタックトレース,
    "cause":            原因エラー（再帰構造）,
    "errors":           集約エラー配列,
    "moduleTrace":      モジュール依存トレース
}
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | message | エラーメッセージ | WebpackError.message / string | 文字列 |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | moduleIdentifier | モジュール識別子 | error.module.identifier() | 文字列 | - |
| 2 | moduleName | モジュール名 | error.module.readableIdentifier() | 文字列 | - |
| 3 | loc | エラー位置 | formatLocation(error.loc) | "行:列" 形式 | - |
| 4 | chunkName | 関連チャンク名 | error.chunk.name | 文字列 | - |
| 5 | chunkId | チャンクID | error.chunk.id | 文字列/数値 | - |
| 6 | chunkEntry | エントリーチャンクか | chunk.hasRuntime() | 真偽値 | - |
| 7 | chunkInitial | 初期チャンクか | chunk.canBeInitial() | 真偽値 | - |
| 8 | file | 関連ファイル | error.file | 文字列 | - |
| 9 | moduleId | モジュールID | chunkGraph.getModuleId(error.module) | 文字列/数値 | - |
| 10 | details | エラー詳細 | error.details | 文字列 | - |
| 11 | stack | スタックトレース | error.stack | 文字列 | - |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | moduleTrace | モジュール依存トレース | moduleGraph.getIssuer()再帰 | StatsModuleTraceItem[] |
| 2 | cause | 原因エラー | error.cause | StatsError（再帰構造） |
| 3 | errors | 集約エラー | error.errors（AggregateError） | StatsError[] |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| errorDetails | エラー詳細出力の有効/無効。`true` / `"auto"` / `false` | No（デフォルト: "auto"） |
| errorStack | スタックトレース出力の有効/無効 | No（デフォルト: false） |
| errorsSpace | エラー表示のスペース制限 | No |

### ソート順

エラーは発生順（compilation.getErrors()の返却順序）で出力される。

### 改ページ条件

N/A

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| Compilation | エラー一覧取得 | compilation.getErrors() |
| ModuleGraph | モジュール依存トレース | moduleGraph.getIssuer() |
| ChunkGraph | モジュールID取得 | chunkGraph.getModuleId() |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| errorsCount | countWithChildren(compilation, getErrors) | なし | 子コンパイル含む |
| details出力判定 | errorDetails === true \|\| (type.endsWith(".error") && errors.length < 3) | - | "auto"時はエラー3件未満で詳細表示 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[SIMPLE_EXTRACTORS.compilation.errors] --> B[cachedGetErrors で全エラー取得]
    B --> C[factory.create compilation.errors 呼び出し]
    C --> D[EXTRACT_ERROR._ でメッセージ/モジュール/位置抽出]
    D --> E[EXTRACT_ERROR.ids でID情報抽出]
    E --> F[EXTRACT_ERROR.moduleTrace でトレース生成]
    F --> G[EXTRACT_ERROR.errorDetails で詳細抽出]
    G --> H[EXTRACT_ERROR.errorStack でスタック抽出]
    H --> I[EXTRACT_ERROR.errorCause で原因チェーン抽出]
    I --> J[EXTRACT_ERROR.errorErrors で集約エラー抽出]
    J --> K{errorsSpace有限?}
    K -->|Yes| L[errorsSpaceLimit で表示制限]
    K -->|No| M[全エラー出力]
    L --> N[StatsError配列返却]
    M --> N
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 文字列エラー | エラーが文字列型 | messageのみ設定 | レガシー対応。webpack 6で非推奨 |
| 循環依存 | moduleTraceで循環検出 | visitedModulesで打ち切り | 無限ループ防止 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | エラー数件〜数十件 |
| 目標出力時間 | エラー数に比例（通常ミリ秒単位） |
| 同時出力数上限 | 1 |

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

エラーメッセージにはファイルパスやソースコード断片が含まれる可能性がある。スタックトレース（`errorStack: true`時）には内部パス情報が含まれるため、公開環境での出力に注意。

## 備考

- EXTRACT_ERRORオブジェクトは、`error`, `warning`, `cause` の3つのタイプで共有される
- `errorDetails: "auto"` 時、エラーが3件未満の場合のみ詳細を自動表示
- `errorsSpaceLimit` 関数によりスペース制限時は `details` が空文字に置換される
- 文字列エラーのサポートはwebpack 6で廃止予定

---

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

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

### 推奨読解順序

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

StatsError型の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行294-313: `KnownStatsError` 型定義。message, chunkName, moduleIdentifier, loc, details, stack, cause, errors, moduleTrace 等のフィールド |

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

compilation.errors 抽出処理の起点を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行910-942: `SIMPLE_EXTRACTORS.compilation.errors` - cachedGetErrorsでエラー取得、factory.createで構造化、errorsSpaceLimitで制限 |

**主要処理フロー**:
1. **行912**: `cachedGetErrors(compilation)` で全エラー取得
2. **行913-916**: `factory.create("compilation.errors", ...)` で構造化
3. **行919-926**: `errorDetails: "auto"` かつエラー3件以上で詳細フィルタ数カウント
4. **行935-939**: `errorsSpaceLimit` でスペース制限適用

#### Step 3: EXTRACT_ERRORの各抽出関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行414-448: `EXTRACT_ERROR._` - 基本情報（message, chunk, file, module, loc）の抽出 |
| 3-2 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行449-464: `EXTRACT_ERROR.ids` - chunkId, moduleIdの抽出 |
| 3-3 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行465-493: `EXTRACT_ERROR.moduleTrace` - モジュール依存トレースの生成 |
| 3-4 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行494-507: `EXTRACT_ERROR.errorDetails` - 詳細情報の条件付き抽出 |
| 3-5 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行508-512: `EXTRACT_ERROR.errorStack` - スタックトレースの条件付き抽出 |
| 3-6 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行513-528: `EXTRACT_ERROR.errorCause` - 原因チェーンの再帰抽出 |
| 3-7 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行529-543: `EXTRACT_ERROR.errorErrors` - AggregateErrorの集約エラー抽出 |

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

```
SIMPLE_EXTRACTORS.compilation.errors()
    |
    +-- cachedGetErrors(compilation)
    +-- factory.create("compilation.errors", rawErrors, context)
    |       |
    |       +-- EXTRACT_ERROR._()
    |       |       +-- error.message
    |       |       +-- error.chunk → chunkName, chunkEntry, chunkInitial
    |       |       +-- error.file
    |       |       +-- error.module → moduleIdentifier, moduleName
    |       |       +-- formatLocation(error.loc) → loc
    |       |
    |       +-- EXTRACT_ERROR.ids()
    |       |       +-- chunk.id → chunkId
    |       |       +-- chunkGraph.getModuleId() → moduleId
    |       |
    |       +-- EXTRACT_ERROR.moduleTrace()
    |       |       +-- moduleGraph.getIssuer() 再帰
    |       |       +-- factory.create("error.moduleTrace", ...)
    |       |
    |       +-- EXTRACT_ERROR.errorDetails()
    |       +-- EXTRACT_ERROR.errorStack()
    |       +-- EXTRACT_ERROR.errorCause()
    |       |       +-- factory.create("error.cause", cause, context)
    |       |
    |       +-- EXTRACT_ERROR.errorErrors()
    |               +-- factory.create("error.errors", errors, context)
    |
    +-- errorsSpaceLimit(factorizedErrors, errorsSpace)
```

### データフロー図

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

compilation.getErrors()    -->  EXTRACT_ERROR._()              -->  StatsError[]
  WebpackError[]           -->    message抽出                   -->    .message
  .chunk                   -->    chunkName/Entry/Initial抽出  -->    .chunkName等
  .module                  -->    moduleIdentifier/Name抽出    -->    .moduleIdentifier等
  .loc                     -->    formatLocation()             -->    .loc
  .details                 -->    errorDetails判定             -->    .details
  .stack                   -->    errorStack判定               -->    .stack
  .cause                   -->    再帰EXTRACT_ERROR            -->    .cause (StatsError)
  .errors (Aggregate)      -->    再帰EXTRACT_ERROR            -->    .errors (StatsError[])
  moduleGraph              -->    getIssuer()再帰              -->    .moduleTrace
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | ソース | EXTRACT_ERRORとcompilation.errors抽出処理 |
| StatsFactory.js | `lib/stats/StatsFactory.js` | ソース | データ変換パイプライン |
| Stats.js | `lib/Stats.js` | ソース | toJson() / toString() エントリーポイント |
| formatLocation.js | `lib/formatLocation.js` | ソース | エラー位置のフォーマット |
| Compilation.js | `lib/Compilation.js` | ソース | getErrors()メソッド提供 |
| WebpackError.js | `lib/WebpackError.js` | ソース | エラーの基底クラス |
