# 機能設計書 5-モジュールファクトリ

## 概要

本ドキュメントは、NormalModuleFactory / ContextModuleFactoryを通じてモジュールの生成・依存解決を行う機能の設計を記述する。

### 本機能の処理概要

モジュールファクトリは、依存関係オブジェクトからモジュールインスタンスを生成する責務を持つ。NormalModuleFactoryは通常のファイルベースのモジュール生成を担当し、パス解決、ローダー適用、パーサー/ジェネレーターの選択を行う。ContextModuleFactoryはディレクトリベースの動的依存関係（require.context等）のモジュール生成を担当する。

**業務上の目的・背景**：webpackがさまざまなファイルタイプを処理するためには、依存関係の種類に応じた適切なモジュール生成が必要である。モジュールファクトリは、RuleSetに基づくローダー選択、パス解決、モジュールタイプ判定を一元的に管理し、拡張可能なモジュール生成パイプラインを提供する。

**機能の利用シーン**：Compilation内のfactorizeキューから呼び出され、依存関係オブジェクトに対応するモジュールインスタンスを生成する。プラグインはbeforeResolve/afterResolve/createModule等のフックを通じてモジュール生成プロセスをカスタマイズできる。

**主要な処理内容**：
1. NormalModuleFactory.create()による依存関係からモジュールへの変換
2. resolveフックによるモジュールパス解決（enhanced-resolve利用）
3. RuleSetCompilerによるローダーチェーンの決定
4. パーサー/ジェネレーターの選択と生成
5. ContextModuleFactory.create()によるコンテキストモジュール生成

**関連システム・外部連携**：enhanced-resolve（パス解決）、RuleSetCompiler（ルールセットコンパイラ）、Compilation.factorizeModule()（呼び出し元）と連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | モジュールファクトリは画面に直接関連しない基盤機能 |

## 機能種別

ファクトリパターン / モジュール生成 / パス解決

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data | ModuleFactoryCreateData | Yes | モジュール生成データ（コンテキスト情報、依存関係、解決オプション等） | - |
| callback | ModuleFactoryCallback | Yes | 完了コールバック | - |

### 入力データソース

- Compilationのfactorizeキューから渡されるModuleFactoryCreateData
- webpack設定のmodule.rules（RuleSet）
- resolve設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| module | Module | 生成されたモジュールインスタンス |
| fileDependencies | LazySet<string> | ファイル依存関係 |
| missingDependencies | LazySet<string> | 不足依存関係 |
| contextDependencies | LazySet<string> | コンテキスト依存関係 |

### 出力先

- Compilationのモジュール管理に渡される

## 処理フロー

### 処理シーケンス

```
1. NormalModuleFactory.create(data, callback) 呼び出し
   └─ 依存関係からリクエスト文字列を抽出
2. beforeResolve フック呼び出し
   └─ プラグインによる前処理（無視、変換等）
3. factorize フック呼び出し
   └─ resolve フック呼び出し
4. パス解決
   ├─ ローダー指定の解析（!区切り）
   ├─ リソースパスの解決（enhanced-resolve）
   └─ ローダーパスの解決
5. RuleSetによるローダー/パーサー/ジェネレーター設定の適用
   └─ module.rules設定とのマッチング
6. afterResolve フック呼び出し
   └─ プラグインによる後処理
7. createModule フック呼び出し
   └─ カスタムモジュール生成の機会
8. NormalModuleインスタンスの生成
9. module フック呼び出し
   └─ 生成後のモジュールの修正
```

### フローチャート

```mermaid
flowchart TD
    A[create呼び出し] --> B[beforeResolve フック]
    B --> C{モジュール無視?}
    C -->|Yes| D[null返却]
    C -->|No| E[factorize フック]
    E --> F[resolve フック]
    F --> G[パス解決 - enhanced-resolve]
    G --> H[RuleSetマッチング]
    H --> I[ローダーチェーン決定]
    I --> J[afterResolve フック]
    J --> K[createModule フック]
    K --> L[NormalModule生成]
    L --> M[module フック]
    M --> N[コールバック返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | beforeResolveでのモジュール無視 | beforeResolveフックがfalseを返した場合、モジュール生成をスキップ | IgnorePlugin等の使用時 |
| BR-02 | MatchResource | `!=!`パターンでマッチリソースを指定可能 | リクエスト文字列に`!=!`を含む場合 |
| BR-03 | RuleSetマッチング | ファイルパス・タイプ・リソースクエリ等でルールをマッチ | module.rules設定 |
| BR-04 | unsafeCache | 同一リクエストに対するファクトリ結果をキャッシュ | resolve.unsafeCache設定 |

### 計算ロジック

特になし。

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

該当なし。

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

該当なし。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ModuleNotFoundError | 解決エラー | モジュールパスが解決できない | パス・alias設定を確認 |
| ローダー解決エラー | 解決エラー | ローダーパスが解決できない | ローダーのインストールを確認 |

### リトライ仕様

リトライ機構はない。

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

該当なし。

## パフォーマンス要件

- unsafeCacheによるモジュール生成結果のキャッシュ
- パーサー/ジェネレーターのインスタンスキャッシュ
- RuleSetの事前コンパイルによるマッチング高速化

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

特になし。

## 備考

- NormalModuleFactoryはModuleFactoryを継承した具象クラス
- ContextModuleFactoryはrequire.context()やimport()のような動的パターンに対応

---

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

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

### 推奨読解順序

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

ResolveData型とNormalModuleFactory.create()の入出力を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NormalModuleFactory.js | `lib/NormalModuleFactory.js` | ResolveData型定義（70-84行目）でモジュール解決データの構造を理解する |
| 1-2 | NormalModuleFactory.js | `lib/NormalModuleFactory.js` | ResourceData/ResourceSchemeData型定義（86-103行目）を理解する |

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

NormalModuleFactory.create()が処理の起点である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NormalModuleFactory.js | `lib/NormalModuleFactory.js` | create()メソッドでbeforeResolve→factorize→resolve→afterResolveのフロー |

#### Step 3: コンテキストモジュールファクトリを理解する

ContextModuleFactory.create()の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ContextModuleFactory.js | `lib/ContextModuleFactory.js` | create()メソッド（109行目以降）でbeforeResolve→afterResolveのフローを理解する |
| 3-2 | ContextModuleFactory.js | `lib/ContextModuleFactory.js` | コンストラクタ（56-101行目）でフック定義を理解する |

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

```
Compilation.factorizeModule()
    │
    ├─ NormalModuleFactory.create(data, callback)
    │      ├─ hooks.beforeResolve.callAsync()
    │      ├─ hooks.factorize.callAsync()
    │      │      └─ hooks.resolve.callAsync()
    │      │             ├─ enhanced-resolve でパス解決
    │      │             ├─ RuleSetCompiler でルールマッチング
    │      │             └─ ローダー/パーサー/ジェネレーター決定
    │      ├─ hooks.afterResolve.callAsync()
    │      ├─ hooks.createModule.callAsync()
    │      └─ hooks.module.call()
    │
    └─ ContextModuleFactory.create(data, callback)
           ├─ hooks.beforeResolve.callAsync()
           ├─ リゾルバでコンテキストディレクトリ解決
           ├─ hooks.afterResolve.callAsync()
           └─ ContextModule生成
```

### データフロー図

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

ModuleFactoryCreateData ──▶ NormalModuleFactory.create()
                                │
依存関係オブジェクト ────▶ リクエスト文字列抽出
                                │
resolve設定 ──────────▶ enhanced-resolve でパス解決 ──▶ 絶対パス
                                │
module.rules ─────────▶ RuleSetマッチング ────────────▶ ローダーチェーン
                                │                          パーサー
                                │                          ジェネレーター
                                │
                         NormalModule生成 ────────────▶ ModuleFactoryResult
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NormalModuleFactory.js | `lib/NormalModuleFactory.js` | ソース | 通常モジュールのファクトリ |
| ContextModuleFactory.js | `lib/ContextModuleFactory.js` | ソース | コンテキストモジュールのファクトリ |
| ModuleFactory.js | `lib/ModuleFactory.js` | ソース | ファクトリ基底クラス |
| RuleSetCompiler.js | `lib/rules/RuleSetCompiler.js` | ソース | ルールセットコンパイラ |
| BasicEffectRulePlugin.js | `lib/rules/BasicEffectRulePlugin.js` | ソース | 基本効果ルールプラグイン |
| BasicMatcherRulePlugin.js | `lib/rules/BasicMatcherRulePlugin.js` | ソース | 基本マッチャールールプラグイン |
| UseEffectRulePlugin.js | `lib/rules/UseEffectRulePlugin.js` | ソース | use効果ルールプラグイン |
| ContextModule.js | `lib/ContextModule.js` | ソース | コンテキストモジュールクラス |
