# 機能設計書 76-@babel/helper-module-transforms

## 概要

本ドキュメントは、@babel/helper-module-transformsの機能設計について記載する。このパッケージは、ESモジュール（import/export）をCommonJS等の他のモジュール形式に変換するためのヘルパー関数を提供するモジュールである。

### 本機能の処理概要

**業務上の目的・背景**：ESモジュール（ES6 Modules）は標準的なJavaScriptモジュールシステムであるが、Node.jsの従来のCommonJSやAMD、UMDなど他のモジュール形式への変換が必要なケースが多い。本パッケージは、ESモジュールのimport/export文を解析し、指定されたモジュール形式に変換するための共通ロジックを提供する。これにより、@babel/plugin-transform-modules-commonjsなどのモジュール変換プラグインが一貫した方法でモジュール変換を実装できる。

**機能の利用シーン**：@babel/plugin-transform-modules-commonjs、@babel/plugin-transform-modules-amd、@babel/plugin-transform-modules-umd、@babel/plugin-transform-modules-systemjsなどのモジュール変換プラグインで内部的に使用される。ESモジュールをターゲット環境に適したモジュール形式に変換する際の中核機能。

**主要な処理内容**：
1. モジュールメタデータの正規化と読み込み（import/export文の解析）
2. トップレベルthisの書き換え（undefinedへの変換）
3. ライブバインディング参照の書き換え
4. __esModuleヘッダーの生成
5. 名前空間再エクスポートの処理
6. 動的インポートの処理

**関連システム・外部連携**：@babel/core、@babel/helper-module-imports、@babel/template、@babel/typesと連携する。

**権限による制御**：権限による実行制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | モジュール変換プラグインから内部利用 |

## 機能種別

モジュール変換 / コード生成 / AST操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | NodePath<Program> | Yes | プログラムのNodePath | ESモジュールであること |
| exportName | string | No | エクスポートオブジェクト名 | - |
| strict | boolean | Yes | strictモード強制 | - |
| allowTopLevelThis | boolean | No | トップレベルthisを許可 | - |
| strictMode | boolean | Yes | "use strict"ディレクティブ追加 | - |
| loose | boolean | No | ルーズモード（簡易出力） | - |
| importInterop | ImportInterop | No | インポート相互運用性設定 | "none" \| "babel" \| "node" \| function |
| lazy | Lazy | No | 遅延読み込み設定 | - |
| esNamespaceOnly | boolean | No | ESM名前空間のみ | - |
| constantReexports | boolean | No | 定数再エクスポート | - |

### 入力データソース

Babelの変換パイプラインからAST（NodePath）として提供

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| meta | ModuleMetadata | モジュールメタデータ |
| headers | Statement[] | ヘッダー文（__esModule等） |

### 出力先

AST変換結果として呼び出し元に返却

## 処理フロー

### 処理シーケンス

```
1. rewriteModuleStatementsAndPrepareHeader呼び出し
   ├─ validateImportInteropOptionでオプション検証
   ├─ isModuleでESモジュール確認
   └─ sourceTypeを"script"に変更
2. normalizeModuleAndLoadMetadata実行
   ├─ 匿名エクスポートの名前付け
   ├─ モジュールメタデータの収集
   ├─ import/export文の削除
   └─ インタロップタイプの決定
3. rewriteThis実行（allowTopLevelThis=false時）
   └─ トップレベルthisをundefinedに変換
4. rewriteLiveReferences実行
   └─ インポート参照をモジュール参照に書き換え
5. strictModeディレクティブ追加
6. ヘッダー文の生成
   ├─ buildESModuleHeader（__esModule）
   ├─ buildExportNameListDeclaration
   └─ buildExportInitializationStatements
7. メタデータとヘッダーを返却
```

### フローチャート

```mermaid
flowchart TD
    A[rewriteModuleStatementsAndPrepareHeader] --> B[importInterop検証]
    B --> C{isModule?}
    C -->|No| D[エラー]
    C -->|Yes| E[sourceType変更]
    E --> F[normalizeModuleAndLoadMetadata]
    F --> G{allowTopLevelThis?}
    G -->|No| H[rewriteThis]
    G -->|Yes| I[rewriteLiveReferences]
    H --> I
    I --> J{strictMode?}
    J -->|Yes| K[use strict追加]
    J -->|No| L[ヘッダー生成]
    K --> L
    L --> M[__esModule設定]
    M --> N[エクスポート初期化]
    N --> O[meta/headers返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-01 | ESモジュール必須 | スクリプトモードでは処理不可 | 常時 |
| BR-76-02 | ライブバインディング | インポートは常にオリジナルソースを参照 | 常時 |
| BR-76-03 | __esModule | ESモジュールであることを示すフラグ設定 | hasExports=true時 |
| BR-76-04 | importInterop | Babel/Node.js形式の相互運用性 | インポート変換時 |
| BR-76-05 | デフォルト/名前空間 | default+namedインポートはnamespaceインタロップ | 複合インポート時 |

### 計算ロジック

**インタロップタイプ判定**：
```
needsDefault && needsNamed → "namespace"
needsDefaultのみ → "default"
それ以外 → "none"
```

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

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

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーションエラー | スクリプトモードで実行 | ESモジュールとして処理 |
| - | 検証エラー | 無効なimportInterop値 | 有効な値を指定 |
| - | コードフレームエラー | "__esModule"エクスポート | エクスポート名を変更 |

### リトライ仕様

リトライ対象外

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

トランザクション処理なし

## パフォーマンス要件

- チャンクサイズ100でエクスポート初期化を分割（深いAST構造回避）

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

特になし

## 備考

- Babel 9でlazy実装はCJS変換に移動予定
- wrapReferenceでカスタムラッピング可能
- noIncompleteNsImportDetectionで不完全NS検出を無効化可能

---

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

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

### 推奨読解順序

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

まず、モジュールメタデータの型定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | normalize-and-load-metadata.ts | `packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts` | ModuleMetadata、SourceModuleMetadata型（6-54行目） |

**読解のコツ**: ModuleMetadataはエクスポート情報、SourceModuleMetadataはインポート情報を保持する。interop、imports、importsNamespace、reexportsの各フィールドの役割を理解する。

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

メインのrewriteModuleStatementsAndPrepareHeader関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-helper-module-transforms/src/index.ts` | rewriteModuleStatementsAndPrepareHeader関数（57-133行目） |

**主要処理フロー**:
1. **79行目**: validateImportInteropOptionでオプション検証
2. **80行目**: isModuleでESモジュールであることを確認
3. **81行目**: sourceTypeを"script"に変更
4. **83-89行目**: normalizeModuleAndLoadMetadataでメタデータ収集
5. **91-93行目**: allowTopLevelThis=falseならrewriteThis実行
6. **95行目**: rewriteLiveReferencesでインポート参照書き換え
7. **97-107行目**: strictModeディレクティブの追加
8. **109-130行目**: ヘッダー文の生成

#### Step 3: メタデータ収集を理解する

モジュールメタデータの正規化処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | normalize-and-load-metadata.ts | `packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts` | normalizeModuleAndLoadMetadata関数（112-187行目） |
| 3-2 | normalize-and-load-metadata.ts | `packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts` | getModuleMetadata関数（231-437行目） |

**主要処理フロー**:
- **138行目**: nameAnonymousExportsで匿名エクスポートに名前付け
- **140-144行目**: getModuleMetadataでメタデータ収集
- **146行目**: removeImportExportDeclarationsでimport/export削除
- **157-177行目**: インタロップタイプの決定

#### Step 4: ヘッダー生成を理解する

ESModuleヘッダーと初期化文の生成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/babel-helper-module-transforms/src/index.ts` | buildESModuleHeader関数（325-340行目） |
| 4-2 | index.ts | `packages/babel-helper-module-transforms/src/index.ts` | buildExportInitializationStatements関数（438-537行目） |

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

```
@babel/helper-module-transforms/src/index.ts
    │
    ├─ rewriteModuleStatementsAndPrepareHeader()
    │      ├─ normalizeModuleAndLoadMetadata()
    │      │      ├─ nameAnonymousExports()
    │      │      ├─ getModuleMetadata()
    │      │      │      ├─ getLocalExportMetadata()
    │      │      │      └─ getData()
    │      │      └─ removeImportExportDeclarations()
    │      ├─ rewriteThis()
    │      ├─ rewriteLiveReferences()
    │      ├─ buildESModuleHeader()
    │      ├─ buildExportNameListDeclaration()
    │      └─ buildExportInitializationStatements()
    │
    ├─ wrapInterop()
    ├─ buildNamespaceInitStatements()
    └─ ensureStatementsHoisted()
```

### データフロー図

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

NodePath<Program> ───▶ rewriteModuleStatementsAndPrepareHeader
  - import文                    │
  - export文                    ├─ メタデータ収集
  - ESモジュール                │   │
                                │   └─ ModuleMetadata
                                │
                                ├─ AST変換
                                │   ├─ this → undefined
                                │   └─ インポート参照書き換え
                                │
                                └─ ヘッダー生成
                                    ├─ __esModule
                                    └─ エクスポート初期化
                                            │
                                            ▼
                                    { meta, headers }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-helper-module-transforms/src/index.ts` | ソース | メインエントリーポイント |
| normalize-and-load-metadata.ts | `packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts` | ソース | メタデータ収集 |
| rewrite-this.ts | `packages/babel-helper-module-transforms/src/rewrite-this.ts` | ソース | this書き換え |
| rewrite-live-references.ts | `packages/babel-helper-module-transforms/src/rewrite-live-references.ts` | ソース | ライブ参照書き換え |
| dynamic-import.ts | `packages/babel-helper-module-transforms/src/dynamic-import.ts` | ソース | 動的インポート処理 |
| get-module-name.ts | `packages/babel-helper-module-transforms/src/get-module-name.ts` | ソース | モジュール名取得 |
| lazy-modules.ts | `packages/babel-helper-module-transforms/src/lazy-modules.ts` | ソース | 遅延読み込み処理 |
