# 機能設計書 73-オプション正規化・デフォルト適用

## 概要

本ドキュメントは、webpackの設定値の正規化処理とデフォルト値の適用処理について、その変換ロジック・対応するオプション項目・処理順序を詳細に記述した機能設計書である。

### 本機能の処理概要

オプション正規化・デフォルト適用機能は、ユーザーが指定したwebpack設定オブジェクトをコンパイラが処理可能な正規化形式に変換し、未指定のオプションにデフォルト値を適用する機能である。

**業務上の目的・背景**：webpackは多様な設定形式（文字列、配列、オブジェクト、関数等）を受け付けるため、内部処理に入る前に統一的な形式に正規化する必要がある。また、未指定のオプションに適切なデフォルト値を適用することで、最小限の設定でwebpackを利用できるようにしている。

**機能の利用シーン**：webpack.config.jsの設定オブジェクトがCompilerに渡された直後、WebpackOptionsApplyの実行前に正規化とデフォルト適用が行われる。

**主要な処理内容**：
1. getNormalizedWebpackOptions: 設定オブジェクトの正規化（entry、output、module、optimization等の各セクション）
2. applyWebpackOptionsDefaults: ターゲットプラットフォームに基づくデフォルト値の適用
3. applyWebpackOptionsInterception: devtoolオプションの後方互換性のためのProxy設定
4. entry正規化: 文字列/配列/オブジェクト形式を統一的なEntryStaticNormalized形式に変換
5. runtimeChunk正規化: "single"/"multiple"/true/false/オブジェクト形式をname関数に統一
6. 非推奨オプションの変換: noEmitOnErrors → emitOnErrors等

**関連システム・外部連携**：targetオプションに基づくプラットフォーム判定（target.js）。browserslistとの連携（browserslistTargetHandler.js）。

**権限による制御**：本機能に権限による制御はない。

## 関連画面

本機能に直接関連する画面はない。設定値の正規化はビルドプロセスの初期化段階で行われる内部処理である。

## 機能種別

データ変換処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| config | WebpackOptions | Yes | ユーザー指定のwebpack設定オブジェクト | バリデーション済みであること |

### 入力データソース

- webpack.config.jsまたはCLI引数から生成されたwebpack設定オブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| normalizedOptions | WebpackOptionsNormalized | 正規化されたwebpack設定オブジェクト |

### 出力先

正規化された設定オブジェクトはCompilerインスタンスに渡される。

## 処理フロー

### 処理シーケンス

```
1. getNormalizedWebpackOptions(config)
   ├─ entry正規化
   │   ├─ 文字列 → { main: { import: [entry] } }
   │   ├─ 配列 → { main: { import: entry } }
   │   ├─ オブジェクト → 各エントリをEntryDescriptionNormalized形式に変換
   │   └─ 関数 → ラップして正規化された値をPromiseで返す
   ├─ cache正規化
   │   ├─ true → { type: "memory", maxGenerations: undefined }
   │   ├─ false → false
   │   ├─ "memory" → { type: "memory", maxGenerations: ... }
   │   └─ "filesystem" → 全プロパティを明示的にコピー
   ├─ output正規化（library、trustedTypes等のネスト構造を平坦化）
   ├─ optimization正規化
   │   ├─ runtimeChunk: "single" → { name: () => "runtime" }
   │   ├─ runtimeChunk: true/"multiple" → { name: (ep) => `runtime~${ep.name}` }
   │   ├─ noEmitOnErrors → emitOnErrorsに変換（非推奨警告付き）
   │   └─ splitChunks、minimizer等のネスト正規化
   ├─ module正規化（parser、generator、rules等）
   ├─ stats正規化（false→"none"、true→"normal"、文字列→preset）
   ├─ ignoreWarnings正規化（RegExp/オブジェクトを関数に変換）
   └─ その他各セクションのcloneObject/nestedConfig処理
2. applyWebpackOptionsDefaults(options)
   └─ ターゲットプラットフォームに基づくデフォルト値適用
3. applyWebpackOptionsInterception(options)
   └─ devtoolプロパティのProxy設定（後方互換性）
```

### フローチャート

```mermaid
flowchart TD
    A[ユーザー設定] --> B[getNormalizedWebpackOptions]
    B --> C[entry正規化]
    B --> D[cache正規化]
    B --> E[output正規化]
    B --> F[optimization正規化]
    B --> G[module正規化]
    B --> H[stats正規化]
    B --> I[その他正規化]
    C --> J[WebpackOptionsNormalized]
    D --> J
    E --> J
    F --> J
    G --> J
    H --> J
    I --> J
    J --> K[applyWebpackOptionsDefaults]
    K --> L[ターゲット判定]
    L --> M[デフォルト値適用]
    M --> N[applyWebpackOptionsInterception]
    N --> O[Proxy設定済み設定オブジェクト]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | entry正規化 | 文字列・配列のentryは{ main: { import: [...] } }形式に変換 | entryが文字列または配列の場合 |
| BR-73-02 | entryのdependOn正規化 | 文字列のdependOnを配列に変換 | dependOnが文字列の場合 |
| BR-73-03 | runtimeChunk正規化 | "single" → { name: () => "runtime" }、true/"multiple" → { name: (ep) => `runtime~${ep.name}` } | runtimeChunkが文字列またはboolean |
| BR-73-04 | noEmitOnErrors非推奨変換 | noEmitOnErrorsをemitOnErrorsに反転変換し非推奨警告を出力 | noEmitOnErrorsが定義されている場合 |
| BR-73-05 | stats正規化 | false→{preset:"none"}、true→{preset:"normal"}、文字列→{preset:文字列} | statsがboolean/文字列の場合 |
| BR-73-06 | cache正規化 | true→{type:"memory"}、"filesystem"→全プロパティを明示コピー | cacheがboolean/オブジェクトの場合 |
| BR-73-07 | library正規化 | library/libraryTarget/auxiliaryComment等を統合されたlibraryオブジェクトに変換 | outputにlibrary関連設定がある場合 |
| BR-73-08 | ignoreWarnings正規化 | RegExpオブジェクトを{message: RegExp}のフィルタ関数に変換 | ignoreWarningsにRegExpが含まれる場合 |
| BR-73-09 | devtool後方互換 | 配列形式のdevtoolをProxy経由で旧形式（文字列）として読み取り可能にする | futureDefaultsが無効の場合 |
| BR-73-10 | defaultSizeTypes | splitChunks.defaultSizeTypesが未指定の場合は["..."]をデフォルト設定 | splitChunksが定義されている場合 |

### 計算ロジック

特になし。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | cache.typeが"memory"/"filesystem"以外の場合 | "Not implemented cache.type"エラー |
| DEP_WEBPACK_CONFIGURATION_OPTIMIZATION_NO_EMIT_ON_ERRORS | 非推奨警告 | noEmitOnErrorsとemitOnErrorsが矛盾する場合 | noEmitOnErrorsを削除し、emitOnErrorsのみ使用する |

### リトライ仕様

リトライは不要。設定修正後に再実行する。

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

トランザクション管理は不要。

## パフォーマンス要件

正規化処理は起動時に一度だけ実行される。浅いコピー（スプレッド演算子）が多用されるが、設定オブジェクトのサイズは通常小さいため性能問題にはならない。

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

特になし。

## 備考

- normalization.jsは正規化処理を担い、defaults.jsはデフォルト値の適用を担う。二者の責務は明確に分離されている。
- ヘルパー関数（nestedConfig、cloneObject、optionalNestedConfig、nestedArray、keyedNestedConfig）により、null/undefined安全な正規化処理が実現されている。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebpackOptions型定義 | `declarations/WebpackOptions.d.ts` | WebpackOptions（入力）とWebpackOptionsNormalized（出力）の型定義の違い |

**読解のコツ**: NormalizedサフィックスがついたTypesは正規化後の型を表す。import/dependOn等が必ず配列形式になる等の違いがある。

#### Step 2: 正規化処理のエントリーポイント

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | normalization.js | `lib/config/normalization.js` | getNormalizedWebpackOptions関数。設定全体の正規化ロジック |

**主要処理フロー**:
1. **57-65行目**: nestedConfig/cloneObject/optionalNestedConfig等のヘルパー関数定義
2. **132-499行目**: getNormalizedWebpackOptions関数本体（全設定セクションの正規化）
3. **505-561行目**: getNormalizedEntryStatic関数（entry正規化の詳細）
4. **567-588行目**: getNormalizedOptimizationRuntimeChunk関数
5. **594-677行目**: applyWebpackOptionsInterception関数（devtoolのProxy設定）

#### Step 3: デフォルト値の適用処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | defaults.js | `lib/config/defaults.js` | applyWebpackOptionsDefaults関数。ターゲットに基づくデフォルト値適用 |

**主要処理フロー**:
- **207-210行目**: DEFAULTS定数（HASH_FUNCTION: "md4"等）
- **221-240行目**: D関数（定数デフォルト設定）、F関数（ファクトリデフォルト設定）ヘルパー

#### Step 4: ターゲット判定処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | target.js | `lib/config/target.js` | getDefaultTarget、getTargetProperties関数 |
| 4-2 | browserslistTargetHandler.js | `lib/config/browserslistTargetHandler.js` | browserslistとの連携処理 |

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

```
webpack(config)
    |
    +-- getNormalizedWebpackOptions(config)
    |       |
    |       +-- getNormalizedEntryStatic(entry)
    |       +-- getNormalizedOptimizationRuntimeChunk(runtimeChunk)
    |       +-- nestedConfig() / cloneObject() / optionalNestedConfig()
    |       +-- keyedNestedConfig()
    |
    +-- applyWebpackOptionsDefaults(options)
    |       |
    |       +-- getDefaultTarget(context)
    |       +-- getTargetProperties(target, context)
    |       +-- D() / F() ヘルパーによるデフォルト値設定
    |
    +-- applyWebpackOptionsInterception(options)
            |
            +-- new Proxy(options, handler) [devtool後方互換]
```

### データフロー図

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

WebpackOptions             normalization.js
  (ユーザー設定) --------> getNormalizedWebpackOptions() ---> WebpackOptionsNormalized
                                                                  |
                           defaults.js                            v
                   +-----> applyWebpackOptionsDefaults() ---> WebpackOptionsNormalizedWithDefaults
                   |                                              |
target.js          |       normalization.js                       v
  getTargetProperties()    applyWebpackOptionsInterception() -> Proxy化設定
  getDefaultTarget()                                              |
                                                                  v
                                                           WebpackOptionsApply
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| normalization.js | `lib/config/normalization.js` | ソース | 設定の正規化処理（メイン） |
| defaults.js | `lib/config/defaults.js` | ソース | デフォルト値の適用 |
| target.js | `lib/config/target.js` | ソース | ターゲットプラットフォーム判定 |
| browserslistTargetHandler.js | `lib/config/browserslistTargetHandler.js` | ソース | browserslist連携 |
| WebpackOptions.d.ts | `declarations/WebpackOptions.d.ts` | 型定義 | 入力・出力の型定義 |
