# 帳票設計書 33-ビルドルートツリー（Build Route Tree）

## 概要

本ドキュメントは、Next.jsビルド完了時にコンソールに出力されるルート一覧表「ビルドルートツリー（Build Route Tree）」の設計仕様を定義する。

### 本帳票の処理概要

本帳票は、`next build` 完了時に標準出力（コンソール）に表示されるルート一覧のツリー表示である。各ルートの種類（Static/SSG/Dynamic/PPR）、サイズ、所要時間をテーブル形式で表示し、ビルド結果の概要を開発者に提供する。

**業務上の目的・背景**：ビルド完了後に開発者がプロジェクト内の全ルートの状態を一目で把握できるようにすることが目的である。各ルートがどのようなレンダリング戦略（Static/SSG/Dynamic/PPR）を使用しているか、ビルドにどれだけの時間がかかったか、ISR/SSGの再検証設定はどうなっているかを視覚的に確認できる。

**帳票の利用シーン**：(1) ビルド完了後のルート状態確認、(2) パフォーマンス最適化の対象特定（遅いルートの検出）、(3) レンダリング戦略の確認、(4) ISR再検証設定の確認。

**主要な出力内容**：
1. ルートパスとシンボル（○=Static, ●=SSG, ƒ=Dynamic, ◐=PPR）
2. ビルド所要時間（300ms以上の場合のみ表示、色分け：緑/黄/赤）
3. Revalidate値（ISR再検証間隔）
4. Expire値（キャッシュ有効期限）

**帳票の出力タイミング**：`next build` コマンド完了直前。ビルドプロセスの最終段階で `printTreeView` 関数が呼び出される。

**帳票の利用者**：フロントエンドエンジニア、DevOpsエンジニア、プロジェクトマネージャー。

## 帳票種別

コンソール出力（標準出力へのテキストテーブル表示）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIコマンド | `next build` | ビルド完了時に自動出力 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（コンソール出力、ANSIカラーコード付き） |
| 用紙サイズ | N/A（コンソール出力） |
| 向き | N/A |
| ファイル名 | N/A（ファイル出力なし、標準出力のみ） |
| 出力方法 | console.log経由の標準出力 |
| 文字コード | UTF-8 |

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

テキストテーブル形式で、ルーターの種類（App Router / Pages Router）ごとにセクション分けして表示する。

```
Route (app)                             Revalidate    Expire
┌ ○ /
├ ○ /about
├ ● /blog/[slug]                        60s           3600s
├ ƒ /api/users
└ ◐ /dashboard

Route (pages)
┌ ○ /
└ ƒ /api/hello

○  (Static)   prerendered as static content
●  (SSG)      prerendered as static HTML (uses generateStaticParams)
ƒ  (Dynamic)  server-rendered on demand
◐  (PPR)      partially prerendered (uses Partial Prerendering)
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Route (app/pages) | ルーターの種類を示すヘッダー | routerType引数 | 下線付きテキスト |
| 2 | Revalidate | 再検証設定列ヘッダー | 条件付き表示（ISR使用時のみ） | 下線付きテキスト |
| 3 | Expire | 有効期限列ヘッダー | 条件付き表示（Expire設定時のみ） | 下線付きテキスト |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | ボーダー | ツリー罫線文字（┌/├/└/─） | 配列インデックス | 単一文字 | 2 |
| 2 | シンボル | ルート種別シンボル（○/●/ƒ/◐） | PageInfo | 単一文字 | 2 |
| 3 | ルートパス | ルートのパス | リスト項目 | 文字列 | 可変 |
| 4 | 所要時間 | ビルド時間（300ms以上の場合） | PageInfo.pageDuration + ssgPageDurations | 色付き文字列（緑/黄/赤） | 可変 |
| 5 | Revalidate | ISR再検証間隔 | PageInfo.initialCacheControl | 秒数表示 | 可変 |
| 6 | Expire | キャッシュ有効期限 | PageInfo.initialCacheControl | 秒数表示 | 可変 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 凡例 | 使用されたシンボルの説明 | usedSymbols Set | シンボル + 説明テキスト |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| App Routerルート | app/配下のルート（/favicon.ico、/_global-errorを除外） | Yes（存在時） |
| Pages Routerルート | pages/配下のルート（_document、_error、カスタム_appがない場合の_appを除外） | Yes（存在時） |
| 所要時間表示閾値 | MIN_DURATION（デフォルト300ms）以上の場合のみ時間を表示 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ルートパス | 昇順（localeCompare） |

### 改ページ条件

N/A（コンソール出力のため改ページは存在しない）

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

N/A（メモリ内のPageInfoマップを参照）

### 参照テーブル一覧

N/A

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

N/A

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 合計所要時間 | pageDuration + sum(ssgPageDurations) | N/A | ページ本体 + SSGパスの合計 |
| シンボル判定 | isEdgeRuntime→ƒ, isRoutePPREnabled→◐/○/ƒ, isStatic→○, isSSG→●, else→ƒ | N/A | 優先順位付き条件分岐 |
| 所要時間の色 | <1000ms→緑, <2000ms→黄, >=2000ms→赤太字 | N/A | getPrettyDuration関数 |
| SSGサブルート表示 | 最大7件表示+残りは「[+N more paths]」（8件の場合は全件表示） | N/A | プレビュー件数制限 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[next build 完了] --> B[printTreeView 呼び出し]
    B --> C[hasCustomApp 判定]
    C --> D{App Router ルート存在?}
    D -->|Yes| E[App Router ルートを整形・表示]
    D -->|No| F{Pages Router ルート存在?}
    E --> F
    F -->|Yes| G[Pages Router ルートを整形・表示]
    F -->|No| H[凡例表示]
    G --> H
    H --> I[text-table でテーブル整形]
    I --> J[console.log で標準出力]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | pageInfosが空の場合 | 空のテーブルが表示される | 正常動作（ルートなし） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数十〜数千ルート |
| 目標出力時間 | 1秒未満（テーブル整形のみ） |
| 同時出力数上限 | 1（ビルド完了時に1回のみ） |

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

コンソール出力のみであり、ファイルには記録されない。ルート構造が表示されるため、CI/CDログの公開範囲に注意が必要。環境変数 `__NEXT_PRIVATE_DETERMINISTIC_BUILD_OUTPUT` を設定すると所要時間が非表示になり、確定的な出力が得られる（テスト用途）。

## 備考

- `text-table`ライブラリを使用してテーブル整形を行う
- ANSIカラーコードを使用するため、カラー対応ターミナルでの表示が前提
- `stripAnsi`でカラーコードを除去した幅でカラム揃えを行う
- SSGサブルートは所要時間の降順でソートされ、上位7件が表示される
- `__NEXT_PRIVATE_DETERMINISTIC_BUILD_OUTPUT`設定時はMIN_DURATIONがInfinityとなり時間表示が抑制される

---

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

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

### 推奨読解順序

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

printTreeViewに渡されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | utils.ts | `packages/next/src/build/utils.ts` | PageInfo型（行199付近）でページ情報の構造を把握 |

**読解のコツ**: PageInfoの主要フィールド: isStatic, isSSG, isRoutePPREnabled, runtime, pageDuration, ssgPageDurations, initialCacheControl。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | utils.ts | `packages/next/src/build/utils.ts` | printTreeView関数（行321-）がメイン処理 |

**主要処理フロー**:
1. **行321-343**: 関数シグネチャ・パラメータ定義
2. **行345-357**: MIN_DURATIONとgetPrettyDuration定義
3. **行360-362**: hasCustomApp判定
4. **行369-376**: printFileTree内部関数でルーター種別ごとの処理
5. **行410-520**: 各ルートの行生成ロジック（シンボル判定、所要時間、SSGサブルート）

#### Step 3: シンボル判定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | utils.ts | `packages/next/src/build/utils.ts` | 行425-452でシンボル判定の条件分岐 |

**主要処理フロー**:
- **行427-428**: _appページはスペース
- **行429**: エッジランタイムは`ƒ`
- **行430-445**: PPR有効時は状態に応じて`ƒ`/`○`/`◐`
- **行446-447**: isStaticは`○`
- **行448-449**: isSSGは`●`
- **行450-451**: それ以外は`ƒ`

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

```
next build (packages/next/src/build/index.ts)
    │
    └─ printTreeView() (packages/next/src/build/utils.ts 行321)
           ├─ findPageFile() → _appの存在確認
           ├─ filterAndSortList() → ルートのフィルタリング・ソート
           ├─ printFileTree() → ルーター種別ごとの行生成
           │      ├─ シンボル判定（isEdge/isPPR/isStatic/isSSG）
           │      ├─ 所要時間計算
           │      └─ SSGサブルート展開
           ├─ textTable() → テーブル整形
           └─ console.log() → 標準出力
```

### データフロー図

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

pageInfos Map ─────────────────▶ printTreeView()
                                    │
lists.pages ───────────────────▶    ├─ filterAndSortList()
lists.app ─────────────────────▶    ├─ シンボル判定
                                    ├─ 所要時間色分け
middlewareManifest ────────────▶     ├─ テーブル行生成       ──▶ コンソール出力
functionsConfigManifest ──────▶     └─ textTable整形              (stdout)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| utils.ts | `packages/next/src/build/utils.ts` | ソース | printTreeView関数、PageInfo型、filterAndSortList関数の実装 |
| index.ts | `packages/next/src/build/index.ts` | ソース | printTreeViewの呼び出し元 |
| format.ts | `packages/next/src/build/output/format.ts` | ソース | formatRevalidate、formatExpire関数 |
| picocolors.ts | `packages/next/src/lib/picocolors.ts` | ソース | ANSIカラーコード関数（bold, cyan, green, red, yellow, underline） |
