# 機能設計書 81-next.config.js / next.config.ts

## 概要

本ドキュメントは、Next.jsの設定ファイル（`next.config.js` / `next.config.ts`）の読み込み・検証・正規化処理に関する機能設計書である。Next.jsアプリケーションのビルド・ルーティング・画像最適化等の全体設定を管理する中核的な設定機構について記述する。

### 本機能の処理概要

**業務上の目的・背景**：Next.jsは多様な設定オプションを提供しており、プロジェクトごとに異なるビルド設定・ルーティング・最適化設定をカスタマイズする必要がある。本機能は設定ファイルの読み込みから検証、デフォルト値のマージまでを一貫して行い、フレームワーク全体に一貫した設定情報を提供する。

**機能の利用シーン**：`next dev`、`next build`、`next start` の各コマンド実行時に必ず呼び出される。開発者がプロジェクトルートに配置した `next.config.js` または `next.config.ts` ファイルから設定を読み込み、ランタイム全体で使用される設定オブジェクトを構築する。

**主要な処理内容**：
1. プロジェクトルートから設定ファイル（`next.config.js`、`next.config.mjs`、`next.config.ts`）を検索・読み込み
2. TypeScript設定ファイル（`.ts`）の場合はSWCによるトランスパイルを実行
3. 設定関数（フェーズベース設定）の場合は現在のフェーズで実行
4. デフォルト設定とユーザー設定のマージ
5. 非推奨オプションの警告・移行処理
6. Zodスキーマによるバリデーション（画像設定など致命的エラーの検出）
7. basePath、assetPrefix、i18n、images等の各設定値の正規化

**関連システム・外部連携**：SWCトランスパイラ（TypeScript設定ファイルの変換）、@next/envパッケージ（環境変数の読み込み）、Zodバリデーションライブラリ（設定値の検証）

**権限による制御**：特になし。設定ファイルはプロジェクト所有者が管理する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面を持たない内部設定機構である |

## 機能種別

設定管理 / バリデーション / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dir | string | Yes | プロジェクトルートディレクトリのパス | 存在するディレクトリであること |
| phase | PHASE_TYPE | Yes | 現在の実行フェーズ（PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD等） | 定義済みフェーズ定数であること |
| rawConfig | NextConfig | No | ユーザー定義の設定オブジェクト | Zodスキーマによる検証 |
| silent | boolean | No | 警告メッセージの抑制フラグ | - |

### 入力データソース

- プロジェクトルートに配置された `next.config.js`、`next.config.mjs`、または `next.config.ts` ファイル
- デフォルト設定（`config-shared.ts` の `defaultConfig`）
- 環境変数（`@next/env` パッケージ経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| NextConfigComplete | object | すべてのプロパティがデフォルト値で補完された完全な設定オブジェクト |
| configFile | string | 使用された設定ファイルのパス |
| configFileName | string | 使用された設定ファイル名 |

### 出力先

フレームワーク内部のランタイムモジュール群（サーバー、ビルダー、開発サーバー等）

## 処理フロー

### 処理シーケンス

```
1. 設定ファイルの検索（findUp）
   └─ next.config.js / next.config.mjs / next.config.ts を順に検索
2. 設定ファイルの読み込み
   └─ .ts ファイルの場合は transpileConfig() でSWCトランスパイル
   └─ .mjs ファイルの場合は dynamic import
   └─ .js ファイルの場合は require
3. フェーズベース設定の解決
   └─ 設定が関数の場合、現在のフェーズを引数に実行
4. 設定のバリデーション
   └─ Zodスキーマによるバリデーション（警告/致命的エラーの分離）
5. 非推奨オプションの検出と警告
   └─ checkDeprecations() で非推奨オプションを検出
   └─ warnOptionHasBeenMovedOutOfExperimental() で移行済みオプションを処理
6. デフォルト値のマージと正規化
   └─ assignDefaultsAndValidate() でデフォルト設定とマージ
   └─ basePath, assetPrefix, images, i18n等の個別正規化
7. 完全な設定オブジェクト（NextConfigComplete）を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[設定ファイル検索]
    B --> C{ファイル拡張子}
    C -->|.ts| D[SWCトランスパイル]
    C -->|.mjs| E[dynamic import]
    C -->|.js| F[require]
    D --> G[設定オブジェクト取得]
    E --> G
    F --> G
    G --> H{設定は関数?}
    H -->|Yes| I[フェーズで関数実行]
    H -->|No| J[そのまま使用]
    I --> K[Zodバリデーション]
    J --> K
    K --> L{致命的エラー?}
    L -->|Yes| M[エラースロー]
    L -->|No| N[非推奨チェック]
    N --> O[デフォルト値マージ]
    O --> P[各設定値の正規化]
    P --> Q[NextConfigComplete返却]
    Q --> R[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | 設定ファイル優先度 | next.config.ts > next.config.js > next.config.mjs の順で検索 | 複数の設定ファイルが存在する場合 |
| BR-81-02 | フェーズベース設定 | 設定がエクスポートする関数の場合、phase引数で呼び出す | 設定ファイルが関数をエクスポートする場合 |
| BR-81-03 | distDir制約 | distDirに"public"は使用不可 | distDir設定時 |
| BR-81-04 | basePath制約 | basePathは"/"で始まり"/"で終わらない文字列であること | basePath設定時 |
| BR-81-05 | 画像設定バリデーション | images設定のバリデーションエラーは致命的エラーとして扱う | 画像設定が不正な場合 |
| BR-81-06 | 非推奨オプション移行 | experimental下から移動されたオプションは自動的に新しい場所にコピー | 非推奨オプション使用時 |

### 計算ロジック

特になし。

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

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

本機能はデータベースに対する操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ZodValidationError | 設定値がスキーマに合致しない | 設定ファイルを修正する |
| - | Error | distDirが"public"に設定 | distDirを別の値に変更する |
| - | Error | basePathの形式が不正 | basePath形式を修正する |
| - | Error | pageExtensionsが空配列 | pageExtensionsに有効な拡張子を追加する |
| - | HardDeprecatedConfigError | 削除済みオプション（experimental.ppr等）の使用 | 新しいオプション名に移行する |

### リトライ仕様

リトライは行わない。設定エラーはプロセスを終了する。

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

トランザクション管理は不要（ファイル読み込みのみ）。

## パフォーマンス要件

設定読み込みはアプリケーション起動時に1回のみ実行される。TypeScript設定ファイルのトランスパイルに数百ミリ秒かかる場合がある。

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

- 設定ファイルはプロジェクトの任意のコードを実行できるため、信頼できるソースからのみ設定ファイルを使用する
- `env` 設定で `NODE_*` や `__*` プレフィックスのキーは使用不可（`errorIfEnvConflicted`による検証）

## 備考

- 設定ファイルが存在しない場合、デフォルト設定のみで動作する
- `next.config.ts` のサポートにはSWCバインディングが必要
- Node.js v22.10.0以降では、ネイティブTypeScriptサポートによるトランスパイルも試行される

---

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

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

### 推奨読解順序

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

設定オブジェクトの型定義を理解することが最も重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config-shared.ts | `packages/next/src/server/config-shared.ts` | `NextConfig` インターフェース（999行目付近）で全設定項目を定義。`NextConfigComplete`型（19行目）が必須フィールドを含む完全な型 |
| 1-2 | config-shared.ts | `packages/next/src/server/config-shared.ts` | `ExperimentalConfig` インターフェース（324行目）で実験的機能の設定項目を定義 |
| 1-3 | config-shared.ts | `packages/next/src/server/config-shared.ts` | `I18NConfig` インターフェース（36行目）、`TypeScriptConfig`（50行目）等の個別設定型 |

**読解のコツ**: `NextConfigComplete` は `Required<Omit<NextConfig, 'configFile'>>` として定義されており、`NextConfig` の全プロパティが必須化されたものである。defaultConfigオブジェクトがこの型のデフォルト値を提供する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.ts | `packages/next/src/server/config.ts` | `loadConfig` 関数がメインエントリーポイント。設定ファイルの検索・読み込み・検証の全体フローを管理する |

**主要処理フロー**:
1. **1-48行目**: インポートと依存モジュールの読み込み
2. **52-96行目**: `normalizeNextConfigZodErrors` - Zodバリデーションエラーの警告/致命的エラー分類
3. **98-123行目**: `warnOptionHasBeenDeprecated` - 非推奨オプションの警告
4. **125-208行目**: `checkDeprecations` - 全非推奨オプションの一括チェック
5. **274-499行目**: `assignDefaultsAndValidate` - デフォルト値マージと設定値検証

#### Step 3: TypeScript設定ファイルのトランスパイル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | transpile-config.ts | `packages/next/src/build/next-config-ts/transpile-config.ts` | `transpileConfig` 関数（139行目）がTypeScript設定ファイルのトランスパイルを担当 |
| 3-2 | require-hook.ts | `packages/next/src/build/next-config-ts/require-hook.ts` | トランスパイル済みコードの実行時にrequireフックを登録 |

**主要処理フロー**:
- **148-181行目**: Node.jsネイティブTypeScriptサポートの試行
- **184-185行目**: tsconfig.jsonの読み込みとSWCオプションの構築
- **193-241行目**: `handleCJS` でSWCトランスパイルと `requireFromString` によるモジュール評価

#### Step 4: 設定値の正規化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.ts | `packages/next/src/server/config.ts` | **301-323行目**: distDir、pageExtensionsの検証 |
| 4-2 | config.ts | `packages/next/src/server/config.ts` | **410-500行目**: output、basePath、assetPrefixの検証と正規化 |
| 4-3 | config.ts | `packages/next/src/server/config.ts` | **502-646行目**: images設定の詳細な検証と正規化 |

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

```
loadConfig(dir, phase)
    |
    +-- findUp(CONFIG_FILES)                 # 設定ファイル検索
    |
    +-- transpileConfig()                    # .tsファイルのトランスパイル
    |       +-- loadTsConfig()               # tsconfig.json読み込み
    |       +-- resolveSWCOptions()           # SWCオプション構築
    |       +-- handleCJS()                  # SWCトランスパイル+評価
    |           +-- loadBindings()           # SWCバインディング読み込み
    |           +-- bindings.transform()     # コード変換
    |           +-- requireFromString()      # モジュール評価
    |
    +-- normalizeConfig()                    # 基本正規化
    |
    +-- Zodスキーマバリデーション
    |       +-- normalizeNextConfigZodErrors()
    |
    +-- checkDeprecations()                  # 非推奨チェック
    |       +-- warnOptionHasBeenDeprecated()
    |
    +-- assignDefaultsAndValidate()          # デフォルト値マージ+検証
    |       +-- warnOptionHasBeenMovedOutOfExperimental()
    |       +-- warnCustomizedOption()
    |
    +-- loadEnvConfig()                      # 環境変数読み込み
```

### データフロー図

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

next.config.ts ───────▶ transpileConfig() ──┐
next.config.js ───────▶ require/import ─────┤
next.config.mjs ──────▶ dynamic import ─────┤
                                             ├──▶ normalizeConfig()
defaultConfig ────────────────────────────────┤
                                             ├──▶ assignDefaultsAndValidate()
Zodスキーマ ──────────────────────────────────┤
                                             └──▶ NextConfigComplete
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.ts | `packages/next/src/server/config.ts` | ソース | 設定読み込み・検証のメインモジュール |
| config-shared.ts | `packages/next/src/server/config-shared.ts` | ソース | 設定型定義・デフォルト値・正規化関数 |
| transpile-config.ts | `packages/next/src/build/next-config-ts/transpile-config.ts` | ソース | TypeScript設定ファイルのトランスパイル |
| require-hook.ts | `packages/next/src/build/next-config-ts/require-hook.ts` | ソース | トランスパイル済みコードのrequireフック |
| constants.ts | `packages/next/src/shared/lib/constants.ts` | ソース | CONFIG_FILES、PHASE_*定数の定義 |
| image-config.ts | `packages/next/src/shared/lib/image-config.ts` | ソース | 画像設定のデフォルト値 |
| static-env.ts | `packages/next/src/lib/static-env.ts` | ソース | 静的環境変数の処理 |
