# 通知設計書 28-HarmonyLinkingError

## 概要

本ドキュメントは、Webpackにおける `HarmonyLinkingError` の通知仕様を定義する。ES6モジュール（Harmonyモジュール）のimport/exportリンク時に、エクスポートの解決に失敗した場合やスターエクスポートの競合が検出された場合に発行されるエラークラスである。

### 本通知の処理概要

HarmonyLinkingErrorは、Webpackのモジュールリンクフェーズにおいて、ES6モジュールシステム（import/export構文）の依存関係解決で問題が検出された場合に発行されるエラー通知である。

**業務上の目的・背景**：ES6モジュールの静的な依存関係解析により、存在しないエクスポートのインポートや、スターエクスポート（`export * from`）間の名前競合をビルド時点で検出する。これにより、ランタイムエラーの発生を防ぎ、モジュール間のインターフェース不整合を早期に発見できる。Tree Shakingの正確性にも影響する重要なチェックである。

**通知の送信タイミング**：HarmonyImportDependencyの`getErrors`メソッドおよびHarmonyExportImportedSpecifierDependencyの`getErrors`メソッドでエクスポート解決を試みた際に、エクスポートが見つからないまたは競合している場合に生成される。これらはCompilationのモジュールリンクフェーズで呼び出される。

**通知の受信者**：Webpackビルドを実行する開発者。compilation.errorsまたはcompilation.warningsに蓄積される（exportPresenceModeの設定による）。

**通知内容の概要**：インポート先のモジュール名、見つからないエクスポート名、利用可能なエクスポート一覧（providedExports）、スターエクスポートの競合情報を含む。

**期待されるアクション**：開発者は、(1) インポートしているエクスポート名のスペルミスを修正、(2) エクスポート先モジュールに必要なエクスポートを追加、(3) スターエクスポートの競合を解消するために明示的なエクスポートを使用する。

## 通知種別

ビルドエラー（Webpack Compilation Error）またはビルド警告（exportPresenceMode設定による）。コンソール出力およびStats APIを通じて開発者に通知される。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（モジュールリンク処理中に即座に生成） |
| 優先度 | 高（エラーレベル） |
| リトライ | なし（一度きりのエラー発行） |

### 送信先決定ロジック

HarmonyImportDependency.getErrors()およびHarmonyExportImportedSpecifierDependency.getErrors()でエクスポート解決に失敗した場合にエラーオブジェクトの配列として返される。Compilation側でこれらのエラーがcompilation.errorsまたはcompilation.warningsに追加される。

## 通知テンプレート

### メール通知の場合

該当なし。本通知はメール通知ではなく、Webpackビルド出力として表示される。

### 本文テンプレート

エクスポートが見つからない場合:
```
ERROR in export '{エクスポート名}' {追加メッセージ} was not found in '{モジュールパス}'
```

エクスポートが見つからない場合（利用可能エクスポート情報あり）:
```
ERROR in export '{エクスポート名}' {追加メッセージ} was not found in '{モジュールパス}' (possible exports: {エクスポート一覧})
```

名前付きエクスポートをdefault-onlyモジュールからインポートした場合:
```
ERROR in Can't import the named export '{エクスポート名}' {追加メッセージ} from default-exporting module (only default export is available)
```

default-with-namedモジュールからの将来非互換インポート:
```
ERROR in Should not import the named export '{エクスポート名}' {追加メッセージ} from default-exporting module (only default export is available soon)
```

スターエクスポートの競合:
```
ERROR in The requested module '{モジュールパス}' contains conflicting star exports for the name '{エクスポート名}' with the previous requested module '{競合モジュールパス}'
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | エラーメッセージ本文 | コンストラクタ引数 | Yes |
| name | エラー名 | 固定値 "HarmonyLinkingError" | Yes |
| hideStack | スタックトレース非表示フラグ | 固定値 true | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| リンク処理 | HarmonyImportDependency.getErrors() | インポートしたエクスポートが提供されていない（provided === false）場合 | 特定のエクスポート名が見つからない |
| リンク処理 | HarmonyImportDependency.getErrors() | exportsTypeが"default-only"で名前付きエクスポートをインポートした場合 | strictモジュールのdefault-only制約 |
| リンク処理 | HarmonyImportDependency.getErrors() | exportsTypeが"default-with-named"でredirect-warnフラグがある場合 | 将来の非互換性警告 |
| リンク処理 | HarmonyExportImportedSpecifierDependency.getErrors() | スターエクスポート間で同名のエクスポートが競合する場合 | export * からの名前衝突 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| エクスポートが正常に解決 | provided !== false でエクスポートが見つかった場合 |
| ids[0] === "default" | デフォルトエクスポートのインポートはdefault-only/default-with-namedモジュールでも許可 |
| スターエクスポート間で競合なし | 各エクスポート名のtargetが一致する場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[モジュールリンクフェーズ] --> B[HarmonyImportDependency.getErrors/HarmonyExportImportedSpecifierDependency.getErrors呼び出し]
    B --> C{エクスポート解決成功?}
    C -->|Yes| D[エラーなし]
    C -->|No| E{エラー種別判定}
    E -->|エクスポート未提供| F[provided === falseのエラー]
    E -->|default-only制約違反| G[名前付きエクスポートのエラー]
    E -->|スター競合| H[競合エクスポートのエラー]
    F --> I[HarmonyLinkingError生成]
    G --> I
    H --> I
    I --> J[compilation.errorsまたはcompilation.warningsに追加]
    D --> K[終了]
    J --> K
```

## データベース参照・更新仕様

### 参照テーブル一覧

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

### 更新テーブル一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| エクスポート未発見 | importしたシンボルがexport先に存在しない | エクスポート名のスペルチェック、またはモジュール側にエクスポートを追加 |
| default-only制約 | default-onlyモジュールから名前付きインポート | デフォルトインポートに変更 |
| スター競合 | 複数のexport *で同名エクスポート | 明示的なexport文に変更 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。ビルド実行時に即座にエラーが生成される。

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

モジュールパスとエクスポート名が含まれるが、ソースコード構造の情報でありビルド環境外に公開されない限りリスクは低い。

## 備考

- WebpackErrorを基底クラスとして継承している
- hideStack = true であるため、スタックトレースは表示されない
- メッセージのみをコンストラクタ引数として受け取るシンプルなクラス（17行）
- getErrors()は配列で返されるため、1つの依存関係から複数のHarmonyLinkingErrorが生成されることがある
- providedExportsの情報が利用可能な場合、利用可能なエクスポート名一覧をエラーメッセージに含める
- exportsTypeの値（"namespace", "default-only", "default-with-named", "dynamic"等）によってエラー判定が分岐する

---

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

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

### 推奨読解順序

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

HarmonyLinkingErrorクラスのシンプルな構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebpackError.js | `lib/WebpackError.js` | 基底クラス |
| 1-2 | HarmonyLinkingError.js | `lib/HarmonyLinkingError.js` | messageのみを受け取る最小限のクラス。hideStack=true |

**読解のコツ**: 全17行の非常にシンプルなクラス。エラーメッセージの構築は呼び出し側（HarmonyImportDependency, HarmonyExportImportedSpecifierDependency）が担当する。

#### Step 2: HarmonyImportDependencyでの使用を理解する

エクスポート解決エラーの主要な発行箇所を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HarmonyImportDependency.js | `lib/dependencies/HarmonyImportDependency.js` | getErrors()メソッド内の240-316行目 |

**主要処理フロー**:
1. **240-265行目**: exportsInfoを走査し、provided === falseのエクスポートを検出。利用可能エクスポート一覧を生成
2. **267-276行目**: 一般的なエクスポート未発見エラーメッセージの生成
3. **280-293行目**: exportsType === "default-only" の場合、名前付きインポートのエラー
4. **295-314行目**: exportsType === "default-with-named" かつ defaultObject === "redirect-warn" の場合の将来非互換警告

#### Step 3: HarmonyExportImportedSpecifierDependencyでの使用を理解する

スターエクスポートの競合検出を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HarmonyExportImportedSpecifierDependency.js | `lib/dependencies/HarmonyExportImportedSpecifierDependency.js` | getErrors()メソッド内の928-941行目 |

**主要処理フロー**:
- **928行目**: conflicts Mapをループ
- **930-940行目**: 各競合に対してHarmonyLinkingErrorを生成。競合するエクスポート名と競合元モジュールパスをメッセージに含める

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

```
Compilation (モジュールリンクフェーズ)
    |
    +-- HarmonyImportDependency.getErrors()
    |       |
    |       +-- exportsInfo.getReadOnlyExportInfo(id) (242行目)
    |       |
    |       +-- exportInfo.provided === false → エクスポート未発見
    |       |       |
    |       |       +-- new HarmonyLinkingError("export ... was not found in ...")
    |       |
    |       +-- exportsType === "default-only" → 名前付きインポート制約
    |       |       |
    |       |       +-- new HarmonyLinkingError("Can't import the named export ...")
    |       |
    |       +-- exportsType === "default-with-named" + redirect-warn
    |               |
    |               +-- new HarmonyLinkingError("Should not import the named export ...")
    |
    +-- HarmonyExportImportedSpecifierDependency.getErrors()
            |
            +-- スターエクスポート競合検出 (928-941行目)
                    |
                    +-- new HarmonyLinkingError("The requested module ... contains conflicting star exports ...")
```

### データフロー図

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

importされたエクスポート名 -------> exportsInfo検索 -----------> HarmonyLinkingError[]
(ids[])                              |                              |
                                     v                              v
importedModule.exportsType -------> エラー種別判定         compilation.errors[]
                                     |                    または compilation.warnings[]
providedExports -----------------> メッセージ構築
(利用可能エクスポート一覧)

otherStarExports ----------------> 競合検出(スター)
(他のスターエクスポート)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HarmonyLinkingError.js | `lib/HarmonyLinkingError.js` | ソース | エラークラス本体 |
| HarmonyImportDependency.js | `lib/dependencies/HarmonyImportDependency.js` | ソース | エクスポート解決エラーの主要発行箇所 |
| HarmonyExportImportedSpecifierDependency.js | `lib/dependencies/HarmonyExportImportedSpecifierDependency.js` | ソース | スターエクスポート競合エラーの発行箇所 |
| WebpackError.js | `lib/WebpackError.js` | ソース | 基底エラー/警告クラス |
