# 帳票設計書 38-client-build-manifest.json

## 概要

本ドキュメントは、Turbopack使用時に生成されるクライアントビルドマニフェスト `client-build-manifest.json` の設計仕様を定義する。

### 本帳票の処理概要

本帳票は、Turbopack使用時に各ページ/ルートのクライアントサイドアセット情報を管理する部分マニフェストである。TurbopackManifestLoaderがページごとの部分マニフェストを読み込み、マージして最終的なクライアントビルドマニフェスト（`_buildManifest.js`）を生成するための中間データとして使用される。

**業務上の目的・背景**：Turbopackではwebpackと異なり、ページごとに個別のマニフェストが生成される。これらの部分マニフェストを統合して、クライアントサイドのルーティングやコード分割に必要なアセット情報を提供する。

**帳票の利用シーン**：(1) Turbopackビルド時の中間マニフェスト、(2) ページ遷移時のクライアントサイドアセットロード制御、(3) `_buildManifest.js` の生成元データ。

**主要な出力内容**：
1. ページパスとクライアントアセットのマッピング
2. リライト情報（`__rewrites`）
3. ソート済みページキー一覧（`sortedPages`）

**帳票の出力タイミング**：Turbopackでのビルドまたは開発サーバー起動時に、各ページのコンパイル完了後にTurbopackManifestLoaderによって読み込まれ、統合マニフェストの生成に使用される。

**帳票の利用者**：Next.jsフレームワーク内部（TurbopackManifestLoader）。

## 帳票種別

中間マニフェスト（JSON形式のTurbopack内部データ）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | 内部処理 | N/A | Turbopackコンパイル時に自動生成 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON |
| 用紙サイズ | N/A（ファイル出力） |
| 向き | N/A |
| ファイル名 | `client-build-manifest.json` |
| 出力方法 | Turbopackによるファイルシステムへの書き込み |
| 文字コード | UTF-8 |

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

JSONオブジェクトとして、ページごとのクライアントアセット情報を含む。統合後は `_buildManifest.js` として以下のような形式でクライアントに提供される。

```javascript
self.__BUILD_MANIFEST = {
  "__rewrites": { "beforeFiles": [], "afterFiles": [], "fallback": [] },
  "sortedPages": ["/", "/about", "/blog/[slug]"],
  "/": ["static/chunks/pages/index-abc123.js"],
  "/about": ["static/chunks/pages/about-def456.js"]
};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
```

### ヘッダー部

N/A

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | __rewrites | リライト設定 | CustomRoutes['rewrites'] | JSONオブジェクト | N/A |
| 2 | sortedPages | ソート済みページキー | getSortedRoutes(pagesKeys) | 文字列配列 | N/A |
| 3 | {pagePath} | ページごとのアセットファイル配列 | Turbopackコンパイル結果 | 文字列配列 | N/A |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| Turbopack使用 | Turbopackでビルドまたは開発サーバー実行 | Yes |
| ページ存在 | 少なくとも1つのページが存在 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | sortedPages | getSortedRoutesによるルートソート |

### 改ページ条件

N/A

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

N/A

### 参照テーブル一覧

N/A

### テーブル別参照項目詳細

N/A

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| sortedPages | getSortedRoutes(pagesKeys) | N/A | Next.jsルートソートアルゴリズム |
| __rewrites | normalizeRewritesForBuildManifest(rewrites) | N/A | リライト情報の正規化 |
| 最終出力パス（dev） | `static/{buildId}/_buildManifest.js` | N/A | 開発時 |
| 最終出力パス（prod+skew） | `static/_buildManifest.js` | N/A | skew protection有効時 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Turbopack ページコンパイル] --> B[部分 client-build-manifest.json 出力]
    B --> C[TurbopackManifestLoader.loadClientBuildManifest]
    C --> D[clientBuildManifests Map に格納]
    D --> E[writeManifests 呼び出し]
    E --> F[writeClientBuildManifest]
    F --> G[mergeClientBuildManifests でマージ]
    G --> H[self.__BUILD_MANIFEST = ... の JS 生成]
    H --> I[_buildManifest.js 書き込み]
    I --> J[_ssgManifest.js 書き込み（空プレースホルダー）]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| マニフェスト読み込みエラー | 部分マニフェストが見つからない | ファイル読み込みエラー | ページのコンパイルが完了しているか確認 |
| ファイル書き込みエラー | ディスク容量不足等 | ファイルシステムエラー | ディスク容量確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | ページ数に比例（数十〜数千） |
| 目標出力時間 | 即時（JSON文字列化・マージのみ） |
| 同時出力数上限 | 1 |

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

クライアントビルドマニフェストにはページパスとアセットファイル名が含まれるが、機密情報は含まない。`_buildManifest.js` は `/_next/static/` 配下に配置され、ブラウザからアクセス可能。リライト設定もクライアント側に公開されるため、URLマッピングルールが閲覧可能となる。

## 備考

- 定数名: `TURBOPACK_CLIENT_BUILD_MANIFEST`（`packages/next/src/shared/lib/constants.ts` 行105）
- 部分マニフェストはTurbopackが `server/{type}/{page}/client-build-manifest.json` に出力
- 統合後の `_buildManifest.js` がクライアントに提供される最終形
- `_ssgManifest.js` も同時に出力される（空のプレースホルダー、本番ビルド後に実データで上書き）
- 開発モードでは `takeChanged` メソッドにより変更があった場合のみ書き出しが行われる（不要な書き込みの回避）
- `self.__BUILD_MANIFEST_CB` コールバックパターンにより非同期ロード対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/next/src/shared/lib/constants.ts` | TURBOPACK_CLIENT_BUILD_MANIFEST定数（行105） |
| 1-2 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | ClientBuildManifest型のインポート（行56） |

**読解のコツ**: client-build-manifest.jsonは中間形式であり、最終的に `_buildManifest.js` に変換されてクライアントに提供される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | loadClientBuildManifest（行368-381）で部分マニフェスト読み込み |

**主要処理フロー**:
1. **行368-381**: readPartialManifestContentで部分マニフェストを読み込み
2. **行567-638**: writeClientBuildManifestでマージ・書き出し
3. **行474-487**: mergeClientBuildManifestsでマージ処理

#### Step 3: マージ・書き出し処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | writeClientBuildManifest（行567-638） |

**主要処理フロー**:
- **行572-579**: リライト情報の正規化
- **行581-589**: ページキーの収集とソート
- **行591-609**: 出力パスの決定（deploymentId、dev環境の考慮）
- **行618-627**: mergeClientBuildManifestsでマージし、JS文字列を生成
- **行629-635**: `_buildManifest.js` と `_ssgManifest.js` の書き込み

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

```
Turbopack コンパイル
    │
    └─ TurbopackManifestLoader
           ├─ loadClientBuildManifest() → 部分マニフェスト読み込み
           │
           └─ writeManifests()
                  └─ writeClientBuildManifest()
                         ├─ normalizeRewritesForBuildManifest()
                         ├─ getSortedRoutes()
                         ├─ mergeClientBuildManifests()
                         ├─ writeFileAtomic(_buildManifest.js)
                         └─ writeFileAtomic(_ssgManifest.js)
```

### データフロー図

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

Turbopack 部分マニフェスト ───▶ loadClientBuildManifest()
(server/{type}/{page}/            ↓
 client-build-manifest.json)   clientBuildManifests Map
                                  ↓
rewrites 設定 ─────────────────▶ writeClientBuildManifest()
                                  ├─ マージ
                                  ├─ JS文字列生成              ──▶ _buildManifest.js
                                  └─ 空プレースホルダー         ──▶ _ssgManifest.js
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | ソース | TurbopackManifestLoader・マニフェスト読み込み・マージ・書き出し |
| constants.ts | `packages/next/src/shared/lib/constants.ts` | ソース | TURBOPACK_CLIENT_BUILD_MANIFEST定数 |
| build-manifest-plugin-utils.ts | `packages/next/src/build/webpack/plugins/build-manifest-plugin-utils.ts` | ソース | normalizeRewritesForBuildManifest、ClientBuildManifest型 |
| route-loader.ts | `packages/next/src/client/route-loader.ts` | ソース | getClientBuildManifestでクライアント側マニフェスト取得 |
