# 機能設計書 9-next typegen

## 概要

本ドキュメントは、Next.jsのTypeScript型定義自動生成コマンド `next typegen` の機能設計を記述する。フルビルドを実行せずにルート・ページ・レイアウトのTypeScript型定義を生成するCLIコマンドである。

### 本機能の処理概要

`next typegen` コマンドは、Next.jsプロジェクトのルーティング構造を解析し、型安全なナビゲーションを実現するためのTypeScript型定義ファイルを生成するCLIコマンドである。

**業務上の目的・背景**：Next.jsのApp RouterおよびPages Routerは、ファイルシステムベースのルーティングを採用している。このルーティング構造から自動的にTypeScript型定義を生成することで、リンクやナビゲーションのパスを型安全に記述でき、タイポや存在しないルートへの遷移をコンパイル時に検出できる。`next build` を実行せずに型定義だけを更新できるため、開発中のイテレーションが高速化される。

**機能の利用シーン**：新しいページやルートを追加した後、TypeScript型定義を更新する際に使用する。開発中にIDEの型補完を最新の状態に保つために実行する。

**主要な処理内容**：
1. プロジェクトディレクトリの検証
2. Next.js設定の読み込み
3. SWCバインディングのインストール確認
4. TypeScriptセットアップの検証
5. pages/ディレクトリのルート収集と処理
6. app/ディレクトリのルート収集と処理（ページ、レイアウト、デフォルトファイル、スロット）
7. ルート型マニフェストの生成
8. バリデーターファイルの生成
9. キャッシュライフ型定義の生成
10. エントリーファイル（routes.d.ts）の生成

**関連システム・外部連携**：TypeScript、SWCバインディング

**権限による制御**：特段の権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 関連画面なし（CLI型定義ファイル生成のみ） |

## 機能種別

CLIコマンド / コード生成 / 型定義生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| directory | string | No | プロジェクトディレクトリ。未指定時はカレントディレクトリ | 存在するディレクトリであること |

### 入力データソース

- CLI引数
- next.config.js / next.config.ts
- プロジェクトのファイルシステム（pages/、app/ディレクトリ構造）
- tsconfig.json

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| route-types.d.ts | file | ルートの型定義ファイル |
| validator.ts | file | ルートバリデーションファイル |
| cache-life.d.ts | file | キャッシュライフの型定義ファイル |
| routes.d.ts | file | エントリーファイル（next-env.d.tsから参照） |

### 出力先

- `{distDir}/types/route-types.d.ts` - メインの型定義
- `{distDir}/types/validator.ts` - バリデーターファイル
- `{distDir}/types/cache-life.d.ts` - キャッシュライフ型定義
- `{distDirRoot}/types/routes.d.ts` - エントリーファイル

## 処理フロー

### 処理シーケンス

```
1. プロジェクトディレクトリの検証
   └─ getProjectDir + existsSync
2. Next.js設定の読み込み
   └─ loadConfig(PHASE_PRODUCTION_BUILD, baseDir)
3. SWCバインディングのインストール
   └─ installBindings(experimental.useWasmBinary)
4. distDir・ページディレクトリの解決
   └─ findPagesDir(baseDir)でpagesDir/appDirを取得
5. TypeScriptセットアップの検証
   └─ verifyTypeScriptSetup()
6. typesディレクトリの作成
   └─ mkdir({distDir}/types, { recursive: true })
7. Pagesルートの処理（pagesDirが存在する場合）
   7-1. collectPagesFiles()でページファイルを収集
   7-2. createPagesMapping()でマッピング生成
   7-3. processPageRoutes()でページルートとAPIルートを分離
8. Appルートの処理（appDirが存在する場合）
   8-1. collectAppFiles()でページ・レイアウト・デフォルトファイルを収集
   8-2. createPagesMapping()でマッピング生成
   8-3. extractSlotsFromAppRoutes() + extractSlotsFromDefaultFiles()でスロット情報を抽出
   8-4. combineSlots()でスロットを結合
   8-5. processAppRoutes()でアプリルートとルートハンドラーを分離
   8-6. processLayoutRoutes()でレイアウトルートを処理
9. ルート型マニフェストの生成
   └─ createRouteTypesManifest()
10. 各ファイルの書き込み
    └─ writeRouteTypesManifest()、writeValidatorFile()、writeCacheLifeTypes()、writeRouteTypesEntryFile()
```

### フローチャート

```mermaid
flowchart TD
    A[next typegen 実行] --> B[プロジェクトディレクトリ検証]
    B --> C[Next.js設定読み込み]
    C --> D[SWCバインディング確認]
    D --> E[TypeScriptセットアップ検証]
    E --> F{pagesDir存在?}
    F -->|Yes| G[Pagesルート処理]
    F -->|No| H{appDir存在?}
    G --> H
    H -->|Yes| I[Appルート処理]
    H -->|No| J[ルート型マニフェスト生成]
    I --> J
    J --> K[route-types.d.ts書き込み]
    K --> L[validator.ts書き込み]
    L --> M[cache-life.d.ts書き込み]
    M --> N[routes.d.ts エントリーファイル書き込み]
    N --> O[完了メッセージ]
    O --> P[process.exit 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | strictRouteTypes | experimental.strictRouteTypesの設定に応じて厳密な型定義を生成 | next.config設定 |
| BR-02 | src/ディレクトリ判定 | pagesDir/appDirがsrc/以下にあるかを判定し、パス生成に反映 | 常時 |
| BR-03 | routes.d.tsはdistDirRootに配置 | next-env.d.tsから一貫したインポートパスにするため | 常時 |
| BR-04 | ビルド完了後の強制終了 | process.exit(0)で強制終了（オープンハンドル防止） | 常時 |
| BR-05 | cacheLife型定義の生成 | nextConfig.cacheLife設定に基づきキャッシュライフの型定義を生成 | cacheLife設定存在時 |

### 計算ロジック

なし。ルーティング構造からの型定義生成はcreateRouteTypesManifest関数に委譲される。

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

### 操作別データベース影響一覧

本機能はデータベースを操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ディレクトリ不在 | 指定されたプロジェクトディレクトリが存在しない | 正しいパスを指定 |
| - | 設定読み込み失敗 | next.config.jsの構文エラー等 | 設定ファイルを修正 |
| - | TypeScriptセットアップ失敗 | tsconfig.jsonの不備 | TypeScriptを正しくセットアップ |

### リトライ仕様

なし。

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

なし。ファイルシステムへの書き込みは順次実行される。

## パフォーマンス要件

- フルビルドと比較して高速に型定義を生成できることが期待される
- プロジェクトのルート数に比例して処理時間が増加

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

- 生成されるファイルにソースコードの内容は含まれず、ルーティング構造のみが反映される

## 備考

- route-types.d.tsとroutes.d.tsは別ファイル。routes.d.tsはエントリーファイルとしてroute-types.d.tsを参照する
- typedRoutes設定とstrictRouteTypes設定の両方をサポート
- redirects/rewritesの設定もルート型マニフェストに含まれる
- collectAppFilesは単一のディレクトリトラバーサルでページ・レイアウト・デフォルトファイルを収集する（効率的）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | next-typegen.ts | `packages/next/src/cli/next-typegen.ts` | NextTypegenOptions型定義（38-40行目）、RouteInfo型・SlotInfo型のインポート（23行目） |
| 1-2 | entries.ts | `packages/next/src/build/entries.ts` | RouteInfo型・SlotInfo型の定義（型のソース） |

**読解のコツ**: RouteInfoとSlotInfoは`packages/next/src/build/entries.ts`からインポートされている。これらの型がルーティング構造の中間表現として使われる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | next.ts | `packages/next/src/bin/next.ts` | typegenコマンドの定義（445-463行目） |
| 2-2 | next-typegen.ts | `packages/next/src/cli/next-typegen.ts` | nextTypegen関数（42-203行目） |

**主要処理フロー**:
1. **46-51行目**: プロジェクトディレクトリの検証
2. **53-54行目**: 設定読み込みとSWCバインディングインストール
3. **56行目**: findPagesDirでpagesDir/appDir取得
4. **60-72行目**: verifyTypeScriptSetup
5. **82-93行目**: 変数の初期化（各種ルート配列・マッピングオブジェクト）
6. **116-125行目**: Pagesルートの処理
7. **128-157行目**: Appルートの処理（collectAppFiles → createMapping → processAppRoutes）
8. **159-170行目**: createRouteTypesManifest呼び出し
9. **172-201行目**: 4つのファイルの書き込み
10. **202行目**: 完了メッセージ

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | route-types-utils.ts | `packages/next/src/server/lib/router-utils/route-types-utils.ts` | createRouteTypesManifest、writeRouteTypesManifest、writeValidatorFile、writeRouteTypesEntryFile |
| 3-2 | cache-life-type-utils.ts | `packages/next/src/server/lib/router-utils/cache-life-type-utils.ts` | writeCacheLifeTypes |

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

```
bin/next.ts (CLIエントリーポイント)
    │
    └─ cli/next-typegen.ts::nextTypegen()
           ├─ lib/get-project-dir.ts::getProjectDir()
           ├─ server/config.ts::loadConfig()
           ├─ build/swc/install-bindings.ts::installBindings()
           ├─ lib/find-pages-dir.ts::findPagesDir()
           ├─ lib/verify-typescript-setup.ts::verifyTypeScriptSetup()
           ├─ server/lib/find-page-file.ts::createValidFileMatcher()
           ├─ build/entries.ts
           │      ├─ collectPagesFiles() [Pages]
           │      ├─ collectAppFiles() [App]
           │      ├─ createPagesMapping()
           │      ├─ processPageRoutes()
           │      ├─ processAppRoutes()
           │      ├─ processLayoutRoutes()
           │      ├─ extractSlotsFromAppRoutes()
           │      ├─ extractSlotsFromDefaultFiles()
           │      └─ combineSlots()
           ├─ server/lib/router-utils/route-types-utils.ts
           │      ├─ createRouteTypesManifest()
           │      ├─ writeRouteTypesManifest()
           │      ├─ writeValidatorFile()
           │      └─ writeRouteTypesEntryFile()
           └─ server/lib/router-utils/cache-life-type-utils.ts
                  └─ writeCacheLifeTypes()
```

### データフロー図

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

ファイルシステム ────▶ collectPagesFiles() ───────▶ pagePaths[]
  (pages/)                   │
                       createPagesMapping() ────▶ mappedPages
                              │
                       processPageRoutes() ─────▶ pageRoutes[], pageApiRoutes[]

ファイルシステム ────▶ collectAppFiles() ─────────▶ appPaths[], layoutPaths[], defaultPaths[]
  (app/)                     │
                       createPagesMapping() ────▶ mappedAppPages, mappedAppLayouts
                              │
                       processAppRoutes() ──────▶ appRoutes[], appRouteHandlers[]
                       processLayoutRoutes() ──▶ layoutRoutes[]
                       extractSlots + combine ─▶ slots[]
                              │
next.config ─────────▶ createRouteTypesManifest() ▶ routeTypesManifest
                              │
                       writeRouteTypesManifest() ▶ route-types.d.ts
                       writeValidatorFile() ─────▶ validator.ts
                       writeCacheLifeTypes() ────▶ cache-life.d.ts
                       writeRouteTypesEntryFile()▶ routes.d.ts
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| next.ts | `packages/next/src/bin/next.ts` | ソース | CLIメインエントリーポイント |
| next-typegen.ts | `packages/next/src/cli/next-typegen.ts` | ソース | next typegenコマンドのメイン処理 |
| entries.ts | `packages/next/src/build/entries.ts` | ソース | ルート収集・マッピング・処理 |
| route-types-utils.ts | `packages/next/src/server/lib/router-utils/route-types-utils.ts` | ソース | ルート型マニフェスト生成・書き込み |
| cache-life-type-utils.ts | `packages/next/src/server/lib/router-utils/cache-life-type-utils.ts` | ソース | キャッシュライフ型定義生成 |
| find-page-file.ts | `packages/next/src/server/lib/find-page-file.ts` | ソース | ファイルマッチャー作成 |
| config.ts | `packages/next/src/server/config.ts` | ソース | Next.js設定読み込み |
| install-bindings.ts | `packages/next/src/build/swc/install-bindings.ts` | ソース | SWCバインディングインストール |
| verify-typescript-setup.ts | `packages/next/src/lib/verify-typescript-setup.ts` | ソース | TypeScriptセットアップ検証 |
| find-pages-dir.ts | `packages/next/src/lib/find-pages-dir.ts` | ソース | pages/appディレクトリ検出 |
| page-types.ts | `packages/next/src/lib/page-types.ts` | ソース | ページタイプ定数 |
