# 機能設計書 54-ビルド統計生成

## 概要

本ドキュメントは、webpackにおけるビルド統計生成機能（DefaultStatsFactoryPlugin / StatsFactory）の設計仕様を記述する。コンパイル結果からモジュール、チャンク、アセット、エラー、警告等の詳細な統計情報オブジェクトを構築するファクトリパターンベースのパイプライン処理である。

### 本機能の処理概要

**業務上の目的・背景**：webpackのビルド結果を分析・可視化するためには、構造化された統計データが必要である。ビルド統計生成機能は、コンパイルオブジェクトからモジュール依存関係、チャンクサイズ、アセット情報、エラー・警告、プロファイリングデータ等を抽出し、統一された統計オブジェクト（StatsCompilation）を生成する。このデータはCLI出力、webpack-bundle-analyzer、webpack-dev-server等で利用される。

**機能の利用シーン**：ビルド完了後のCLI出力、`stats.toJson()`によるJSON統計出力、バンドルサイズ分析ツールとの連携、CI/CDパイプラインでのビルド品質チェックに利用される。

**主要な処理内容**：
1. Compilationオブジェクトから統計データを抽出するフックパイプラインを構築する
2. 各データ種別（compilation, asset, chunk, module, error等）について、extract/filter/sort/merge/resultの各フェーズを実行する
3. 配列データに対してはフィルタリング、ソート、グルーピング、件数制限を適用する
4. 階層的な型システム（"compilation.modules[].module"等）でフック解決を行う
5. 統計オブジェクト全体をStatsCompilation型として返却する

**関連システム・外部連携**：StatsPrinter（No.55）と連携し、統計オブジェクトを人間可読な文字列に整形する。webpack-bundle-analyzer等の外部ツールはstats.toJson()の出力を消費する。

**権限による制御**：特になし。stats設定オプションにより出力レベル・内容を制御する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はUIを持たない内部処理であり、直接関連する画面は存在しない |

## 機能種別

データ抽出処理 / レポート生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | string | Yes | 抽出対象の型名（"compilation", "module"等） | StatsFactory内部で解決 |
| data | any | Yes | 抽出対象のデータ（Compilation, Module等） | 型に応じた処理 |
| baseContext | StatsFactoryContext | Yes | コンテキスト情報（compilation, makePathsRelative等） | - |

### 入力データソース

- Compilationオブジェクト: モジュール、チャンク、アセット、エラー、警告等を含むコンパイル結果
- NormalizedStatsOptions: 統計出力オプション（表示項目の制御）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| hash | string | コンパイルハッシュ |
| version | string | webpackバージョン |
| time | number | ビルド所要時間（ms） |
| builtAt | number | ビルド完了時刻（UNIX timestamp） |
| assets | StatsAsset[] | アセット一覧（ファイル名、サイズ、チャンク情報等） |
| chunks | StatsChunk[] | チャンク一覧（ID、名前、サイズ、モジュール等） |
| modules | StatsModule[] | モジュール一覧（ID、名前、サイズ、依存関係等） |
| entrypoints | Record<string, StatsChunkGroup> | エントリポイント情報 |
| errors | StatsError[] | エラー一覧 |
| warnings | StatsError[] | 警告一覧 |
| errorsCount | number | エラー件数 |
| warningsCount | number | 警告件数 |

### 出力先

StatsCompilationオブジェクトとしてメモリ上に生成。JSON出力またはStatsPrinterへ渡される。

## 処理フロー

### 処理シーケンス

```
1. StatsFactory.create("compilation", compilationData, baseContext) 呼び出し
   └─ 型が"compilation"の場合、オブジェクト抽出パスに入る
2. extractフック実行
   └─ DefaultStatsFactoryPluginが各フィールド（hash, version, assets等）を抽出
3. 配列フィールド（modules, chunks, errors等）の場合
   └─ filterフック → sortフック → filterSortedフック → 各アイテムのcreate再帰呼び出し
4. グルーピング・件数制限
   └─ groupResultsフック → sortResultsフック → filterResultsフック
5. 結果マージ
   └─ mergeフック → resultフック
6. StatsCompilationオブジェクトとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[StatsFactory.create呼び出し] --> B{データは配列?}
    B -->|Yes| C[filterフックで項目フィルタ]
    C --> D[sortフックでソート]
    D --> E[filterSortedフック]
    E --> F[各アイテムにcreate再帰呼び出し]
    F --> G[sortResultsフック]
    G --> H[groupResultsフックでグルーピング]
    H --> I[filterResultsフック]
    I --> J[mergeフック]
    B -->|No| K[extractフックでフィールド抽出]
    J --> L[resultフック]
    K --> L
    L --> M[統計オブジェクト返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-01 | 階層的フック解決 | "compilation.modules[].module"のように型パスを分解し、各レベルでフックを探索する | StatsFactory._getAllLevelHooks |
| BR-54-02 | キャッシュクリア | create呼び出し完了後にフックキャッシュをクリアする | _inCreateフラグがfalseになる時 |
| BR-54-03 | アイテムファクトリ委譲 | getItemFactoryフックで子アイテム用の別ファクトリを取得可能 | 配列アイテムの処理時 |
| BR-54-04 | スマートグルーピング | smartGrouping関数でモジュールを種別・パス等でグループ化する | groupResultsフック |

### 計算ロジック

フック解決: 型パス"a.b.c"に対して、"a.b.c" → "b.c" → "c"の順でHookMapを探索し、最初に見つかったフックを実行する。配列処理では、フィルタ→ソート→アイテム生成→結果ソート→グルーピング→結果フィルタ→マージ→結果の順序でパイプライン処理を行う。

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | 本機能はデータベースを使用しない |

### テーブル別操作詳細

該当なし（インメモリ処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本機能自体はエラーをスローしない | extractフック内で例外が発生した場合はCompilationレベルでハンドリング |

### リトライ仕様

該当なし。

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

該当なし（同期的なインメモリ処理）

## パフォーマンス要件

- 大規模プロジェクトでは統計生成に時間がかかる場合がある
- stats: 'minimal'やstats: 'errors-only'で出力項目を限定することで高速化可能
- modulesSpaceやassetsSpace等のSpace系オプションで表示件数を制限可能

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

- 統計出力にはファイルパスやモジュール名が含まれるため、公開環境では情報漏洩に注意
- stats.toJson()の結果を外部に送信する場合はセンシティブ情報の除去を検討

## 備考

- StatsFactory(No.54) → StatsPrinter(No.55)の2段階アーキテクチャ
- DefaultStatsFactoryPluginは3000行超の大規模プラグインであり、全統計項目の抽出ロジックを含む

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | StatsFactory.js | `lib/stats/StatsFactory.js` | StatsFactoryHooksの型定義とHookMapベースのフックシステムを理解する |

**読解のコツ**: HookMap<SyncBailHook>パターンを理解することが重要。各フック（extract, filter, sort等）は型パス（"compilation", "compilation.modules[]"等）をキーとするHookMapであり、プラグインがタップして処理を登録する。

- **78-91行目**: StatsFactoryHooksの型定義 - extract, filter, sort, filterSorted, groupResults, sortResults, filterResults, merge, result, getItemName, getItemFactoryの11種類
- **98-133行目**: StatsFactoryコンストラクタ - HookMapの初期化とキャッシュマップの構築
- **44-57行目**: KnownStatsFactoryContextの型定義 - compilation, makePathsRelative, rootModules等

#### Step 2: ファクトリの実行フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | StatsFactory.js | `lib/stats/StatsFactory.js` | create()メソッドと_create()メソッドの実行フロー |

**主要処理フロー**:
1. **235-248行目**: `create()`メソッド - _inCreateフラグ管理とキャッシュクリア
2. **259-264行目**: `_create()`メソッド - コンテキスト構築
3. **265-386行目**: 配列データの場合のパイプライン処理（filter→sort→filterSorted→create再帰→sortResults→groupResults→filterResults→merge→result）
4. **387-402行目**: オブジェクトデータの場合のextract→result

#### Step 3: DefaultStatsFactoryPluginの抽出ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 統計項目の抽出ロジック |

**主要処理フロー**:
- **66-100行目**: StatsCompilation型定義 - 出力オブジェクトの構造
- extractフックで各フィールド（hash, version, time, assets, chunks, modules, errors, warnings等）を抽出
- filterフックでNormalizedStatsOptionsに基づいてフィルタリング
- sortフックでcomparatorsを使用してソート

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

```
Compilation.getStats()
    │
    └─ Stats.toJson(options)
           │
           └─ StatsFactory.create("compilation", compilation, baseContext)
                  │
                  ├─ hooks.extract("compilation") ──▶ DefaultStatsFactoryPlugin
                  │      ├─ hash, version, time, builtAt 抽出
                  │      ├─ assets 抽出 → create("compilation.assets[]", ...)
                  │      ├─ chunks 抽出 → create("compilation.chunks[]", ...)
                  │      ├─ modules 抽出 → create("compilation.modules[]", ...)
                  │      ├─ errors 抽出 → create("compilation.errors[]", ...)
                  │      └─ warnings 抽出 → create("compilation.warnings[]", ...)
                  │
                  ├─ hooks.filter / sort / groupResults
                  │      └─ smartGrouping() でグルーピング
                  │
                  └─ hooks.result("compilation")
                         └─ StatsCompilation オブジェクト返却
```

### データフロー図

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

Compilation ───────────────▶ StatsFactory.create() ─────────▶ StatsCompilation
  ├─ modules                   ├─ extract: 各フィールド抽出         ├─ hash
  ├─ chunks                    ├─ filter: オプションベースフィルタ   ├─ version
  ├─ assets                    ├─ sort: 比較関数でソート             ├─ assets[]
  ├─ errors                    ├─ groupResults: グルーピング         ├─ chunks[]
  ├─ warnings                  └─ result: 最終オブジェクト構築      ├─ modules[]
  └─ entrypoints                                                    ├─ errors[]
                                                                     └─ warnings[]

NormalizedStatsOptions ────▶ filterフック制御 ──────────────▶ 表示項目の制御
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| StatsFactory.js | `lib/stats/StatsFactory.js` | ソース | 統計ファクトリ本体（HookMapベースのパイプライン） |
| DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | ソース | デフォルト統計抽出プラグイン（3000行超） |
| comparators.js | `lib/util/comparators.js` | ソース | ソート用比較関数群 |
| smartGrouping.js | `lib/util/smartGrouping.js` | ソース | スマートグルーピングユーティリティ |
| identifier.js | `lib/util/identifier.js` | ソース | パス相対化ユーティリティ |
