# 機能設計書 37-ModuleFederationPlugin

## 概要

本ドキュメントは、webpackにおけるModule Federationプラグインの機能について記述する。ModuleFederationPluginは複数の独立ビルド間でモジュールを共有するマイクロフロントエンドアーキテクチャを実現するオーケストレーションプラグインである。

### 本機能の処理概要

ModuleFederationPluginは、webpack 5で導入されたModule Federation機能の統合エントリポイントである。複数の独立したwebpackビルド（マイクロフロントエンド）が、ランタイムでモジュールを動的に共有・取得できるアーキテクチャを提供する。

**業務上の目的・背景**：大規模Webアプリケーションを複数のチームが独立して開発・デプロイするマイクロフロントエンドアーキテクチャにおいて、チーム間でのモジュール共有が課題となる。Module Federationにより、各チームのアプリケーションが独立してビルド・デプロイされながらも、ランタイムでコンポーネントやライブラリを共有できる。バージョン不整合の自動解決や重複回避も行われる。

**機能の利用シーン**：
- マイクロフロントエンドアーキテクチャでホストアプリケーションがリモートアプリのコンポーネントを利用する場合
- 複数の独立ビルド間でReact, lodash等の依存パッケージを共有する場合
- 動的にリモートモジュールを読み込み・遅延ロードする場合

**主要な処理内容**：
1. ContainerPluginによるFederationコンテナの作成（exposes設定）
2. ContainerReferencePluginによるリモートコンテナの参照（remotes設定）
3. SharePluginによる共有依存パッケージの管理（shared設定）
4. HoistContainerReferencesPluginによる参照最適化
5. ライブラリタイプの自動有効化

**関連システム・外部連携**：リモートアプリケーションのリモートエントリファイル（remoteEntry.js等）をHTTP経由で読み込む。複数のwebpackビルド間でランタイム通信を行う。

**権限による制御**：特になし。設定オブジェクトにより機能を制御する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | App (Host) (module-federation) | 主機能 | ホストアプリケーションとしてリモートモジュール(mfe-b,mfe-c)を消費 |
| 20 | MFE-B (Remote) (module-federation) | 主機能 | リモートBとしてComponentを外部に公開 |
| 21 | MFE-C (Remote) (module-federation) | 主機能 | リモートCとしてComponent,Component2を外部に公開 |

## 機能種別

プラグインオーケストレーション / マイクロフロントエンド基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | コンテナの名前 | スキーマバリデーション |
| filename | string | No | リモートエントリファイル名 | スキーマバリデーション |
| exposes | object/array | No | 外部に公開するモジュール | スキーマバリデーション |
| remotes | object/array | No | 参照するリモートコンテナ | スキーマバリデーション |
| shared | object/array | No | 共有する依存パッケージ | スキーマバリデーション |
| library | LibraryOptions | No | ライブラリ出力設定（デフォルト: {type:"var", name:options.name}） | isValidExternalsType |
| remoteType | ExternalsType | No | リモートの外部タイプ（デフォルト: "script"） | isValidExternalsType |
| runtime | string | No | ランタイム名 | スキーマバリデーション |
| shareScope | string | No | 共有スコープ名 | スキーマバリデーション |

### 入力データソース

- webpack設定オブジェクトのplugins配列に含まれるModuleFederationPluginオプション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| リモートエントリファイル | JavaScript | コンテナのエントリポイント（remoteEntry.js） |
| 共有モジュール | JavaScript | 共有されるモジュールのチャンク |
| ランタイムコード | string | リモートモジュール読み込み・共有スコープ初期化のランタイムコード |

### 出力先

output.pathにリモートエントリファイルと共有モジュールチャンクが出力される。

## 処理フロー

### 処理シーケンス

```
1. オプションバリデーション
   └─ createSchemaValidationによるJSON Schemaベースの検証
2. ライブラリタイプ有効化
   └─ library.typeがenabledLibraryTypesに含まれなければ追加
3. ContainerPlugin適用（exposes設定あり時）
   └─ name, library, filename, runtime, shareScope, exposesを渡して適用
4. ContainerReferencePlugin適用（remotes設定あり時）
   └─ remoteType, shareScope, remotesを渡して適用
5. SharePlugin適用（shared設定あり時）
   └─ shared, shareScopeを渡して適用
6. HoistContainerReferences適用
   └─ コンテナ参照の最適化
```

### フローチャート

```mermaid
flowchart TD
    A[ModuleFederationPlugin.apply] --> B[ライブラリタイプ有効化]
    B --> C{exposes設定あり?}
    C -->|Yes| D[ContainerPlugin適用]
    C -->|No| E{remotes設定あり?}
    D --> E
    E -->|Yes| F[ContainerReferencePlugin適用]
    E -->|No| G{shared設定あり?}
    F --> G
    G -->|Yes| H[SharePlugin適用]
    G -->|No| I[HoistContainerReferences適用]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルトライブラリ | library未指定時は{type:"var", name:options.name}をデフォルト使用 | library未設定時 |
| BR-02 | デフォルトリモートタイプ | remoteType未指定時、libraryのtypeがvalidなexternalsTypeならそれを使用、そうでなければ"script" | remoteType未設定時 |
| BR-03 | ライブラリタイプ自動有効化 | library.typeがenabledLibraryTypesに含まれない場合は自動追加 | apply時 |
| BR-04 | afterPluginsフック | ContainerPlugin/ContainerReferencePlugin/SharePluginはafterPluginsフックで適用 | apply時 |
| BR-05 | 空配列チェック | exposes/remotesが空配列またはキーなしオブジェクトの場合はプラグインを適用しない | apply時 |

### 計算ロジック

該当なし。ModuleFederationPluginはオーケストレーションプラグインであり、個別の処理はContainerPlugin, ContainerReferencePlugin, SharePluginに委譲される。

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | オプションがスキーマに適合しない | createSchemaValidationでエラーメッセージを出力 |
| - | TypeError | compilationがCompilationインスタンスでない | getCompilationHooksでTypeErrorをスロー |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- HoistContainerReferencesPluginによりコンテナ参照を最適化し、不要な読み込みを回避
- 共有モジュールのeagerオプションにより、即座読み込みと遅延読み込みを制御可能

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

- リモートエントリファイルのHTTP読み込みはCORS制約を受ける
- 信頼できないリモートコンテナからのコード実行リスクに注意
- 共有モジュールのバージョン制約（requiredVersion, strictVersion）による互換性保証

## 備考

- CompilationHooksにはaddContainerEntryDependencyとaddFederationRuntimeDependencyの2つのSyncHookが含まれる
- webpack 5.0+で利用可能

---

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

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

### 推奨読解順序

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

ModuleFederationPluginのオプション構造とフック定義を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ModuleFederationPlugin.js | `lib/container/ModuleFederationPlugin.js` | 22-26行目: CompilationHooksの型定義（addContainerEntryDependency, addFederationRuntimeDependency） |
| 1-2 | ModuleFederationPlugin.js | `lib/container/ModuleFederationPlugin.js` | 37-39行目: compilationHooksMap(WeakMap)とPLUGIN_NAME定数 |

**読解のコツ**: ModuleFederationPluginは自身ではほとんどロジックを持たず、ContainerPlugin/ContainerReferencePlugin/SharePluginへの委譲パターンで構成されている。各サブプラグインの役割を理解してから全体を把握すること。

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

apply()メソッドの委譲パターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ModuleFederationPlugin.js | `lib/container/ModuleFederationPlugin.js` | 45-49行目: コンストラクタでのバリデーション |
| 2-2 | ModuleFederationPlugin.js | `lib/container/ModuleFederationPlugin.js` | 78-128行目: apply()メソッド全体 |

**主要処理フロー**:
1. **79-80行目**: libraryとremoteTypeのデフォルト値決定
2. **86-91行目**: enabledLibraryTypesへのライブラリタイプ追加
3. **92-127行目**: afterPluginsフック内でContainerPlugin/ContainerReferencePlugin/SharePlugin/HoistContainerReferencesを適用
4. **93-107行目**: exposes設定がある場合のみContainerPlugin適用
5. **108-119行目**: remotes設定がある場合のみContainerReferencePlugin適用
6. **120-125行目**: shared設定がある場合のみSharePlugin適用

#### Step 3: 各サブプラグインとの連携を理解する

委譲先の各サブプラグインの概要を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ContainerPlugin.js | `lib/container/ContainerPlugin.js` | 34-99行目: コンテナ作成・公開モジュール管理 |
| 3-2 | ContainerReferencePlugin.js | `lib/container/ContainerReferencePlugin.js` | 35-100行目: リモートコンテナ参照・モジュール取得 |
| 3-3 | SharePlugin.js | `lib/sharing/SharePlugin.js` | 19-91行目: 共有パッケージ管理（ConsumeSharedPlugin + ProvideSharedPlugin） |

**主要処理フロー**:
- **ContainerPlugin 79-98行目**: compilation.addEntryでコンテナエントリを登録
- **ContainerReferencePlugin 63-79行目**: ExternalsPluginでリモート外部参照を登録
- **SharePlugin 79-88行目**: ConsumeSharedPluginとProvideSharedPluginを適用

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

```
ModuleFederationPlugin.apply(compiler)
    |
    +-- compiler.hooks.afterPlugins.tap
           |
           +-- ContainerPlugin.apply(compiler)     [exposes設定時]
           |      +-- ContainerEntryDependency
           |      +-- ContainerEntryModule
           |      +-- compilation.addEntry()
           |
           +-- ContainerReferencePlugin.apply(compiler)  [remotes設定時]
           |      +-- ExternalsPlugin.apply(compiler)
           |      +-- RemoteModule
           |      +-- RemoteRuntimeModule
           |      +-- FallbackModule
           |
           +-- SharePlugin.apply(compiler)          [shared設定時]
           |      +-- ConsumeSharedPlugin.apply(compiler)
           |      +-- ProvideSharedPlugin.apply(compiler)
           |
           +-- HoistContainerReferences.apply(compiler)
```

### データフロー図

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

webpack設定 ─────────────> ModuleFederationPlugin
  name                          |
  exposes ──────────────> ContainerPlugin           ──> remoteEntry.js
  remotes ──────────────> ContainerReferencePlugin  ──> リモートモジュール参照
  shared ───────────────> SharePlugin               ──> 共有モジュールチャンク
  library                       |
  remoteType                    v
                          HoistContainerReferences  ──> 最適化されたバンドル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ModuleFederationPlugin.js | `lib/container/ModuleFederationPlugin.js` | ソース | Module Federationの統合プラグイン（本機能の主要ファイル） |
| ContainerPlugin.js | `lib/container/ContainerPlugin.js` | ソース | Federationコンテナの作成 |
| ContainerReferencePlugin.js | `lib/container/ContainerReferencePlugin.js` | ソース | リモートコンテナの参照 |
| SharePlugin.js | `lib/sharing/SharePlugin.js` | ソース | 共有依存パッケージの管理 |
| HoistContainerReferencesPlugin.js | `lib/container/HoistContainerReferencesPlugin.js` | ソース | コンテナ参照の最適化 |
| options.js | `lib/container/options.js` | ソース | オプション解析ユーティリティ |
| ModuleFederationPlugin.json | `schemas/plugins/container/ModuleFederationPlugin.json` | スキーマ | オプションバリデーションスキーマ |
