# 機能設計書 92-ビルドトレース

## 概要

本ドキュメントは、Next.jsのビルドトレース機能の設計について記述する。ビルドトレースは、ビルド時にNode.jsサーバーの依存関係をトレースし、デプロイに必要なファイルのみを特定することで、デプロイサイズの最適化を実現する機能である。

### 本機能の処理概要

**業務上の目的・背景**：Next.jsアプリケーションをデプロイする際、node_modulesを含む全ファイルをデプロイすると非常に大きなサイズになる。ビルドトレースは`@vercel/nft`（Node File Trace）を使用して、実行に必要なファイルのみを特定し、特にstandalone出力モード時のデプロイサイズを最小化する。

**機能の利用シーン**：
- `output: 'standalone'` でビルドする際、最小限のサーバーファイルセットを生成する場合
- 各ルートの依存ファイルを `.nft.json` として出力し、デプロイ最適化に利用する場合
- カスタムキャッシュハンドラーの依存関係を正しくトレースする必要がある場合

**主要な処理内容**：
1. サーバーエントリポイント（next-server, minimal-server）の依存関係トレース
2. 各ルート（ページ/App Router）の個別依存関係トレース
3. 不要ファイルの除外（開発用ファイル、テストファイル、webpack関連等）
4. `.nft.json` ファイルの生成（トレース結果の永続化）
5. カスタムキャッシュハンドラー・standalone用ファイルの追加トレース

**関連システム・外部連携**：`@vercel/nft`（Node File Trace）ライブラリ、Webpackビルドコンテキスト、Vercel CI環境検出。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ビルドトレースは画面を持たないビルド時処理 |

## 機能種別

データ連携 / ファイルシステム操作 / 依存解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dir | string | Yes | プロジェクトルートディレクトリ | 有効なパス |
| config | NextConfigComplete | Yes | Next.js設定オブジェクト | - |
| distDir | string | Yes | ビルド出力ディレクトリ | 有効なパス |
| edgeRuntimeRoutes | RoutesUsingEdgeRuntime | Yes | Edge Runtimeを使用するルート情報 | - |
| staticPages | string[] | Yes | 静的ページのリスト | - |
| nextBuildSpan | Span | No | トレーシング用スパン | - |
| buildTraceContext | BuildTraceContext | No | Webpackビルドトレースコンテキスト | - |
| outputFileTracingRoot | string | Yes | ファイルトレースのルートディレクトリ | 有効なパス |

### 入力データソース

ビルドプロセスから渡されるビルド設定、Webpackビルドコンテキスト、ファイルシステム上のソースファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| next-server.js.nft.json | JSON file | サーバー全体の依存ファイルリスト |
| next-minimal-server.js.nft.json | JSON file | 最小サーバーの依存ファイルリスト |
| {route}.nft.json | JSON file | 各ルートの個別依存ファイルリスト |

### 出力先

`distDir`（`.next/`）配下に`.nft.json`ファイルとして出力。

## 処理フロー

### 処理シーケンス

```
1. 共有エントリポイントの構築
   └─ defaultOverrides, cacheHandler, standalone用ファイルを収集
2. サーバーエントリポイントの定義
   └─ next-server, minimal-server のエントリを構築
3. 除外パターンの構築
   └─ 開発用ファイル、webpack、テストファイル等のignoreパターンを定義
4. nodeFileTrace の実行
   └─ @vercel/nft を使用して依存関係グラフを構築
5. トレース結果の分類
   └─ server用、minimal用、routes用に分類
6. .nft.json の生成
   └─ 各カテゴリのトレース結果をJSONファイルとして書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[collectBuildTraces開始] --> B[共有エントリポイント構築]
    B --> C[除外パターン定義]
    C --> D[nodeFileTrace実行]
    D --> E[トレース結果分類]
    E --> F{standaloneモード?}
    F -->|Yes| G[jest-worker等追加]
    F -->|No| H[スキップ]
    G --> I[.nft.json生成]
    H --> I
    I --> J[各ルートのトレース結果生成]
    J --> K[ルート別.nft.json書き出し]
    K --> L[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 開発用ファイル除外 | `*.development.js`ファイルはトレース対象外 | 常時 |
| BR-02 | 型定義除外 | `*.d.ts`および`*.map`ファイルはサーバートレースから除外 | サーバートレース時 |
| BR-03 | CI環境最適化 | Vercel CI環境（hasNextSupport）では image-optimizer, sharp を除外 | CI環境検出時 |
| BR-04 | 親ファイル全除外時の子除外 | ファイルの全親が除外対象の場合、そのファイルも除外される | shouldIgnore評価時 |
| BR-05 | standalone追加ファイル | standaloneモードではIPCサーバー、ワーカーファイルを追加トレース | output: 'standalone' 時 |

### 計算ロジック

トレース対象の判定は `shouldIgnore` 関数で再帰的に行われる。あるファイルの全ての親ファイルがignore対象であれば、そのファイル自体もignore対象となる（28-91行目）。

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

該当なし（ファイルシステム操作のみ）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENOENT | ファイル未検出 | トレース中にファイルが削除された場合 | 空文字列を返して処理継続（静的生成と並行実行のため） |
| EISDIR | ディレクトリ参照 | ファイルパスがディレクトリの場合 | 空文字列を返して処理継続 |
| EINVAL | 無効なリンク | シンボリックリンクが無効な場合 | nullを返して処理継続 |
| ENOTDIR | パスエラー | ファイルstatでディレクトリでない場合 | nullを返して処理継続 |

### リトライ仕様

リトライ不要。ファイル不存在エラーは静的生成との並行実行を考慮して寛容に処理される。

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

該当なし。

## パフォーマンス要件

- `nextBuildSpan` を使用したトレーシングにより処理時間を計測可能
- `debug('next:build:build-traces')` によるデバッグログ出力をサポート
- 大規模プロジェクトではnodeFileTraceの実行に数十秒〜数分かかる場合がある

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

- ファイルシステムの読み取りのみを行い、書き込みは`.nft.json`ファイルの生成に限定される
- `outputFileTracingRoot` によりトレース範囲が制限される

## 備考

- `@vercel/nft` はVercelが開発したNode.jsファイルトレースツールであり、静的解析によりrequire/importの依存関係を解決する
- Turbotrace関連のコードは今後削除予定（TODO コメントあり）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | collect-build-traces.ts | `packages/next/src/build/collect-build-traces.ts` | collectBuildTraces関数のパラメータ型（93-112行目）を理解する |

**読解のコツ**: `BuildTraceContext`はWebpackプラグインから渡されるコンテキストで、チャンクの依存関係情報を含む。`NodeFileTraceReasons`は`@vercel/nft`が返すファイル間の依存理由マップ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | collect-build-traces.ts | `packages/next/src/build/collect-build-traces.ts` | `collectBuildTraces`関数（93行目〜）がメインのエントリーポイント |

**主要処理フロー**:
1. **113-114行目**: 処理開始のタイムスタンプとデバッグログ
2. **116-119行目**: outputFileTracingIncludes/Excludesの取得
3. **138-143行目**: standaloneモードの判定とエントリ構築
4. **192-202行目**: サーバーエントリポイントの定義
5. **300-341行目**: nodeFileTraceの実行（非同期ファイルI/Oハンドラ付き）

#### Step 3: 除外ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | collect-build-traces.ts | `packages/next/src/build/collect-build-traces.ts` | makeIgnoreFn（28-42行目）とshouldIgnore（44-91行目）の除外判定ロジック |

**主要処理フロー**:
- **28-42行目**: `makeIgnoreFn`がpicomatchを使ってignoreパターンを事前コンパイル
- **44-91行目**: `shouldIgnore`が再帰的に親ファイルの除外状態をチェック

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

```
collectBuildTraces (collect-build-traces.ts:93)
    │
    ├─ makeIgnoreFn (collect-build-traces.ts:28)
    │      └─ picomatch (glob matching)
    │
    ├─ nodeFileTrace (@vercel/nft)
    │      ├─ readFile (非同期、ENOENT寛容)
    │      ├─ readlink (非同期、EINVAL寛容)
    │      └─ stat (非同期、ENOENT寛容)
    │
    ├─ shouldIgnore (collect-build-traces.ts:44)
    │      └─ 再帰的に親ファイルの除外状態をチェック
    │
    ├─ getFilesMapFromReasons (next-trace-entrypoints-plugin.ts)
    │
    └─ fs.writeFile (.nft.json生成)
```

### データフロー図

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

サーバーエントリ ─────▶ nodeFileTrace ──────────▶ トレースファイル集合
ポイント                    │                         │
                           ├─ shouldIgnore ──────▶ フィルタリング
                           │                         │
ビルドトレース ─────▶ getFilesMapFromReasons ──▶ ルート別依存ファイル
コンテキスト                                          │
                                                      ▼
                                              .nft.json ファイル群
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| collect-build-traces.ts | `packages/next/src/build/collect-build-traces.ts` | ソース | ビルドトレースのメイン処理 |
| next-trace-entrypoints-plugin.ts | `packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts` | ソース | Webpackプラグインによるエントリポイントトレース |
| ci-info.ts | `packages/next/src/server/ci-info.ts` | ソース | CI環境検出（hasNextSupport） |
| require-hook.ts | `packages/next/src/server/require-hook.ts` | ソース | デフォルトのモジュールオーバーライド定義 |
