# 機能設計書 74-WebpackOptionsApply

## 概要

本ドキュメントは、webpackの正規化済み設定オブジェクトに基づいて必要なプラグイン・モジュールルールを自動適用するWebpackOptionsApplyクラスについて、その処理内容・プラグイン適用ロジック・条件分岐を詳細に記述した機能設計書である。

### 本機能の処理概要

WebpackOptionsApplyは、正規化・デフォルト適用済みのwebpack設定オブジェクトを読み取り、設定値に応じて必要な50以上のプラグインをCompilerに自動適用する中核的な初期化機能である。

**業務上の目的・背景**：webpackは設定駆動のアーキテクチャを採用しており、多数の機能がプラグインとして実装されている。ユーザーが個々のプラグインを手動で登録する代わりに、WebpackOptionsApplyが設定値を解釈して必要なプラグインを自動的に適用することで、設定の簡潔さと機能の網羅性を両立する。

**機能の利用シーン**：webpack初期化プロセスにおいて、Compiler生成後・コンパイル開始前に呼び出される。設定オブジェクトの全セクション（externals、output、experiments、optimization、cache等）を解釈し、対応するプラグインをCompilerに登録する。

**主要な処理内容**：
1. Compilerの基本プロパティ設定（outputPath、recordsPath、name）
2. externals関連プラグイン適用（ExternalsPlugin、NodeTargetPlugin、ElectronTargetPlugin）
3. output.chunkFormat/chunkLoading/wasmLoading/libraryTypeに基づくプラグイン適用
4. devtool設定に基づくソースマッププラグイン適用
5. JavaScript/JSON/Asset/CSS/WebAssemblyモジュールプラグイン適用
6. experiments設定に基づく実験的機能プラグイン適用
7. エントリオプション処理とランタイムプラグイン適用
8. optimization設定に基づく最適化プラグイン適用（15種類以上）
9. cache設定に基づくキャッシュプラグイン適用
10. リゾルバ設定の適用

**関連システム・外部連携**：50以上の内部プラグインとの連携。tapableフックシステムを通じたイベント発火（afterPlugins、entryOption、afterResolvers）。

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

## 関連画面

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

## 機能種別

初期化処理・プラグイン自動適用

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| options | WebpackOptionsNormalizedWithDefaults | Yes | 正規化・デフォルト適用済み設定オブジェクト | 正規化済みであること |
| compiler | Compiler | Yes | Compilerインスタンス | - |
| interception | WebpackOptionsInterception | No | devtool後方互換用のインターセプションオブジェクト | - |

### 入力データソース

正規化済みwebpack設定オブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| options | WebpackOptionsNormalizedWithDefaults | 入力と同じ設定オブジェクト（参照渡し） |

### 出力先

Compilerインスタンスに各種プラグインが適用される（副作用）。

## 処理フロー

### 処理シーケンス

```
1. Compiler基本設定
   ├─ outputPath、recordsInputPath、recordsOutputPath、name設定
   └─ externals設定時はExternalsPlugin適用
2. ターゲットプリセット処理
   ├─ externalsPresets.node → NodeTargetPlugin
   ├─ externalsPresets.webAsync/web → ExternalsPlugin（URL外部化）
   ├─ externalsPresets.electron → ElectronTargetPlugin
   └─ externalsPresets.nwjs → ExternalsPlugin("nw.gui")
3. チャンクフォーマット/ローディング設定
   ├─ chunkFormat: array-push/commonjs/module
   ├─ enabledChunkLoadingTypes
   ├─ enabledWasmLoadingTypes
   └─ enabledLibraryTypes
4. 出力設定プラグイン
   ├─ pathinfo → ModuleInfoHeaderPlugin
   ├─ clean → CleanPlugin
   └─ dotenv → DotenvPlugin
5. devtool設定 → SourceMap/EvalDevToolプラグイン
6. モジュールプラグイン
   ├─ JavascriptModulesPlugin（常時）
   ├─ JsonModulesPlugin（常時）
   ├─ AssetModulesPlugin（常時）
   ├─ CssModulesPlugin（experiments.css時）
   └─ WebAssemblyModulesPlugin（experiments.syncWebAssembly/asyncWebAssembly時）
7. experiments設定
   ├─ lazyCompilation → LazyCompilationPlugin
   ├─ buildHttp → HttpUriPlugin
   └─ deferImport → acorn-import-phases拡張
8. 依存性解析プラグイン
   ├─ HarmonyModulesPlugin、CommonJsPlugin、LoaderPlugin
   ├─ AMDPlugin、RequireJsStuffPlugin（amd有効時）
   └─ ImportPlugin、SystemPlugin、URLPlugin、WorkerPlugin等
9. optimization設定（15種類以上）
   ├─ removeAvailableModules → RemoveParentModulesPlugin
   ├─ sideEffects → SideEffectsFlagPlugin
   ├─ usedExports → FlagDependencyUsagePlugin
   ├─ moduleIds/chunkIds → 各IDプラグイン
   └─ minimize → minimizerの適用
10. キャッシュ設定
    ├─ memory → MemoryCachePlugin/MemoryWithGcCachePlugin
    └─ filesystem → IdleFileCachePlugin + PackFileCacheStrategy
11. リゾルバ設定（normal/context/loader）
12. フック発火（afterPlugins、afterResolvers）
```

### フローチャート

```mermaid
flowchart TD
    A[process開始] --> B[Compiler基本設定]
    B --> C[externals処理]
    C --> D[ターゲットプリセット]
    D --> E[チャンクフォーマット/ローディング]
    E --> F[devtoolプラグイン]
    F --> G[モジュールプラグイン]
    G --> H[experiments処理]
    H --> I[依存性解析プラグイン]
    I --> J[optimization処理]
    J --> K[キャッシュ処理]
    K --> L[リゾルバ設定]
    L --> M[afterPlugins/afterResolversフック発火]
    M --> N[options返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-01 | outputModule制約 | output.module=trueはexperiments.outputModule有効時のみ許可 | experiments.outputModule未有効時 |
| BR-74-02 | moduleIds選択 | natural/named/hashed/deterministic/sizeの5種のIDプラグインから選択 | optimization.moduleIdsが指定されている場合 |
| BR-74-03 | chunkIds選択 | natural/named/deterministic/size/total-sizeの5種のIDプラグインから選択 | optimization.chunkIdsが指定されている場合 |
| BR-74-04 | hashed非推奨 | moduleIds: "hashed"使用時にWarnDeprecatedOptionPluginで非推奨警告 | moduleIds==="hashed"の場合 |
| BR-74-05 | nodeEnv設定 | optimization.nodeEnvが指定されている場合、DefinePluginでprocess.env.NODE_ENVとimport.meta.env.NODE_ENVを設定 | nodeEnvがtruthyの場合 |
| BR-74-06 | FlagDependencyExports強制適用 | library type=module/commonjs-static/modern-moduleの場合、optimization.providedExports無効でもFlagDependencyExportsPluginを適用 | 該当libraryType使用時 |

### 計算ロジック

特になし。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | output.module=trueでexperiments.outputModule未有効 | experiments.outputModuleを有効にする |
| - | Error | externalsType="module"でexperiments.outputModule未有効 | experiments.outputModuleを有効にする |
| - | Error | 未サポートのchunkFormat指定 | array-push/commonjs/moduleのいずれかを指定 |
| - | Error | inputFileSystemが未設定 | NodeEnvironmentPlugin等を先に適用 |

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

50以上のプラグインの遅延require（必要時のみインポート）により、初期化時間を最適化している。

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

特になし。

## 備考

- WebpackOptionsApplyはOptionsApplyクラスを継承しているが、主要なロジックはprocessメソッドに集約されている
- プラグインの適用順序は処理の依存関係に基づいて決定されており、順序の変更は予期しない動作を引き起こす可能性がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebpackOptionsApply.js | `lib/WebpackOptionsApply.js` | 78-84行目のimport文で使用される型定義を確認 |

**読解のコツ**: WebpackOptionsApplyはWebpackOptionsNormalizedWithDefaults型の設定を受け取る。この型はdefaults.jsで定義され、全プロパティがNonNullableとなっている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WebpackOptionsApply.js | `lib/WebpackOptionsApply.js` | processメソッド（98-938行目）がエントリーポイント |

**主要処理フロー**:
1. **99-102行目**: Compilerの基本プロパティ設定
2. **104-211行目**: externals/externalsPresets処理
3. **215-291行目**: チャンクフォーマット/ローディング/ライブラリタイプ処理
4. **317-371行目**: devtool処理
5. **373-425行目**: モジュール/experiments処理
6. **503-555行目**: 依存性解析プラグイン群
7. **563-765行目**: optimization設定によるプラグイン適用
8. **792-895行目**: キャッシュ設定処理
9. **908-936行目**: リゾルバ設定とフック発火

#### Step 3: プラグイン適用パターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WebpackOptionsApply.js | `lib/WebpackOptionsApply.js` | 遅延require + new Plugin().apply(compiler)のパターン |

**読解のコツ**: ほぼ全てのプラグインが `const Plugin = require("..."); new Plugin(...).apply(compiler);` の形式で遅延ロードされている。これはメモリ効率と起動速度の最適化のためである。

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

```
WebpackOptionsApply.process(options, compiler)
    |
    +-- ExternalsPlugin / NodeTargetPlugin / ElectronTargetPlugin
    +-- ArrayPushCallbackChunkFormatPlugin / CommonJsChunkFormatPlugin / ModuleChunkFormatPlugin
    +-- EnableChunkLoadingPlugin / EnableWasmLoadingPlugin / EnableLibraryPlugin
    +-- SourceMapDevToolPlugin / EvalSourceMapDevToolPlugin / EvalDevToolModulePlugin
    +-- JavascriptModulesPlugin / JsonModulesPlugin / AssetModulesPlugin
    +-- CssModulesPlugin / WebAssemblyModulesPlugin / AsyncWebAssemblyModulesPlugin
    +-- LazyCompilationPlugin / HttpUriPlugin
    +-- EntryOptionPlugin → compiler.hooks.entryOption.call()
    +-- RuntimePlugin / InferAsyncModulesPlugin
    +-- HarmonyModulesPlugin / CommonJsPlugin / ImportPlugin / ...
    +-- SideEffectsFlagPlugin / FlagDependencyExportsPlugin / FlagDependencyUsagePlugin
    +-- InnerGraphPlugin / MangleExportsPlugin / ModuleConcatenationPlugin
    +-- SplitChunksPlugin / RuntimeChunkPlugin
    +-- DeterministicModuleIdsPlugin / NamedChunkIdsPlugin / ...
    +-- DefinePlugin (NODE_ENV)
    +-- SizeLimitsPlugin
    +-- MemoryCachePlugin / IdleFileCachePlugin + PackFileCacheStrategy
    +-- ResolverCachePlugin
    +-- compiler.hooks.afterPlugins.call()
    +-- resolverFactory.hooks.resolveOptions (normal/context/loader)
    +-- compiler.hooks.afterResolvers.call()
```

### データフロー図

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

WebpackOptionsNormalized    WebpackOptionsApply.process()
WithDefaults =============> 設定値に基づく条件分岐 ============> Compiler
                                |                              (プラグイン登録済み)
                                v
                          50+プラグインの
                          条件付き適用
                                |
                                v
                          afterPlugins
                          afterResolvers
                          フック発火
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WebpackOptionsApply.js | `lib/WebpackOptionsApply.js` | ソース | 設定に基づくプラグイン自動適用の本体 |
| OptionsApply.js | `lib/OptionsApply.js` | ソース | WebpackOptionsApplyの基底クラス |
| Compiler.js | `lib/Compiler.js` | ソース | プラグインが適用されるCompilerインスタンス |
| normalization.js | `lib/config/normalization.js` | ソース | 入力設定の正規化（前段処理） |
| defaults.js | `lib/config/defaults.js` | ソース | デフォルト値の適用（前段処理） |
| cleverMerge.js | `lib/util/cleverMerge.js` | ソース | リゾルバ設定のマージに使用 |
