# 機能設計書 3-モジュール処理

## 概要

本ドキュメントは、webpackのコアバンドリング機能であるモジュール処理の機能設計を記述する。NormalModule / RawModule / CssModule / DllModule / ExternalModule / DelegatedModule等の各モジュールタイプを解析・変換する機能である。

### 本機能の処理概要

webpackのモジュール処理は、ファイルシステム上のソースコードを読み込み、ローダーによる変換、パーサーによる解析、コードジェネレーターによるコード生成を行う一連のパイプラインである。NormalModuleが最も一般的なモジュールタイプであり、JavaScript、CSS、アセットファイルなどを処理する。

**業務上の目的・背景**：アプリケーション開発では、JavaScript、CSS、画像、WebAssembly等の多様なファイル形式を扱う必要がある。モジュール処理機能は、これらの多様なファイルをwebpackが統一的に処理できるようにし、依存関係の解析・変換・最適化を可能にする。

**機能の利用シーン**：すべてのwebpackビルドにおいて、各ソースファイルがモジュールとして処理される。require()やimport文で参照されるファイルはすべてモジュール処理の対象となる。画面機能マッピングでは、多くの画面で「各requireモジュールの解析・変換処理」として参照されている。

**主要な処理内容**：
1. NormalModuleのbuild()によるローダーチェーンの実行とソースコード変換
2. パーサー（JavascriptParser等）による依存関係の抽出
3. コードジェネレーターによる出力コードの生成
4. ソースマップの処理と生成
5. ハッシュ計算によるキャッシュバスティング対応

**関連システム・外部連携**：loader-runner（ローダー実行エンジン）、webpack-sources（ソースコード抽象化）、acorn（JavaScriptパーサーエンジン）と連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Page A (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 2 | Page B (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 3 | Page C (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 4 | Page D (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 5 | Page E (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 6 | Page F (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 7 | Page G (many-pages) | 補助機能 | 各requireモジュールの解析・変換処理 |
| 10 | Login (reexport-components) | 補助機能 | Reactコンポーネントモジュールの解析・変換 |
| 11 | Dashboard (reexport-components) | 補助機能 | Reactコンポーネントモジュールの解析・変換 |

## 機能種別

データ変換 / パース処理 / コード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| request | string | Yes | モジュールリクエスト文字列（ローダー付き） | - |
| userRequest | string | Yes | ユーザーが意図したリクエスト（ローダーなし） | - |
| rawRequest | string | Yes | 解決前の生リクエスト | - |
| resource | string | Yes | リソースファイルパス | ファイルが存在すること |
| loaders | LoaderItem[] | Yes | 適用するローダーリスト | - |
| parser | Parser | Yes | 使用するパーサーインスタンス | - |
| generator | Generator | Yes | 使用するジェネレーターインスタンス | - |
| type | string | Yes | モジュールタイプ（javascript/auto等） | 有効なタイプであること |

### 入力データソース

- ファイルシステム上のソースコードファイル
- ローダー設定（webpack.config.jsのmodule.rules）
- パーサー/ジェネレーター設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| _source | Source | 変換後のソースコード |
| buildInfo | BuildInfo | ビルド情報（依存関係、キャッシュ情報等） |
| buildMeta | BuildMeta | ビルドメタ情報（ESM/CJS判定等） |
| dependencies | Dependency[] | 検出された依存関係 |
| blocks | AsyncDependenciesBlock[] | 非同期依存関係ブロック |

### 出力先

- Compilationのモジュールグラフに格納される
- CodeGenerationResultsにコード生成結果が格納される

## 処理フロー

### 処理シーケンス

```
1. NormalModule.build() 呼び出し
   └─ needBuildフックでリビルド要否を判定
2. doBuild() 実行
   ├─ beforeLoadersフック呼び出し
   ├─ runLoaders() でローダーチェーン実行
   ├─ ソースマップの処理
   └─ processResultフック呼び出し
3. ソースオブジェクトの生成
   └─ OriginalSource / SourceMapSource / RawSource
4. パーサーによる解析
   ├─ beforeParseフック呼び出し
   ├─ parser.parse() でAST生成・依存関係抽出
   └─ dependencies / blocks に依存関係を登録
5. ハッシュ計算
   └─ updateHash() でモジュールハッシュを更新
6. コード生成
   └─ generator.generate() で出力コードを生成
```

### フローチャート

```mermaid
flowchart TD
    A[build呼び出し] --> B{needBuild?}
    B -->|No| C[キャッシュ済み結果を使用]
    B -->|Yes| D[doBuild - ローダー実行]
    D --> E[ソースオブジェクト生成]
    E --> F[パーサーで解析]
    F --> G[依存関係抽出]
    G --> H[ビルド情報更新]
    H --> I[完了コールバック]
    C --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ローダー逆順実行 | ローダーはright-to-left（下から上）の順に実行される | doBuild()時 |
| BR-02 | バイナリモジュール判定 | type名がassetまたはwebassemblyで始まる場合はbinaryフラグがtrue | コンストラクタ時 |
| BR-03 | noParse判定 | noParse設定に一致するモジュールはパース処理をスキップ | build()時 |
| BR-04 | ソースマップ抽出 | extractSourceMap設定がtrueの場合、ソースマップを抽出する | doBuild()後 |

### 計算ロジック

特になし。

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

該当なし。データベースは使用しない。

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

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ModuleBuildError | ビルドエラー | ローダー実行中にエラー発生 | ローダー設定・ソースコードを確認 |
| ModuleParseError | パースエラー | パーサーによる解析に失敗 | ソースコードの構文を修正 |
| ModuleError | モジュールエラー | ローダーがerrorを発出 | エラーメッセージを確認し対処 |
| ModuleWarning | モジュール警告 | ローダーがwarningを発出 | 警告内容を確認 |
| InvalidDependenciesModuleWarning | 依存関係警告 | ビルド依存関係が無効 | 依存関係設定を見直す |
| UnhandledSchemeError | スキームエラー | 未対応のURLスキーム | スキームハンドラを追加 |

### リトライ仕様

リトライ機構は実装されていない。

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

該当なし。

## パフォーマンス要件

- ローダーの結果はキャッシュ可能（buildInfo.cacheableフラグによる制御）
- needBuild()フックによりリビルドの要否を判定し、不要なビルドをスキップ
- unsafeCacheによるモジュールファクトリ結果のキャッシュ

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

- ローダーはNode.js環境で任意のコードを実行するため、信頼されたローダーのみを使用すること
- ソースマップにはファイルパス情報が含まれるため、公開環境では注意が必要

## 備考

- NormalModuleが最も一般的で重要なモジュールタイプ
- モジュールタイプにはjavascript/auto, javascript/dynamic, javascript/esm, json, asset, asset/resource, asset/inline, asset/source, webassembly/async, webassembly/sync, css, css/global, css/module, css/auto等がある

---

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

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

### 推奨読解順序

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

NormalModuleの型定義とプロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NormalModule.js | `lib/NormalModule.js` | NormalModuleCreateData型定義（245-262行目）でモジュール生成時のデータ構造を把握する |
| 1-2 | NormalModule.js | `lib/NormalModule.js` | コンストラクタ（338-399行目）でプロパティの初期化を理解する |
| 1-3 | Module.js | `lib/Module.js` | 基底クラスModuleの定義を理解する |

**読解のコツ**: NormalModuleはModuleを継承しており、build()やcodeGeneration()等の主要メソッドはNormalModuleでオーバーライドされている。基底クラスのインターフェースを先に理解すると良い。

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

NormalModule.build()が処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NormalModule.js | `lib/NormalModule.js` | build()メソッドでローダー実行→パース→依存関係抽出の流れを理解する |

#### Step 3: ローダー処理を理解する

doBuild()内のローダーチェーン実行を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NormalModule.js | `lib/NormalModule.js` | doBuild()メソッドでrunLoaders()の呼び出しとソースオブジェクト生成を理解する |

#### Step 4: コンパイルフックを理解する

NormalModuleCompilationHooksの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | NormalModule.js | `lib/NormalModule.js` | getCompilationHooks()（276-333行目）でloader/beforeLoaders/beforeParse/readResource等のフックを理解する |

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

```
NormalModule.build(options, compilation, resolver, fs, callback)
    │
    ├─ NormalModule.needBuild() [リビルド要否判定]
    │
    ├─ NormalModule.doBuild()
    │      ├─ hooks.beforeLoaders.call()
    │      ├─ runLoaders() [loader-runner]
    │      │      └─ ローダーチェーンの逐次実行（right-to-left）
    │      ├─ ソースオブジェクト生成
    │      │      ├─ SourceMapSource（ソースマップあり）
    │      │      ├─ OriginalSource（ソースマップなし）
    │      │      └─ RawSource（バイナリモジュール）
    │      └─ hooks.processResult.call()
    │
    ├─ parser.parse(source)
    │      └─ 依存関係の抽出・登録
    │
    └─ コールバック（buildInfo / buildMeta 更新済み）

NormalModule.codeGeneration(context)
    │
    └─ generator.generate(module, context)
           └─ 出力コードの生成
```

### データフロー図

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

ソースファイル ────▶ runLoaders() ──────────────▶ 変換後ソース
                          │
ローダー設定 ────▶ ローダーチェーン実行
                          │
                   parser.parse() ──────────────▶ dependencies[]
                          │                        blocks[]
                          │                        buildMeta
                   generator.generate() ───────▶ CodeGenerationResult
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NormalModule.js | `lib/NormalModule.js` | ソース | 最も一般的なモジュールタイプの実装 |
| Module.js | `lib/Module.js` | ソース | モジュール基底クラス |
| RawModule.js | `lib/RawModule.js` | ソース | 生のソースコードモジュール |
| ExternalModule.js | `lib/ExternalModule.js` | ソース | 外部モジュール |
| DelegatedModule.js | `lib/DelegatedModule.js` | ソース | 委譲モジュール |
| ModuleBuildError.js | `lib/ModuleBuildError.js` | ソース | ビルドエラークラス |
| ModuleParseError.js | `lib/ModuleParseError.js` | ソース | パースエラークラス |
| ModuleError.js | `lib/ModuleError.js` | ソース | モジュールエラークラス |
| ModuleWarning.js | `lib/ModuleWarning.js` | ソース | モジュール警告クラス |
