# 機能設計書 66-@babel/plugin-proposal-import-defer

## 概要

本ドキュメントは、Babelの遅延インポート（import defer）を変換する提案プラグイン `@babel/plugin-proposal-import-defer` の機能設計を定義する。

### 本機能の処理概要

本プラグインは、TC39で提案されている遅延インポート構文（`import defer * as ns from './mod'`）をCommonJS形式に変換する機能を提供する。遅延インポートはモジュールの評価を実際に使用されるまで遅延させ、起動時間の改善やリソース効率化を実現する。

**業務上の目的・背景**：大規模アプリケーションでは、起動時に多数のモジュールをロードすることでパフォーマンスが低下する。遅延インポートを使用することで、実際に必要になるまでモジュールの評価を遅らせ、初期ロード時間を短縮できる。特にサーバーサイドアプリケーションや大規模SPAで有効である。

**機能の利用シーン**：
- 起動時間が重要なCLIツール
- 条件付きで使用されるモジュール
- 大規模ライブラリの部分的な使用

**主要な処理内容**：
1. `import defer * as ns from './mod'`構文を検出
2. CommonJS変換プラグインと連携してrequireラッパーを生成
3. 参照パターンに応じてプロキシまたは関数形式を選択
4. 遅延インポートを通常インポートの後に移動して評価順序を維持

**関連システム・外部連携**：`@babel/plugin-transform-modules-commonjs`と連携してCommonJS形式に変換する。

**権限による制御**：特にロールや権限による制御はない。Babel設定ファイルでのプラグイン有効化により機能する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLIツールまたはビルドプロセスで使用され、GUI画面との関連はない |

## 機能種別

コード変換処理（AST変換）、モジュールシステム変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 本プラグインにはオプションパラメータはない | - |

### 入力データソース

- ソースコードからのASTノード（ImportDeclarationノード、phase="defer"のもの）
- @babel/plugin-transform-modules-commonjsの設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | AST Node | 変換後のAST（CommonJS形式のrequire呼び出し） |

### 出力先

- 変換後のJavaScriptコード（Babelのパイプライン出力）

## 処理フロー

### 処理シーケンス

```
1. pre()フックでCommonJSフック登録
   └─ defineCommonJSHookでwrapperペイロードを定義
2. getWrapperPayload呼び出し
   └─ 全インポートがdeferフェーズか確認
   └─ 参照パターンを分析（プロパティのみ or それ以外）
   └─ "defer/proxy"または"defer/function"を返却
3. buildRequireWrapper呼び出し
   └─ ペイロードに応じてラッパーコードを生成
4. Program visitor
   └─ 遅延インポートを通常インポートの後に移動
   └─ 評価順序を維持
```

### フローチャート

```mermaid
flowchart TD
    A[ImportDeclaration検出] --> B{phase === "defer"?}
    B -->|No| Z[処理スキップ]
    B -->|Yes| C[参照パターン分析]
    C --> D{全参照がプロパティアクセス?}
    D -->|Yes| E[defer/function ペイロード]
    D -->|No| F[defer/proxy ペイロード]
    E --> G[buildRequireWrapper]
    F --> G
    G --> H{defer/proxy?}
    H -->|Yes| I[importDeferProxyヘルパー使用]
    H -->|No| J[関数形式のラッパー生成]
    I --> K[Program visitor]
    J --> K
    K --> L[遅延インポートを末尾に移動]
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | CommonJS必須 | CommonJSへの変換時のみ動作 | @babel/plugin-transform-modules-commonjs使用時 |
| BR-02 | 参照パターン判定 | 全参照がプロパティアクセスの場合はfunction形式 | allReferencesAreProps === true |
| BR-03 | プロキシ形式 | 直接参照がある場合はProxy形式を使用 | allReferencesAreProps === false |
| BR-04 | 評価順序維持 | 通常インポートが先、遅延インポートが後 | 同一ソースの通常/遅延インポート混在時 |
| BR-05 | 未参照最適化 | 参照されていない遅延インポートはラッパー不要 | referenced === false |

### 計算ロジック

- function形式:
  ```javascript
  function ns(data) {
    ns = () => data;
    return data = require('./mod');
  }
  ```
- proxy形式:
  ```javascript
  var ns = _importDeferProxy(() => require('./mod'));
  ```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | モジュール形式エラー | CommonJS以外のモジュール形式で使用 | @babel/plugin-transform-modules-commonjsを設定 |

### リトライ仕様

リトライ処理は不要（コンパイル時のエラーはリトライ対象外）

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

トランザクション管理は不要（ファイル変換処理のため）

## パフォーマンス要件

- 変換処理自体は軽量
- 変換後のコードは実行時のモジュール評価を遅延させる

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

- ソースコード変換のため、実行時のセキュリティリスクは限定的
- Proxy使用時はES6+環境が必要

## 備考

- TC39 Stage 2 提案
- CommonJS変換時のみ動作
- 名前空間インポート（`* as ns`）形式のみサポート

---

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

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

### 推奨読解順序

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

遅延インポートの変換では、ImportDeclarationのphaseプロパティとCommonJSフックが主要なデータ構造となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-proposal-import-defer/src/index.ts` | CommonJSフックの構造（getWrapperPayload、buildRequireWrapper） |

**読解のコツ**: `defineCommonJSHook`で登録するフックオブジェクトの各メソッドの役割を理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-proposal-import-defer/src/index.ts` | pre()フックとProgram visitor |

**主要処理フロー**:
1. **26行目**: manipulateOptionsでdeferredImportEvaluationパーサープラグインを追加
2. **28-67行目**: pre()フックでCommonJSフックを登録
3. **70-116行目**: Program visitorで評価順序を調整

#### Step 3: CommonJSフック処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-plugin-proposal-import-defer/src/index.ts` | getWrapperPayload、buildRequireWrapper、wrapReference |

**主要処理フロー**:
- **34-42行目**: getWrapperPayload - 参照パターン分析とペイロード決定
- **43-61行目**: buildRequireWrapper - ラッパーコード生成
- **63-66行目**: wrapReference - 参照のラップ処理

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

```
@babel/core (transform)
    │
    └─ @babel/plugin-proposal-import-defer/src/index.ts
           │
           ├─ pre() フック
           │      │
           │      └─ defineCommonJSHook
           │             │
           │             ├─ getWrapperPayload
           │             │      └─ allReferencesAreProps
           │             │
           │             ├─ buildRequireWrapper
           │             │      ├─ defer/proxy → importDeferProxy
           │             │      └─ defer/function → 関数形式
           │             │
           │             └─ wrapReference
           │
           └─ Program visitor
                  │
                  ├─ 通常インポート収集
                  │
                  └─ 遅延インポート末尾移動
```

### データフロー図

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

ImportDeclaration          参照パターン分析                  CommonJS形式
import defer * as ns       ───▶                              var ns = _importDeferProxy(
  from './mod'                 ペイロード決定                   () => require('./mod')
                               ラッパー生成                   )
                                                              または
                                                              function ns(data) {...}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-proposal-import-defer/src/index.ts` | ソース | プラグインエントリーポイント、変換ロジック |
| package.json | `packages/babel-plugin-proposal-import-defer/package.json` | 設定 | パッケージ定義・依存関係 |
