# 機能設計書 93-マニフェスト生成

## 概要

本ドキュメントは、Next.jsのマニフェスト生成機能の設計について記述する。マニフェスト生成は、ビルド時にルーティング情報、アセットマッピング、フォント情報、Client/Server Componentの対応関係などをJSON形式のマニフェストファイルとして生成する機能である。

### 本機能の処理概要

**業務上の目的・背景**：Next.jsのサーバーランタイムは、ビルド時に生成されたマニフェストファイルを参照して、リクエストに対する適切なページの特定、アセットの配信、リライト/リダイレクトの処理を行う。マニフェストはビルドとランタイムの橋渡しとなる重要なデータ構造である。

**機能の利用シーン**：
- `next build` 実行時に各種マニフェストを自動生成する場合
- サーバーがリクエストを処理する際にルーティングマニフェストを参照する場合
- クライアントがコード分割されたチャンクを読み込む際にビルドマニフェストを参照する場合

**主要な処理内容**：
1. ルートマニフェスト（routes-manifest.json）の生成 - ルーティング情報、リダイレクト、リライト、ヘッダー設定
2. ビルドマニフェスト（build-manifest.json）の生成 - ページとチャンクの対応関係
3. ページマニフェスト（pages-manifest.json）の生成 - Pages Routerのページファイルマッピング
4. フライトマニフェスト（RSC関連マニフェスト）の生成 - React Server Componentのモジュール対応
5. フォントマニフェスト（next-font-manifest.json）の生成 - フォント最適化情報
6. マニフェストのJSON整形出力

**関連システム・外部連携**：Webpackビルドシステム、Turbopackビルドシステム、Next.jsサーバーランタイム。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | マニフェスト生成は画面を持たないビルド時処理 |

## 機能種別

データ生成 / ファイルシステム操作

## 入力仕様

### 入力パラメータ

#### ルートマニフェスト生成

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pageKeys | object | Yes | ページキー（pages, app） | pages: string[], app?: string[] |
| config | NextConfigComplete | Yes | Next.js設定 | - |
| redirects | Redirect[] | Yes | リダイレクト設定 | - |
| headers | Header[] | Yes | カスタムヘッダー設定 | - |
| rewrites | Rewrite | Yes | リライト設定 | - |
| restrictedRedirectPaths | string[] | Yes | 制限付きリダイレクトパス | - |
| isAppPPREnabled | boolean | Yes | PPR有効フラグ | - |
| appType | string | Yes | アプリケーション種別 | 'pages' \| 'app' \| 'hybrid' |

#### ビルドマニフェスト生成

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| assetMap | BuildManifest | Yes | アセットマップ | - |
| rewrites | CustomRoutes['rewrites'] | Yes | リライト設定 | - |
| clientRouterFilters | object | No | クライアントルーターフィルタ | BloomFilter形式 |

### 入力データソース

Webpackコンパイル結果、Next.js設定ファイル（next.config.js）、カスタムルート設定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| routes-manifest.json | JSON file | ルーティング情報（静的ルート、動的ルート、リダイレクト、リライト、ヘッダー） |
| build-manifest.json | JSON file | ページとJSチャンクの対応マッピング |
| _buildManifest.js | JS file | クライアント向けビルドマニフェスト（軽量版） |
| pages-manifest.json | JSON file | Pages Routerのページファイルパスマッピング |
| react-loadable-manifest.json | JSON file | 動的インポートのマニフェスト |
| next-font-manifest.json | JSON file | フォント最適化マニフェスト |

### 出力先

`distDir`（`.next/`）配下および`distDir/server/`配下。

## 処理フロー

### 処理シーケンス

```
1. ビルド設定の読み込み
   └─ next.config.js からカスタムルート、リダイレクト、ヘッダーを取得
2. ページキーの収集
   └─ ビルド済みページの一覧を取得
3. ルートマニフェスト生成
   └─ 静的ルート・動的ルート・RSC関連ヘッダーを含むマニフェスト構築
4. Webpackプラグインによるビルドマニフェスト生成
   └─ コンパイル完了後にアセットマップからマニフェスト生成
5. フォーマットとファイル書き出し
   └─ formatManifest で整形しJSONファイルとして出力
```

### フローチャート

```mermaid
flowchart TD
    A[next build 開始] --> B[ページキー収集]
    B --> C[generateRoutesManifest]
    C --> D[routes-manifest.json 出力]
    B --> E[Webpackコンパイル]
    E --> F[BuildManifestPlugin]
    F --> G[build-manifest.json 出力]
    F --> H[_buildManifest.js 出力]
    E --> I[PagesManifestPlugin]
    I --> J[pages-manifest.json 出力]
    E --> K[FlightManifestPlugin]
    K --> L[RSCマニフェスト出力]
    E --> M[NextFontManifestPlugin]
    M --> N[next-font-manifest.json 出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | マニフェストフォーマット | マニフェストはインデント2のJSON形式で出力 | 常時（formatManifest） |
| BR-02 | RSCヘッダー追加 | App Router使用時はRSC関連ヘッダー（Rsc, Next-Router-State-Tree等）をルートマニフェストに追加 | App Router有効時 |
| BR-03 | ルートソート | ルートは決定論的順序でソートされる（sortPagesで） | 常時 |
| BR-04 | 予約ページ除外 | `_app`, `_document`, `_error` 等の予約ページはルートマニフェストのルートから除外 | 常時 |
| BR-05 | クライアントマニフェスト軽量化 | クライアント向けビルドマニフェストは不要な情報を除去した軽量版 | クライアント配信時 |

### 計算ロジック

BloomFilterによるクライアントルーターフィルタの生成（静的ルート・動的ルートを確率的データ構造で表現し、クライアント側のルーティング判定を高速化）。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ビルドエラー | 動的ルートパターンのパースに失敗 | ビルドエラーとして報告 |
| - | ファイル書き込みエラー | 出力ディレクトリへの書き込みに失敗 | ビルドプロセスを中断 |

### リトライ仕様

リトライ不要。

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

該当なし。

## パフォーマンス要件

マニフェスト生成はビルドの最終フェーズで行われ、通常は数百ミリ秒以内に完了する。

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

- マニフェストファイルにはソースコードのパス情報が含まれるため、本番環境ではクライアントに不必要に公開しないこと
- クライアント向けビルドマニフェスト（`_buildManifest.js`）には機密情報を含めない

## 備考

- `formatManifest` は現在常にインデント付きJSONを出力するが、将来的にNODE_ENV=productionで圧縮出力に変更される可能性がある
- skew protection有効時は、ビルドIDを含まないパスが使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | generate-routes-manifest.ts | `packages/next/src/build/generate-routes-manifest.ts` | GenerateRoutesManifestOptions型（26-39行目）でルートマニフェストの入力を理解する |
| 1-2 | format-manifest.ts | `packages/next/src/build/manifests/formatter/format-manifest.ts` | formatManifest関数（6-8行目）のJSON整形ロジック |

**読解のコツ**: RoutesManifest型とBuildManifest型はNext.jsのランタイムでも参照されるため、これらの型定義を理解することでサーバーの動作も把握しやすくなる。

#### Step 2: ルートマニフェスト生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | generate-routes-manifest.ts | `packages/next/src/build/generate-routes-manifest.ts` | generateRoutesManifest関数（52行目〜）がルートマニフェスト生成のメイン処理 |

**主要処理フロー**:
1. **52-60行目**: オプションの分割代入
2. pageKeysの走査とisReservedPageによるフィルタリング
3. 動的ルートの正規表現パターン生成
4. リダイレクト・リライト・ヘッダーのbuildCustomRouteによる変換

#### Step 3: Webpackプラグインによるマニフェスト生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | build-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/build-manifest-plugin.ts` | BuildManifestPluginがWebpackのemitフェーズでビルドマニフェストを生成 |
| 3-2 | pages-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/pages-manifest-plugin.ts` | PagesManifestPluginがPagesRouterのマニフェストを生成 |
| 3-3 | flight-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts` | RSC関連のフライトマニフェスト生成 |
| 3-4 | next-font-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/next-font-manifest-plugin.ts` | フォントマニフェスト生成 |

**主要処理フロー**:
- **build-manifest-plugin.ts 48行目〜**: generateClientManifest関数がクライアント向け軽量マニフェストを生成
- **build-manifest-plugin.ts 32-44行目**: skew protection対応のパス生成

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

```
next build (build/index.ts)
    │
    ├─ generateRoutesManifest (generate-routes-manifest.ts:52)
    │      ├─ pageToRoute (build/utils.ts)
    │      ├─ buildCustomRoute (lib/build-custom-route.ts)
    │      └─ sortPages (router/utils/sortable-routes.ts)
    │
    ├─ BuildManifestPlugin.apply (Webpack plugin)
    │      ├─ generateClientManifest (build-manifest-plugin.ts:48)
    │      └─ formatManifest (manifests/formatter/format-manifest.ts:6)
    │
    ├─ PagesManifestPlugin.apply (Webpack plugin)
    │
    ├─ FlightManifestPlugin.apply (Webpack plugin)
    │
    └─ NextFontManifestPlugin.apply (Webpack plugin)
```

### データフロー図

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

next.config.js ────────▶ generateRoutesManifest ──▶ routes-manifest.json
(rewrites/redirects)

Webpackコンパイル結果 ──▶ BuildManifestPlugin ────▶ build-manifest.json
                                                     _buildManifest.js

Pages Routerページ ────▶ PagesManifestPlugin ────▶ pages-manifest.json

RSCモジュール ─────────▶ FlightManifestPlugin ───▶ flight-manifest

フォント設定 ──────────▶ NextFontManifestPlugin ─▶ next-font-manifest.json
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| generate-routes-manifest.ts | `packages/next/src/build/generate-routes-manifest.ts` | ソース | ルートマニフェスト生成のメインロジック |
| format-manifest.ts | `packages/next/src/build/manifests/formatter/format-manifest.ts` | ソース | マニフェストJSON整形 |
| build-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/build-manifest-plugin.ts` | ソース | ビルドマニフェストWebpackプラグイン |
| build-manifest-plugin-utils.ts | `packages/next/src/build/webpack/plugins/build-manifest-plugin-utils.ts` | ソース | ビルドマニフェストユーティリティ |
| pages-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/pages-manifest-plugin.ts` | ソース | ページマニフェストWebpackプラグイン |
| flight-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts` | ソース | RSCフライトマニフェストプラグイン |
| next-font-manifest-plugin.ts | `packages/next/src/build/webpack/plugins/next-font-manifest-plugin.ts` | ソース | フォントマニフェストプラグイン |
