# 機能設計書 6-依存性解析

## 概要

本ドキュメントは、CommonJS / ESM（Harmony）/ AMD / CSS / WASM等122種以上の依存タイプを解析・追跡する機能の設計を記述する。

### 本機能の処理概要

依存性解析は、ソースコード内のimport/require/import()等の依存宣言を検出し、型付けされた依存関係オブジェクトとしてモジュールグラフに登録する機能である。各依存タイプに対応するDependencyクラスとParserPluginが連携して、静的・動的な依存関係を網羅的に追跡する。

**業務上の目的・背景**：webpackがモジュールバンドルを正しく生成するためには、すべてのモジュール間の依存関係を正確に把握する必要がある。依存性解析は、多様なモジュールシステム（CommonJS、ESM、AMD等）の構文を解析し、統一的な依存関係グラフを構築する基盤である。Tree ShakingやコードスプリッティングもDependency情報に基づいて動作する。

**機能の利用シーン**：画面機能マッピングでは多くの画面で「CommonJS形式のrequire依存関係を解析・追跡」として参照されている。ESM形式のimport/export、動的import()、CSS @import、WebAssemblyインポート等、あらゆるモジュール参照で使用される。

**主要な処理内容**：
1. HarmonyImportDependency系：ESM import/export文の解析
2. CommonJsRequireDependency系：require()/module.exports文の解析
3. AMDRequireDependency系：define()/require([])文の解析
4. ImportDependency：動的import()の解析
5. CssImportDependency：CSS @import文の解析
6. ConstDependency：コンパイル時定数の置換

**関連システム・外部連携**：JavascriptParser（パーサー）、各種ParserPlugin（依存関係検出プラグイン）、ModuleGraph（依存関係グラフ格納先）と連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Page A (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 2 | Page B (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 3 | Page C (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 4 | Page D (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 5 | Page E (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 6 | Page F (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 7 | Page G (many-pages) | 補助機能 | CommonJS形式のrequire依存関係を解析・追跡 |
| 12 | Page A (multiple-entry-points) | 補助機能 | CommonJS/AMD形式の依存関係を解析 |
| 14 | Page A (two-explicit-vendor-chunks) | 補助機能 | vendor1,vendor2へのrequire依存関係を解析 |

## 機能種別

解析処理 / 依存関係管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | string \| Buffer | Yes | パース対象のソースコード | - |
| state | ParserState | Yes | パーサーの状態オブジェクト | - |

### 入力データソース

- NormalModuleのbuild()後にパーサーに渡されるソースコード
- ASTノード（acornパーサーで生成）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| dependencies | Dependency[] | 検出された同期依存関係 |
| blocks | AsyncDependenciesBlock[] | 検出された非同期依存関係ブロック |
| presentationalDependencies | Dependency[] | 出力に影響する依存関係（コード変換用） |

### 出力先

- モジュールのdependencies/blocks配列に登録
- ModuleGraphに格納される

## 処理フロー

### 処理シーケンス

```
1. パーサーがソースコードをAST化
2. AST走査中に各ノードタイプに対応するフックを発火
   ├─ import文検出 → HarmonyImportDependencyParserPlugin
   ├─ export文検出 → HarmonyExportDependencyParserPlugin
   ├─ require()検出 → CommonJsImportsParserPlugin
   ├─ module.exports検出 → CommonJsExportsParserPlugin
   ├─ import()検出 → ImportParserPlugin
   ├─ define()検出 → AMDDefineDependencyParserPlugin
   └─ その他パターン検出 → 各種ParserPlugin
3. ParserPluginが対応するDependencyインスタンスを生成
4. module.addDependency() / module.addBlock()でモジュールに登録
5. Compilationのseal()時にModuleGraphに反映
```

### フローチャート

```mermaid
flowchart TD
    A[ソースコード] --> B[acornパーサーでAST生成]
    B --> C[AST走査]
    C --> D{ノードタイプ}
    D -->|ImportDeclaration| E[HarmonyImportDependency生成]
    D -->|CallExpression require| F[CommonJsRequireDependency生成]
    D -->|CallExpression import| G[ImportDependency生成]
    D -->|AMD define| H[AMDDefineDependency生成]
    E --> I[module.addDependency]
    F --> I
    G --> J[module.addBlock - AsyncDependenciesBlock]
    H --> I
    I --> K[ModuleGraph登録]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ESM/CJS判定 | import/export文があればESM、require/module.exportsがあればCJS | パース時のソースタイプ判定 |
| BR-02 | 動的import非同期化 | import()は非同期依存関係としてAsyncDependenciesBlockに格納 | import()検出時 |
| BR-03 | sideEffects最適化 | Dependencyのusedexports情報に基づきTree Shakingが動作 | seal()時の最適化フェーズ |
| BR-04 | Harmony厳格モード | ESMモジュールは自動的にstrictモードとなる | ESMソースタイプ時 |

### 計算ロジック

特になし。

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

該当なし。

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

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ModuleDependencyError | 依存関係エラー | 依存関係の解決や処理に失敗 | 依存先モジュールの存在を確認 |
| ModuleDependencyWarning | 依存関係警告 | 依存関係に関する警告（非推奨パターン等） | コードの修正を検討 |

### リトライ仕様

リトライ機構はない。

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

該当なし。

## パフォーマンス要件

- パーサーフックのSyncBailHook使用により、最初にマッチしたプラグインで処理が完了する
- 依存関係オブジェクトはシリアライズ可能で、キャッシュに対応

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

特になし。

## 備考

- lib/dependencies/配下に74以上のDependencyクラスが存在する
- 各DependencyクラスにはTemplate（コード生成テンプレート）が対応している
- webpack 5ではHarmony（ESM）依存関係がデフォルトで推奨される

---

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

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

### 推奨読解順序

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

Dependencyクラスの基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Dependency.js | `lib/Dependency.js` | Dependency基底クラスの構造（loc、range、type等）を理解する |
| 1-2 | ModuleDependency.js | `lib/dependencies/ModuleDependency.js` | request属性を持つ依存関係の基底を理解する |

#### Step 2: 主要な依存タイプを理解する

ESM/CommonJS/動的importの依存関係クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HarmonyImportDependency.js | `lib/dependencies/HarmonyImportDependency.js` | ESM importの依存関係構造 |
| 2-2 | CommonJsRequireDependency.js | `lib/dependencies/CommonJsRequireDependency.js` | CommonJS requireの依存関係構造 |
| 2-3 | ImportDependency.js | `lib/dependencies/ImportDependency.js` | 動的import()の依存関係構造 |
| 2-4 | EntryDependency.js | `lib/dependencies/EntryDependency.js` | エントリポイントの依存関係構造 |

#### Step 3: ParserPluginの動作を理解する

依存関係を検出するParserPluginの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HarmonyImportDependencyParserPlugin.js | `lib/dependencies/HarmonyImportDependencyParserPlugin.js` | ESM import検出ロジック |
| 3-2 | CommonJsImportsParserPlugin.js | `lib/dependencies/CommonJsImportsParserPlugin.js` | CommonJS require検出ロジック |
| 3-3 | ImportParserPlugin.js | `lib/dependencies/ImportParserPlugin.js` | 動的import()検出ロジック |

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

```
JavascriptParser.parse(source)
    │
    ├─ AST生成（acorn）
    │
    ├─ AST走査（walkStatements / walkExpression）
    │      │
    │      ├─ hooks.import.call() → HarmonyImportDependencyParserPlugin
    │      │      └─ new HarmonyImportSideEffectDependency()
    │      │
    │      ├─ hooks.call["require"].call() → CommonJsImportsParserPlugin
    │      │      └─ new CommonJsRequireDependency()
    │      │
    │      ├─ hooks.importCall.call() → ImportParserPlugin
    │      │      └─ new ImportDependency() + AsyncDependenciesBlock
    │      │
    │      └─ hooks.call["define"].call() → AMDDefineDependencyParserPlugin
    │             └─ new AMDDefineDependency()
    │
    └─ module.addDependency() / module.addBlock()
```

### データフロー図

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

ソースコード ────────▶ acorn AST生成 ──────────▶ AST
                            │
AST ──────────────▶ AST走査 + フック発火
                            │
                     ParserPlugin群
                     ├─ Harmony系 ────────────▶ HarmonyImport/ExportDependency
                     ├─ CommonJS系 ───────────▶ CommonJsRequire/ExportsDependency
                     ├─ AMD系 ────────────────▶ AMDDefineDependency
                     └─ Import系 ─────────────▶ ImportDependency + AsyncBlock

                     module.dependencies[] / blocks[] に格納
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Dependency.js | `lib/Dependency.js` | ソース | 依存関係基底クラス |
| ModuleDependency.js | `lib/dependencies/ModuleDependency.js` | ソース | モジュール依存関係基底 |
| HarmonyImportDependency.js | `lib/dependencies/HarmonyImportDependency.js` | ソース | ESM import依存関係 |
| HarmonyImportSpecifierDependency.js | `lib/dependencies/HarmonyImportSpecifierDependency.js` | ソース | ESM import specifier |
| HarmonyExportSpecifierDependency.js | `lib/dependencies/HarmonyExportSpecifierDependency.js` | ソース | ESM export specifier |
| CommonJsRequireDependency.js | `lib/dependencies/CommonJsRequireDependency.js` | ソース | CommonJS require |
| CommonJsExportsDependency.js | `lib/dependencies/CommonJsExportsDependency.js` | ソース | CommonJS exports |
| ImportDependency.js | `lib/dependencies/ImportDependency.js` | ソース | 動的import() |
| AMDDefineDependency.js | `lib/dependencies/AMDDefineDependency.js` | ソース | AMD define |
| ConstDependency.js | `lib/dependencies/ConstDependency.js` | ソース | コンパイル時定数置換 |
| CssImportDependency.js | `lib/dependencies/CssImportDependency.js` | ソース | CSS @import |
| EntryDependency.js | `lib/dependencies/EntryDependency.js` | ソース | エントリポイント |
