# 帳票設計書 37-_clientMiddlewareManifest.js

## 概要

本ドキュメントは、Turbopack使用時に生成されるクライアントサイドミドルウェアマニフェスト `_clientMiddlewareManifest.js` の設計仕様を定義する。

### 本帳票の処理概要

本帳票は、Turbopack使用時にミドルウェアのマッチャー情報をクライアントサイドで利用可能にするためのJavaScriptファイルである。ミドルウェアが定義するURLマッチパターンを含み、クライアントサイドのPageLoaderがナビゲーション前にミドルウェア適用対象のルートを判定するために使用される。

**業務上の目的・背景**：Next.jsのミドルウェア機能では、特定のURLパターンにマッチするリクエストに対してサーバーサイドで処理を挿入できる。クライアントサイドナビゲーション時にミドルウェアが適用されるルートかどうかを事前に判定するため、マッチャー情報をクライアント側に提供する必要がある。本マニフェストはTurbopack環境でこの情報を提供する。

**帳票の利用シーン**：(1) Turbopackビルド時のクライアントサイドナビゲーション制御、(2) ミドルウェア適用対象ルートの事前判定、(3) 開発サーバー・本番ビルドの両方で使用。

**主要な出力内容**：
1. ミドルウェアマッチャーの配列（`self.__MIDDLEWARE_MATCHERS`グローバル変数として設定）
2. コールバック関数の呼び出し（`self.__MIDDLEWARE_MATCHERS_CB`、非同期ロード対応）

**帳票の出力タイミング**：Turbopack使用時のビルド時または開発サーバー起動時に、TurbopackManifestLoaderの`writeMiddlewareManifest`メソッドにより出力される。

**帳票の利用者**：Next.jsクライアントサイドランタイム（PageLoader）、ブラウザ。

## 帳票種別

クライアントサイドマニフェスト（JavaScript形式のランタイム設定ファイル）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | 全ページ | ブラウザ内ナビゲーション時に参照 | 自動ロード |

## 出力形式

### 基本仕様

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

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

JavaScriptとして実行される自己設定スクリプト。

```javascript
self.__MIDDLEWARE_MATCHERS = [
  {
    "regexp": "^/api/.*$",
    "originalSource": "/api/:path*"
  }
];self.__MIDDLEWARE_MATCHERS_CB && self.__MIDDLEWARE_MATCHERS_CB()
```

### ヘッダー部

N/A（グローバル変数への代入形式）

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | __MIDDLEWARE_MATCHERS | ミドルウェアマッチャー配列 | middlewareManifest.middleware['/'].matchers | JSON配列 | N/A |
| 2 | __MIDDLEWARE_MATCHERS_CB | コールバック呼び出し | 固定パターン | JavaScript関数呼び出し | N/A |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| Turbopack使用 | Turbopackでビルドまたは開発サーバー実行 | Yes |
| ミドルウェア定義 | middleware.ts/js が存在すること | No（存在しない場合は空配列） |

### ソート順

N/A

### 改ページ条件

N/A

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

N/A

### 参照テーブル一覧

N/A

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

N/A

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| マッチャー取得 | middlewareManifest?.middleware['/']?.matchers \|\| [] | N/A | ルートミドルウェアのマッチャーを取得 |
| 出力パス（dev） | `static/{buildId}/_clientMiddlewareManifest.js` | N/A | 開発モード時 |
| 出力パス（prod+skew） | `static/_clientMiddlewareManifest.js` | N/A | skew protection有効時 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Turbopack ビルド/開発サーバー] --> B[TurbopackManifestLoader.writeManifests]
    B --> C[writeMiddlewareManifest 呼び出し]
    C --> D[middlewareManifests のマージ]
    D --> E[サーバーサイド middleware-manifest.json 書き込み]
    E --> F[マッチャー情報抽出]
    F --> G[clientMiddlewareManifestJs 文字列生成]
    G --> H[_clientMiddlewareManifest.js 書き込み]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| マッチャーなし | ミドルウェアが定義されていない | 空配列がセットされる | 正常動作 |
| ファイル書き込みエラー | ディスク容量不足等 | ファイルシステムエラー | ディスク容量確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1〜数件のマッチャー |
| 目標出力時間 | 即時（JSON文字列化のみ） |
| 同時出力数上限 | 1 |

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

ミドルウェアのURLマッチパターンが公開されるため、クライアントサイドで閲覧可能となる。ミドルウェアのマッチパターンにセキュリティ上の秘密情報を含めないこと。本ファイルは `/_next/static/` 配下に配置され、ブラウザからアクセス可能。

## 備考

- 定数名: `TURBOPACK_CLIENT_MIDDLEWARE_MANIFEST`（`packages/next/src/shared/lib/constants.ts` 行103-104）
- 出力先: `.next/static/{buildId}/_clientMiddlewareManifest.js`（開発時）、`.next/static/_clientMiddlewareManifest.js`（skew protection有効時）
- webpack使用時はこのファイルではなく、ビルド時にインライン化される `process.env.__NEXT_MIDDLEWARE_MATCHERS` を使用
- クライアント側の読み込みは `PageLoader.getMiddleware()` メソッドで行われる（`packages/next/src/client/page-loader.ts` 行104-126）
- コールバックパターン（`__MIDDLEWARE_MATCHERS_CB`）により、スクリプトの非同期ロードに対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/next/src/shared/lib/constants.ts` | TURBOPACK_CLIENT_MIDDLEWARE_MANIFEST定数（行103-104） |
| 1-2 | page-loader.ts | `packages/next/src/client/page-loader.ts` | `__MIDDLEWARE_MATCHERS`グローバル変数の使用（行99-126） |

**読解のコツ**: クライアント側ではProxyMatcher型の配列としてマッチャー情報を利用する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | TurbopackManifestLoaderクラス（行179-916）のwriteMiddlewareManifest（行797-863） |

**主要処理フロー**:
1. **行800-807**: 出力パスの決定（deploymentIdの有無で分岐）
2. **行814-816**: mergeMiddlewareManifestsでマニフェストをマージ
3. **行833-841**: サーバーサイドのmiddleware-manifest.jsonを書き込み
4. **行846-852**: クライアント用JS文字列生成（`self.__MIDDLEWARE_MATCHERS = ...`）
5. **行854-858**: _clientMiddlewareManifest.jsの書き込み

#### Step 3: クライアント側の読み込みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | page-loader.ts | `packages/next/src/client/page-loader.ts` | getMiddleware()メソッド（行92-152） |

**主要処理フロー**:
- **行94-101**: webpack本番：process.env.__NEXT_MIDDLEWARE_MATCHERSから取得
- **行104-126**: Turbopack本番：`__MIDDLEWARE_MATCHERS`グローバル変数から取得、未ロード時はコールバック待ち
- **行128-151**: 開発モード：fetchで`_devMiddlewareManifest.json`を取得

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

```
Turbopack ビルド/開発サーバー
    │
    └─ TurbopackManifestLoader.writeManifests() (行890)
           └─ writeMiddlewareManifest() (行797)
                  ├─ mergeMiddlewareManifests() → MiddlewareManifest統合
                  ├─ writeFileAtomic(middleware-manifest.json) → サーバー用
                  └─ writeFileAtomic(_clientMiddlewareManifest.js) → クライアント用
                         │
                         ▼
                  PageLoader.getMiddleware() (page-loader.ts 行92)
                         └─ self.__MIDDLEWARE_MATCHERS 参照
```

### データフロー図

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

middleware.ts ─────────────────▶ Turbopack コンパイル
                                    │
                               middlewareManifests (部分マニフェスト)
                                    │
                               mergeMiddlewareManifests()
                                    │
                                    ├─ middleware-manifest.json ──▶ サーバーサイド
                                    │
                                    └─ matchers 抽出
                                         │
                                    _clientMiddlewareManifest.js ──▶ ブラウザ
                                         │
                                    PageLoader.getMiddleware() ──▶ ナビゲーション制御
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| manifest-loader.ts | `packages/next/src/shared/lib/turbopack/manifest-loader.ts` | ソース | TurbopackManifestLoader・writeMiddlewareManifest実装 |
| constants.ts | `packages/next/src/shared/lib/constants.ts` | ソース | TURBOPACK_CLIENT_MIDDLEWARE_MANIFEST定数 |
| page-loader.ts | `packages/next/src/client/page-loader.ts` | ソース | クライアント側のマッチャー読み込み（getMiddleware） |
| setup-dev-bundler.ts | `packages/next/src/server/lib/router-utils/setup-dev-bundler.ts` | ソース | 開発サーバーでのマニフェストパス登録（行1271-1272） |
| index.ts | `packages/next/src/build/index.ts` | ソース | 本番ビルドでのマニフェスト書き込み |
