# 帳票設計書 19-webpack-stats.json

## 概要

本ドキュメントは、Next.jsビルドプロセスにおいて生成される `webpack-stats.json`（Webpackビルド統計情報）の設計仕様を定義する。本ファイルは、Webpackビルドの統計情報（モジュール・チャンク・アセット情報・エントリポイント等）を含むJSONであり、バンドル解析やデバッグ目的で使用される。

### 本帳票の処理概要

本ファイルは、Turbopack使用時に `TurbopackManifestLoader` によって生成されるJSON形式の統計情報ファイルである。各ページのビルド統計を個別に収集し、マージして最終的な統計ファイルとして出力する。環境変数 `TURBOPACK_STATS` が設定されている場合にのみ生成される。

**業務上の目的・背景**：Next.jsアプリケーションのバンドルサイズ最適化やパフォーマンス分析において、モジュール・チャンク・アセットの詳細情報が必要となる。webpack-stats.json は標準的なWebpack統計情報フォーマットに準拠しており、既存のバンドル解析ツール（webpack-bundle-analyzer等）との互換性を提供する。Turbopackではこの情報をWebpack互換形式で出力することで、移行期間中のツールチェーン互換性を確保する。

**帳票の利用シーン**：Turbopackを使用したビルドで `TURBOPACK_STATS` 環境変数が設定されている場合に生成される。バンドルサイズ分析、モジュール依存関係の調査、チャンク分割の最適化検討時に参照される。

**主要な出力内容**：
1. バージョン情報（`'Turbopack'`）
2. エントリポイント情報（各ページのチャンクグループ）
3. アセット情報（出力されたファイルのリスト）
4. チャンク情報（コード分割されたチャンクのリスト）
5. モジュール情報（バンドルされたモジュールのリスト）

**帳票の出力タイミング**：Turbopackビルド時に `TurbopackManifestLoader.writeManifests` メソッド内で `writeWebpackStats` が呼ばれ、`TURBOPACK_STATS` 環境変数が設定されている場合のみ出力される。

**帳票の利用者**：開発者がバンドル解析ツールを使用してアプリケーションのバンドルサイズを分析する際に利用。Next.jsフレームワーク内部では直接的な利用はない。

## 帳票種別

診断レポート（JSON形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIコマンド | `next build` (Turbopack) | TURBOPACK_STATS環境変数設定時 |
| N/A | 開発サーバー | `next dev` (Turbopack) | TURBOPACK_STATS環境変数設定時 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON (.json) |
| 用紙サイズ | N/A（データファイル） |
| 向き | N/A |
| ファイル名 | `webpack-stats.json` |
| 出力方法 | ファイルシステムへの書き込み |
| 文字コード | UTF-8 |

### JSON形式（Webpack Stats互換）

```json
{
  "version": "Turbopack",
  "entrypoints": {
    "pages/index": {
      "name": "pages/index",
      "chunks": ["chunk-abc"],
      "assets": [{ "name": "static/chunks/pages/index.js" }]
    }
  },
  "assets": [
    { "name": "static/chunks/main.js", "size": 12345 }
  ],
  "chunks": [
    { "id": "chunk-abc", "names": ["pages/index"], "files": ["static/chunks/pages/index.js"] }
  ],
  "modules": [
    { "id": "module-1", "name": "./pages/index.tsx", "chunks": ["chunk-abc"], "size": 1234 }
  ]
}
```

## 帳票レイアウト

### レイアウト概要

Webpack Stats 互換のJSON構造。

```
┌─────────────────────────────────────┐
│  version: "Turbopack"               │
├─────────────────────────────────────┤
│  entrypoints: {                     │
│    [name]: StatsChunkGroup          │
│  }                                  │
├─────────────────────────────────────┤
│  assets: StatsAsset[]               │
├─────────────────────────────────────┤
│  chunks: StatsChunk[]               │
├─────────────────────────────────────┤
│  modules: StatsModule[]             │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | version | バージョン識別子 | 固定値 | `"Turbopack"` |
| 2 | entrypoints | エントリポイント情報 | 各ページの部分マニフェストをマージ | `Record<string, StatsChunkGroup>` |
| 3 | assets | アセット情報 | 各ページの部分マニフェストをマージ（名前で重複排除） | `StatsAsset[]` |
| 4 | chunks | チャンク情報 | 各ページの部分マニフェストをマージ（IDで重複排除） | `StatsChunk[]` |
| 5 | modules | モジュール情報 | 各ページの部分マニフェストをマージ（IDで重複排除、チャンクリストはマージ） | `StatsModule[]` |

### 明細部

N/A（Webpack Stats標準形式）

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| Turbopack使用 | Turbopackバンドラーを使用していること | Yes |
| TURBOPACK_STATS環境変数 | `process.env.TURBOPACK_STATS` が設定されていること | Yes |

### ソート順

N/A（マージ時の登録順）

### 改ページ条件

N/A

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

N/A

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| entrypointsマージ | 同一キーが存在しない場合のみ追加 | N/A | 先勝ちマージ |
| assetsマージ | asset.nameで重複チェック。未存在時のみ追加 | N/A | Mapベースの重複排除 |
| chunksマージ | chunk.idで重複チェック。未存在時のみ追加 | N/A | Mapベースの重複排除 |
| modulesマージ | module.idで重複チェック。既存時はchunksリストをマージ | N/A | IDベースの重複排除＋チャンクリスト統合 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Turbopackビルド] --> B[各ページのStats収集]
    B --> C[loadWebpackStats]
    C --> D[writeManifests呼び出し]
    D --> E{TURBOPACK_STATS設定あり?}
    E -->|Yes| F[writeWebpackStats]
    E -->|No| G[スキップ]
    F --> H[mergeWebpackStats]
    H --> I[entrypoints/assets/chunks/modulesマージ]
    I --> J[.next/server/webpack-stats.json出力]
    J --> K[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| Stats未生成 | ページの部分Statsファイルが存在しない | ファイル読み込みエラー | ビルドの再実行 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | プロジェクトの全モジュール・チャンク数（大規模プロジェクトでは数千件） |
| 目標出力時間 | マージ処理のため、モジュール数に比例（通常は数秒以内） |
| 同時出力数上限 | 1 |

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

モジュールパス、アセット名などビルドの内部構造情報が含まれる。プロジェクトのソースコード構造が推測可能になるため、本番環境での公開は避けるべき。デバッグ・分析用途に限定して使用する。

## 備考

- 定数名 `WEBPACK_STATS` は `constants.ts` の88行目で定義（値: `'webpack-stats.json'`）。
- Turbopack使用時のみ生成される。Webpack使用時は標準のWebpack stats機能を直接使用する。
- `mergeWebpackStats` メソッド（manifest-loader.ts 390-448行目）でモジュールのチャンクリストマージが行われる点が特徴的。同一モジュールが複数エンドポイントで使用される場合、チャンクリストが統合される。
- `version` フィールドは `'Turbopack'` 固定値で、Webpack標準の数値バージョンとは異なる。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | 7-11行目: `StatsAsset`, `StatsChunk`, `StatsChunkGroup`, `StatsModule`, `WebpackStats` 型のインポート |
| 1-2 | constants.ts | `packages/next/src/shared/lib/constants.ts` | 88行目: `WEBPACK_STATS` 定数（値: `'webpack-stats.json'`） |

**読解のコツ**: 型定義はWebpackの標準 `webpack` パッケージからインポートされている（`StatsCompilation as WebpackStats`）。Turbopackが生成する形式はWebpack互換だが、versionフィールドが `'Turbopack'` となる。

#### Step 2: ロード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | 383-388行目: `loadWebpackStats` メソッド。ページごとの部分Statsを読み込みManifestsMapに格納 |

#### Step 3: マージ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | 390-448行目: `mergeWebpackStats` メソッド。entrypoints, assets, chunks, modulesそれぞれのマージロジック |

**主要処理フロー**:
- **391-394行目**: Map初期化（entrypoints, assets, chunks, modules）
- **396-403行目**: entrypointsのマージ（先勝ち）
- **405-411行目**: assetsのマージ（名前で重複排除）
- **413-419行目**: chunksのマージ（IDで重複排除）
- **421-438行目**: modulesのマージ（IDで重複排除＋チャンクリスト統合）
- **440-448行目**: 最終結果構築。version は `'Turbopack'`

#### Step 4: 書き込み処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | 351-359行目: `writeWebpackStats` メソッド。変更検知付きの書き込み |
| 4-2 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | 912-914行目: `writeManifests` メソッド内。`TURBOPACK_STATS` 環境変数チェック |

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

```
TurbopackManifestLoader.writeManifests()
    |
    +-- if (process.env.TURBOPACK_STATS != null)
            |
            +-- writeWebpackStats()
                    |
                    +-- webpackStats.takeChanged() [変更検知]
                    +-- mergeWebpackStats(webpackStats.values())
                    |       +-- entrypointsマージ
                    |       +-- assetsマージ（名前重複排除）
                    |       +-- chunksマージ（ID重複排除）
                    |       +-- modulesマージ（ID重複排除＋チャンク統合）
                    |
                    +-- writeFileAtomic(path, JSON.stringify())
```

### データフロー図

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

Turbopack per-page         TurbopackManifestLoader             .next/server/webpack-stats.json
  stats files          --> mergeWebpackStats()              -->
                           (マージ・重複排除)
                           TURBOPACK_STATS環境変数チェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | ソース | Stats読み込み・マージ・書き込み処理 |
| constants.ts | `packages/next/src/shared/lib/constants.ts` | ソース | WEBPACK_STATS定数定義 |
