# 機能設計書 39-@babel/plugin-transform-dynamic-import

## 概要

本ドキュメントは、Babelの変換プラグイン「@babel/plugin-transform-dynamic-import」の機能設計を記述する。本プラグインはES2020の動的インポート構文（`import()`）を、モジュールトランスフォームプラグインと連携して古いJavaScript環境でも動作する形式に変換する。

### 本機能の処理概要

本プラグインは、動的インポート式（`import("module")`）を検出し、対応するモジュールトランスフォームプラグイン（CommonJS、AMD、SystemJS）と連携して適切な形式に変換する機能を提供する。本プラグイン自体は変換のマーカーとして機能し、実際の変換はモジュールトランスフォームプラグインが担当する。

**業務上の目的・背景**：ES2020で正式に仕様化された動的インポートは、実行時にモジュールを非同期で読み込むための機能である。これはコード分割やオンデマンドローディングに不可欠な機能である。古いブラウザやNode.jsバージョンではこの構文をサポートしていないため、トランスパイルが必要となる。

**機能の利用シーン**：
- コード分割によるパフォーマンス最適化
- 条件付きモジュールローディング
- `@babel/preset-env`の一部として自動的に適用される場合

**主要な処理内容**：
1. pre関数でファイルに`@babel/plugin-proposal-dynamic-import`バージョンをマーク
2. Program visitorでモジュールトランスフォームプラグインの存在を確認
3. 実際の変換は対応するモジュールトランスフォームプラグインに委譲

**関連システム・外部連携**：
- `@babel/plugin-transform-modules-commonjs`: CommonJS形式への変換
- `@babel/plugin-transform-modules-amd`: AMD形式への変換
- `@babel/plugin-transform-modules-systemjs`: SystemJS形式への変換
- `@babel/helper-plugin-utils`: プラグインユーティリティ
- `@babel/core`: Babelコアとの統合

**権限による制御**：特になし。変換はビルド時に実行される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIまたはビルドツール経由で使用されるため、画面との関連なし |

## 機能種別

コード変換処理 / AST操作 / プラグイン連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | オプションなし | - |

### 入力データソース

- Babelによってパースされたソースコード（AST形式）
- CallExpression（callee: Import）またはImportExpression

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | AST | 変換後のAST（モジュールトランスフォームによる） |

### 出力先

- 変換されたASTは`@babel/generator`によってJavaScriptコードとして出力

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化（pre関数）
   └─ file.set("@babel/plugin-proposal-dynamic-import", version)

2. Programノードの訪問
   ├─ file.get("@babel/plugin-transform-modules-*")でモジュールタイプ取得
   └─ サポートされていない場合はエラーをスロー

3. 実際の変換（モジュールトランスフォーム側）
   ├─ CommonJS: require()ベースのPromise変換
   ├─ AMD: require.asyncベースの変換
   └─ SystemJS: System.import()への変換
```

### フローチャート

```mermaid
flowchart TD
    A[プラグイン初期化] --> B[pre: dynamic-importバージョンをマーク]
    B --> C[Program visitor]
    C --> D{モジュールトランスフォームあり?}
    D -->|No| E[Error: MODULES_NOT_FOUND]
    D -->|Yes| F{モジュールタイプ}
    F -->|commonjs| G[CommonJS変換に委譲]
    F -->|amd| H[AMD変換に委譲]
    F -->|systemjs| I[SystemJS変換に委譲]
    G --> J[変換完了]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | モジュールトランスフォーム必須 | CommonJS、AMD、SystemJSのいずれかのモジュールトランスフォームが必要 | 常時 |
| BR-39-02 | バンドラー使用時の推奨 | Webpack/Rollup使用時は@babel/plugin-syntax-dynamic-importを推奨 | バンドラー使用時 |
| BR-39-03 | バージョンマーキング | pre関数で互換性のためのバージョン情報をマーク | 常時 |

### 計算ロジック

- 変換例（CommonJS）: `import("mod")` → `Promise.resolve().then(() => require("mod"))`

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

該当なし（コンパイル時変換のため）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| MODULES_NOT_FOUND | Error | サポートされているモジュールトランスフォームが見つからない | CommonJS/AMD/SystemJSプラグインを追加するか、バンドラー使用時はsyntax-dynamic-importを使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 変換処理は同期的に実行される
- 本プラグイン自体の処理は軽量（マーキングと検証のみ）

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

- 特になし

## 備考

- 本プラグインは`@babel/preset-env`に含まれており、ターゲット環境に応じて自動的に適用される
- Webpack、Rollup等のバンドラーを使用する場合は、このプラグインの代わりに`@babel/plugin-syntax-dynamic-import`を使用することを推奨

---

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

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

### 推奨読解順序

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

本プラグインはimport()式を検出するが、実際の変換はモジュールトランスフォームプラグインに委譲する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-dynamic-import/src/index.ts` | SUPPORTED_MODULESセット、MODULES_NOT_FOUNDエラーメッセージ |

**読解のコツ**: 本プラグインは主に検証とマーキングを担当し、実際の変換はモジュールトランスフォームプラグインが行う。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-dynamic-import/src/index.ts` | pre関数、Program visitor |

**主要処理フロー**:
1. **1行目**: @babel/helper-plugin-utilsのインポート
2. **3行目**: SUPPORTED_MODULES定義（commonjs, amd, systemjs）
3. **5-16行目**: MODULES_NOT_FOUNDエラーメッセージ
4. **18-19行目**: APIバージョン検証
5. **22-23行目**: プラグイン名定義
6. **24-30行目**: pre関数でバージョンマーキング
7. **32-39行目**: Program visitorでモジュールトランスフォームの検証

#### Step 3: モジュールトランスフォームとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dynamic-import.ts | `packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts` | CommonJSでの動的インポート変換実装 |

**主要処理フロー（CommonJS連携）**:
- **16-28行目**: transformDynamicImport関数の実装
- **21行目**: noInteropに基づくrequire選択
- **23-27行目**: buildDynamicImportでPromise.resolve().then(() => require())生成

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

```
@babel/plugin-transform-dynamic-import/src/index.ts
    │
    ├─ pre()
    │      └─ file.set("@babel/plugin-proposal-dynamic-import", version)
    │
    └─ visitor.Program()
           │
           └─ file.get("@babel/plugin-transform-modules-*")
                  │
                  ├─ "commonjs" → @babel/plugin-transform-modules-commonjs
                  │                     └─ dynamic-import.ts
                  │                            └─ transformDynamicImport()
                  │
                  ├─ "amd" → @babel/plugin-transform-modules-amd
                  │
                  └─ "systemjs" → @babel/plugin-transform-modules-systemjs
```

### データフロー図

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

import("mod")       ─▶  dynamic-import plugin      ─▶  CommonJS: Promise.resolve()
(ImportExpression)       │                              .then(() => require("mod"))
                         ├─ バージョンマーク
                         │                              AMD: require(["mod"], ...)
                         └─ モジュールトランスフォーム
                            に委譲                       SystemJS: System.import("mod")
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-dynamic-import/src/index.ts` | ソース | プラグインエントリーポイント、検証ロジック |
| package.json | `packages/babel-plugin-transform-dynamic-import/package.json` | 設定 | パッケージ依存関係定義 |
| dynamic-import.ts | `packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts` | ソース | CommonJS変換の実装 |
| test/index.js | `packages/babel-plugin-transform-dynamic-import/test/index.js` | テスト | テストランナー設定 |
| fixtures/commonjs/ | `packages/babel-plugin-transform-dynamic-import/test/fixtures/commonjs/` | テスト | CommonJS変換テストケース |
| fixtures/amd/ | `packages/babel-plugin-transform-dynamic-import/test/fixtures/amd/` | テスト | AMD変換テストケース |
| fixtures/systemjs/ | `packages/babel-plugin-transform-dynamic-import/test/fixtures/systemjs/` | テスト | SystemJS変換テストケース |
