# 帳票設計書 40-_devMiddlewareManifest.json

## 概要

本ドキュメントは、Next.js開発サーバー用のミドルウェアマニフェスト `_devMiddlewareManifest.json` の設計仕様を定義する。

### 本帳票の処理概要

本帳票は、Next.jsの開発サーバー（`next dev`）においてクライアント側にミドルウェアのマッチャー情報を提供するためのJSONマニフェストである。クライアントサイドナビゲーション時にミドルウェアが適用されるルートかどうかを事前に判定するために使用される。

**業務上の目的・背景**：本番ビルドでは `_clientMiddlewareManifest.js`（Turbopack使用時）や `process.env.__NEXT_MIDDLEWARE_MATCHERS`（webpack使用時）でマッチャー情報がインライン化されるが、開発モードではミドルウェア定義が動的に変更されるため、HTTPエンドポイントとして動的に提供する必要がある。本マニフェストはwebpack/Turbopackの両方の開発モードで共通に使用される。

**帳票の利用シーン**：(1) 開発モードでのクライアントサイドナビゲーションにおけるミドルウェア適用判定、(2) ミドルウェア変更時のHMR後のマッチャー情報再取得。

**主要な出力内容**：
1. ミドルウェアマッチャーの配列（ProxyMatcher型の配列）

**帳票の出力タイミング**：開発サーバー（`next dev`）の実行中、クライアントからのHTTPリクエスト時に動的に生成される。

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

## 帳票種別

開発用マニフェスト（JSON形式のHTTPエンドポイントレスポンス）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | 開発サーバー | `/_next/static/development/_devMiddlewareManifest.json` | クライアントからのfetchリクエスト |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON（HTTPレスポンス） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | `_devMiddlewareManifest.json` |
| 出力方法 | HTTPレスポンス（Content-Type: application/json） |
| 文字コード | UTF-8 |

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

JSON配列として以下の構造を持つ。マッチャーが存在しない場合は空配列。

```json
[
  {
    "regexp": "^/api/.*$",
    "originalSource": "/api/:path*"
  },
  {
    "regexp": "^/dashboard/.*$",
    "originalSource": "/dashboard/:path*"
  }
]
```

### ヘッダー部

N/A（トップレベルが配列のため）

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | マッチャー | ミドルウェアマッチャーオブジェクトの配列 | serverFields.middleware?.matchers | ProxyMatcher型の配列 | N/A |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 開発モード | `next dev` で実行中であること | Yes |
| ミドルウェア定義 | middleware.ts/js が存在すること | No（存在しない場合は空配列） |

### ソート順

N/A（マッチャー定義順を維持）

### 改ページ条件

N/A

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

N/A

### 参照テーブル一覧

N/A

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

N/A

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| マッチャー取得 | serverFields.middleware?.matchers \|\| [] | N/A | ミドルウェア未定義時は空配列 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[クライアント: PageLoader.getMiddleware] --> B[fetch: /_next/static/development/_devMiddlewareManifest.json]
    B --> C[開発サーバー: requestHandler]
    C --> D{pathname に devMiddlewareManifestPath を含む?}
    D -->|Yes| E[serverFields.middleware.matchers を取得]
    E --> F[JSON.stringify してレスポンス返却]
    F --> G[クライアント: window.__DEV_MIDDLEWARE_MATCHERS に設定]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| fetch失敗 | ネットワークエラー、サーバー未起動 | `Failed to fetch _devMiddlewareManifest` + エラー詳細 | 開発サーバーの起動確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1〜数件のマッチャー |
| 目標出力時間 | 即時（メモリ内データのJSON化のみ） |
| 同時出力数上限 | 複数のブラウザタブからの同時リクエスト対応 |

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

開発モード専用であり、本番環境では出力されない。ミドルウェアのマッチパターンが公開されるが、開発環境のlocalhostアクセスに限定されるため、通常は問題にならない。`credentials: 'same-origin'`でfetchされる。

## 備考

- 定数名: `DEV_CLIENT_MIDDLEWARE_MANIFEST`（`packages/next/src/shared/lib/constants.ts` 行106）
- 値: `_devMiddlewareManifest.json`
- 仮想ファイルとして`devVirtualFsItems`に登録され、実ファイルとしては存在しない（HTTPレスポンスとして動的生成）
- `window.__DEV_MIDDLEWARE_MATCHERS`グローバル変数にキャッシュされ、2回目以降はHTTPリクエストなしで取得
- webpack/Turbopackの両方の開発モードで同じエンドポイントが使用される
- Turbopack開発モードでは`_clientMiddlewareManifest.js`パスでも同じ内容が提供される（行1291-1294でdevTurbopackMiddlewareManifestPathも同じハンドラ）
- 本番モードではこのエンドポイントは存在せず、代わりにインライン化されたマッチャー情報を使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/next/src/shared/lib/constants.ts` | DEV_CLIENT_MIDDLEWARE_MANIFEST定数（行106） |
| 1-2 | page-loader.ts | `packages/next/src/client/page-loader.ts` | `__DEV_MIDDLEWARE_MATCHERS`グローバル変数の型: `ProxyMatcher[]`（行24） |

**読解のコツ**: マニフェストの構造はProxyMatcher配列であり、主にregexpとoriginalSourceプロパティを持つ。

#### Step 2: サーバー側（提供元）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | setup-dev-bundler.ts | `packages/next/src/server/lib/router-utils/setup-dev-bundler.ts` | requestHandler内のマニフェスト提供ロジック（行1291-1300） |

**主要処理フロー**:
1. **行1268-1269**: devMiddlewareManifestPathの定義とdevVirtualFsItemsへの登録
2. **行1271-1272**: devTurbopackMiddlewareManifestPath（Turbopack用）も同時登録
3. **行1291-1299**: pathnameがdevMiddlewareManifestPathまたはdevTurbopackMiddlewareManifestPathを含む場合、serverFields.middleware.matchersをJSON返却

#### Step 3: クライアント側（消費元）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | page-loader.ts | `packages/next/src/client/page-loader.ts` | getMiddleware()メソッド（行92-152）の開発モードブランチ（行128-151） |

**主要処理フロー**:
- **行129-130**: `__DEV_MIDDLEWARE_MATCHERS`をチェック、存在すればそのまま返す
- **行132-149**: なければfetchで`_devMiddlewareManifest.json`を取得→`__DEV_MIDDLEWARE_MATCHERS`に設定
- **行136**: buildIdを含むパスで取得（`/_next/static/{buildId}/_devMiddlewareManifest.json`）

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

```
next dev (開発サーバー)
    │
    ├─ setup-dev-bundler.ts
    │      ├─ devMiddlewareManifestPath 定義 (行1268)
    │      ├─ devTurbopackMiddlewareManifestPath 定義 (行1271)
    │      ├─ devVirtualFsItems.add() (行1269, 1272)
    │      └─ requestHandler() (行1291)
    │             └─ JSON.stringify(serverFields.middleware?.matchers || [])
    │
    └─ クライアントサイド
           └─ PageLoader.getMiddleware() (page-loader.ts 行128)
                  └─ fetch(_devMiddlewareManifest.json) → window.__DEV_MIDDLEWARE_MATCHERS
```

### データフロー図

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

serverFields.middleware ──────▶ requestHandler()
  .matchers                        └─ JSON.stringify()         ──▶ HTTP Response
                                                                    (/_next/static/development/
                                                                     _devMiddlewareManifest.json)
                                                                        │
                                                                        ▼
                                                                    PageLoader.getMiddleware()
                                                                        │
                                                                        ▼
                                                                    window.__DEV_MIDDLEWARE_MATCHERS
                                                                        │
                                                                        ▼
                                                                    ナビゲーション時のミドルウェア判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| setup-dev-bundler.ts | `packages/next/src/server/lib/router-utils/setup-dev-bundler.ts` | ソース | 開発サーバーでのマニフェスト提供（requestHandler） |
| page-loader.ts | `packages/next/src/client/page-loader.ts` | ソース | クライアント側のマッチャー取得（getMiddleware） |
| constants.ts | `packages/next/src/shared/lib/constants.ts` | ソース | DEV_CLIENT_MIDDLEWARE_MANIFEST定数 |
| get-page-static-info.ts | `packages/next/src/build/analysis/get-page-static-info.ts` | ソース | ProxyMatcher型の定義元 |
