# 帳票設計書 7-Stats モジュールレポート

## 概要

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

### 本帳票の処理概要

Stats モジュールレポートは、ビルド対象のモジュール（ソースファイル）の名前、サイズ、依存関係、キャッシュ状態、最適化情報等の一覧を出力する帳票である。`SIMPLE_EXTRACTORS.compilation.modules` および `SIMPLE_EXTRACTORS.module` / `module$visible` により生成される。

**業務上の目的・背景**：ビルドに含まれる全モジュールを把握し、不要なモジュールの検出、重複モジュールの特定、モジュールサイズの最適化を行うために必要である。Tree-shaking効果の確認（usedExports / providedExports）や、ビルドキャッシュの効果測定にも利用される。

**帳票の利用シーン**：バンドル分析、モジュール依存関係の可視化、Tree-shaking効果の確認、ビルドパフォーマンス分析、デバッグ時のモジュール特定に利用される。

**主要な出力内容**：
1. モジュール基本情報（type, moduleType, layer, identifier, name, size, sizes）
2. ビルド状態（built, codeGenerated, buildTimeExecuted, cached）
3. モジュールグラフ情報（index, preOrderIndex, postOrderIndex, depth）
4. 依存関係（issuer, issuerName, issuerPath, reasons）
5. 最適化情報（usedExports, providedExports, optimizationBailout）
6. チャンク関連（id, chunks, orphan）
7. ネストモジュール（modules）
8. プロファイル情報（profile）
9. ソースコード（source）

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

**帳票の利用者**：フロントエンド開発者、バンドル分析ツール（webpack-bundle-analyzer等）。

## 帳票種別

モジュール一覧出力

## 利用画面

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

## 出力形式

### 基本仕様

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

## 帳票レイアウト

### レイアウト概要

StatsModule型の配列として出力される。

```
{
    "type":               "module",
    "moduleType":         モジュールタイプ,
    "layer":              レイヤー名,
    "identifier":         モジュール識別子,
    "name":               モジュール名,
    "size":               総サイズ,
    "sizes":              ソースタイプ別サイズ,
    "built":              ビルド済みか,
    "codeGenerated":      コード生成済みか,
    "cached":             キャッシュか,
    "id":                 モジュールID,
    "chunks":             所属チャンクID配列,
    "issuer":             依存元モジュール識別子,
    "issuerName":         依存元モジュール名,
    "issuerPath":         依存元パス,
    "reasons":            依存理由配列,
    "usedExports":        使用エクスポート,
    "providedExports":    提供エクスポート,
    "optimizationBailout": 最適化中止理由,
    "depth":              依存深度,
    "modules":            ネストモジュール,
    "profile":            プロファイル情報,
    "source":             ソースコード
}
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | type | 常に "module" | 固定値 | 文字列 |
| 2 | moduleType | モジュールタイプ | module.type | 文字列 |
| 3 | layer | レイヤー名 | module.layer | 文字列/null |
| 4 | identifier | モジュール識別子 | module.identifier() | 文字列 |
| 5 | name | モジュール名 | module.readableIdentifier() | 文字列 |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | size | 総サイズ | module.size() | 数値（バイト） | - |
| 2 | sizes | ソースタイプ別サイズ | module.getSourceTypes() + module.size(type) | Record<string, number> | - |
| 3 | built | ビルド済みか | compilation.builtModules.has(module) | 真偽値 | - |
| 4 | codeGenerated | コード生成済みか | compilation.codeGeneratedModules.has(module) | 真偽値 | - |
| 5 | buildTimeExecuted | ビルド時実行済みか | compilation.buildTimeExecutedModules.has(module) | 真偽値 | - |
| 6 | cached | キャッシュか | !built && !codeGenerated | 真偽値 | - |
| 7 | cacheable | キャッシュ可能か | module.buildInfo.cacheable | 真偽値 | - |
| 8 | optional | オプショナルか | module.isOptional(moduleGraph) | 真偽値 | - |
| 9 | orphan | 孤立モジュールか | chunkGraph.getNumberOfModuleChunks(module) === 0 | 真偽値 | - |
| 10 | dependent | 依存モジュールか | !rootModules.has(module) | 真偽値 | - |
| 11 | depth | 依存深度 | moduleGraph.getDepth(module) | 数値 | - |
| 12 | reasons | 依存理由 | moduleGraph.getIncomingConnections(module) | StatsModuleReason[] | - |
| 13 | usedExports | 使用エクスポート | moduleGraph.getUsedExports(module, runtime) | boolean/null/string[] | - |
| 14 | providedExports | 提供エクスポート | moduleGraph.getProvidedExports(module) | string[]/null | - |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | filteredModules | フィルタされたモジュール数 | spaceLimited() | 数値 |
| 2 | filteredReasons | フィルタされた依存理由数 | spaceLimited() | 数値 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| cachedModules | キャッシュ済みモジュールの詳細表示有効/無効 | No |
| modulesSpace | モジュール表示のスペース制限 | No |
| nestedModulesSpace | ネストモジュール表示のスペース制限 | No |
| reasonsSpace | 依存理由表示のスペース制限 | No |
| ids | ID情報の出力有効/無効 | No |
| moduleAssets | モジュールアセットの出力有効/無効 | No |
| reasons | 依存理由の出力有効/無効 | No |
| usedExports | 使用エクスポートの出力有効/無効 | No |
| providedExports | 提供エクスポートの出力有効/無効 | No |
| optimizationBailout | 最適化中止理由の出力有効/無効 | No |
| depth | 依存深度の出力有効/無効 | No |
| nestedModules | ネストモジュールの出力有効/無効 | No |
| source | ソースコードの出力有効/無効 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | depth | 昇順 |
| 2 | preOrderIndex | 昇順 |
| 3 | identifier | 昇順 |

### 改ページ条件

N/A

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| Compilation | モジュール一覧 | compilation.modules |
| ModuleGraph | 依存関係グラフ | compilation.moduleGraph |
| ChunkGraph | チャンク-モジュール関係 | compilation.chunkGraph |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| cached | !built && !codeGenerated | - | 論理演算 |
| errors | countIterable(module.getErrors()) | なし | エラー数 |
| warnings | countIterable(module.getWarnings()) | なし | 警告数 |
| failed | errorsCount > 0 | - | ビルド失敗判定 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[SIMPLE_EXTRACTORS.compilation.modules] --> B[compilation.modulesをArray化]
    B --> C[factory.create compilation.modules 呼び出し]
    C --> D[MODULES_SORTER で depth/preOrderIndex/identifier順ソート]
    D --> E[module._ で基本情報抽出 type/size/built/cached]
    E --> F{cached && !cachedModules?}
    F -->|Yes| G[visible情報スキップ]
    F -->|No| H[module$visible で詳細情報抽出]
    H --> I[identifier/name/issuer/reasons/usedExports等]
    I --> J[spaceLimited でスペース制限]
    J --> K[StatsModule配列返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| モジュールなし | compilation.modulesが空 | 空配列返却 | ビルド設定を確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | モジュール数千〜数万 |
| 目標出力時間 | モジュール数に比例 |
| 同時出力数上限 | 1 |

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

モジュール識別子（identifier）と名前（name）にはファイルシステムの絶対パスが含まれる。`source: true` の場合、ソースコードそのものが出力に含まれるため、公開環境での利用に注意が必要。

## 備考

- `module$visible` は `cachedModules: true` またはビルド/コード生成されたモジュールのみに適用
- `orphan` フラグは `module.modules[].module$visible` の場合は設定されない（ネストモジュールは親の判定に従う）
- `rootModules` はチャンクのルートモジュール（chunkGraph.getChunkRootModules）で、dependent判定に使用
- `issuerPath` はモジュールの発行元を再帰的にたどった経路

---

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

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

### 推奨読解順序

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

StatsModule型の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行154-196: `KnownStatsModule` 型定義。moduleType, identifier, name, size, sizes, built, cached, issuer, reasons, usedExports 等のフィールド |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行852-859: `SIMPLE_EXTRACTORS.compilation.modules` - compilation.modulesをArray化し、factory.create→spaceLimited |

#### Step 3: module / module$visible 抽出処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行1226-1259: `SIMPLE_EXTRACTORS.module._` - moduleType, layer, size, sizes, built, codeGenerated, cached |
| 3-2 | DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | 行1260-1418: `SIMPLE_EXTRACTORS.module$visible` - identifier, name, index, cacheable, orphan, issuer, reasons, usedExports, providedExports, optimizationBailout, depth, nestedModules, source |

**主要処理フロー**:
1. **行1230-1233**: built / codeGenerated / buildTimeExecuted 判定
2. **行1236-1238**: sizes計算（ソースタイプ別）
3. **行1249**: cached = !built && !codeGenerated
4. **行1261-1316**: module$visible._ - identifier, name, issuerPath, errors, warnings
5. **行1339-1356**: reasons - moduleGraph.getIncomingConnections → spaceLimited
6. **行1357-1389**: usedExports / providedExports / optimizationBailout
7. **行1393-1411**: nestedModules - module.modules配列の再帰処理

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

```
SIMPLE_EXTRACTORS.compilation.modules()
    |
    +-- [...compilation.modules] Array化
    +-- factory.create("compilation.modules", array, context)
    |       |
    |       +-- MODULES_SORTER (depth → preOrderIndex → identifier)
    |       +-- module._()
    |       |       +-- moduleType, layer, size, sizes
    |       |       +-- built, codeGenerated, buildTimeExecuted, cached
    |       |       +-- module$visible()（cachedでない場合）
    |       |               +-- identifier, name, nameForCondition
    |       |               +-- index, preOrderIndex, postOrderIndex
    |       |               +-- cacheable, optional, orphan, dependent
    |       |               +-- issuer, issuerName, issuerPath
    |       |               +-- failed, errors, warnings
    |       |               +-- profile
    |       |               +-- ids → id, issuerId, chunks
    |       |               +-- moduleAssets → assets
    |       |               +-- reasons → StatsModuleReason[]
    |       |               +-- usedExports
    |       |               +-- providedExports
    |       |               +-- optimizationBailout
    |       |               +-- depth
    |       |               +-- nestedModules → modules[]
    |       |               +-- source → source
    |
    +-- spaceLimited(groupedModules, modulesSpace)
```

### データフロー図

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

compilation.modules          -->  module._()                     -->  StatsModule[]
  Module[]                   -->    size / sizes計算              -->    .size, .sizes
compilation.builtModules     -->    built判定                     -->    .built
compilation.codeGeneratedMod -->    codeGenerated判定             -->    .codeGenerated
moduleGraph                  -->    module$visible._()            -->    .identifier, .name
  .getIssuer()               -->    issuerPath構築                -->    .issuerPath
  .getIncomingConnections()  -->    reasons構築                   -->    .reasons
  .getUsedExports()          -->    usedExports取得               -->    .usedExports
  .getProvidedExports()      -->    providedExports取得           -->    .providedExports
  .getDepth()                -->    depth取得                     -->    .depth
chunkGraph                   -->    id / chunks取得               -->    .id, .chunks
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DefaultStatsFactoryPlugin.js | `lib/stats/DefaultStatsFactoryPlugin.js` | ソース | module / module$visible / moduleIssuer 抽出処理 |
| StatsFactory.js | `lib/stats/StatsFactory.js` | ソース | データ変換パイプライン |
| Stats.js | `lib/Stats.js` | ソース | toJson() / toString() エントリーポイント |
| DefaultStatsPrinterPlugin.js | `lib/stats/DefaultStatsPrinterPlugin.js` | ソース | MODULE_SIMPLE_PRINTERSでテキスト表示 |
| Compilation.js | `lib/Compilation.js` | ソース | modules / builtModules / codeGeneratedModules 提供 |
| ModuleGraph.js | `lib/ModuleGraph.js` | ソース | モジュール間依存関係グラフ |
| ChunkGraph.js | `lib/ChunkGraph.js` | ソース | チャンク-モジュール関係 |
