# 機能設計書 38-@babel/plugin-transform-export-namespace-from

## 概要

本ドキュメントは、Babelの変換プラグイン「@babel/plugin-transform-export-namespace-from」の機能設計を記述する。本プラグインはES2020の名前空間エクスポート構文（`export * as ns from "module"`）を、古いJavaScript環境でも動作する形式に変換する。

### 本機能の処理概要

本プラグインは、名前空間エクスポート構文を検出し、importとexportの組み合わせに変換する機能を提供する。これにより、ES2020以前の環境でも名前空間としてのモジュール再エクスポートを実現できる。

**業務上の目的・背景**：ES2020で導入された`export * as ns from "module"`構文は、モジュールの全エクスポートを名前空間オブジェクトとして再エクスポートできる機能である。これはモジュールの組織化やファサードパターンの実装に便利である。古いブラウザやNode.jsバージョンではこの構文をサポートしていないため、トランスパイルが必要となる。

**機能の利用シーン**：
- モジュールの再エクスポート（バレルファイル）
- ライブラリのファサードパターン実装
- `@babel/preset-env`の一部として自動的に適用される場合

**主要な処理内容**：
1. ExportNamedDeclaration内のExportNamespaceSpecifierを検出
2. `import * as _ns from "module"`に変換
3. `export { _ns as ns }`に変換
4. 残りのspecifierがあれば元のExportNamedDeclarationを維持

**関連システム・外部連携**：
- `@babel/helper-plugin-utils`: プラグインユーティリティ
- `@babel/core`: Babelコアとの統合

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

## 関連画面

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

## 機能種別

コード変換処理 / AST操作

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- Babelによってパースされたソースコード（AST形式）
- ExportNamedDeclaration内のExportNamespaceSpecifier

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | AST | 変換後のAST |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化

2. ExportNamedDeclarationの処理
   ├─ ExportDefaultSpecifier（index 0）のチェック
   ├─ ExportNamespaceSpecifierの検出
   ├─ 一意な識別子の生成
   ├─ ImportDeclaration（名前空間インポート）の生成
   ├─ ExportNamedDeclaration（名前付きエクスポート）の生成
   └─ 残りのspecifierがあれば元のノードを維持

3. スコープへの登録
   └─ path.scope.registerDeclaration()
```

### フローチャート

```mermaid
flowchart TD
    A[ExportNamedDeclarationの訪問] --> B{ExportNamespaceSpecifier?}
    B -->|No| Z[変換なし]
    B -->|Yes| C{先頭にExportDefaultSpecifier?}
    C -->|Yes| D[ExportDefaultSpecifierを別のExportとして分離]
    C -->|No| E[ExportNamespaceSpecifierを処理]
    D --> E
    E --> F[一意な識別子を生成]
    F --> G[import * as _uid from source を生成]
    G --> H[export _uid as exported を生成]
    H --> I{残りのspecifier?}
    I -->|Yes| J[元のノードを維持]
    I -->|No| K[元のノードを削除]
    J --> L[変換完了]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-01 | 識別子の一意性 | scope.generateUidIdentifierで衝突しない識別子を生成 | 常時 |
| BR-38-02 | スコープ登録 | 生成したimportDeclarationをスコープに登録 | 常時 |
| BR-38-03 | ExportDefaultSpecifier分離 | 先頭のExportDefaultSpecifierは別のExportとして分離 | ExportDefaultSpecifier存在時 |

### 計算ロジック

- 変換: `export * as ns from "mod"` → `import * as _ns from "mod"; export { _ns as ns };`
- 変換: `export v, * as ns from "mod"` → `export { v } from "mod"; import * as _ns from "mod"; export { _ns as ns };`

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | SyntaxError | 不正なエクスポート構文 | パーサーレベルでエラー |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 変換処理は同期的に実行される
- 軽量な変換処理

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

- 特になし

## 備考

- 本プラグインは`@babel/preset-env`に含まれており、ターゲット環境に応じて自動的に適用される
- ES2020をサポートしない環境向けの変換

---

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

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

### 推奨読解順序

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

本プラグインはExportNamedDeclaration内のExportNamespaceSpecifierを変換対象とする。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-export-namespace-from/src/index.ts` | シンプルな構造。ExportNamedDeclaration visitorのみ |

**読解のコツ**: 本プラグインは比較的シンプルで、1ファイルで完結している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-export-namespace-from/src/index.ts` | ExportNamedDeclaration visitorの実装 |

**主要処理フロー**:
1. **1-2行目**: 必要なモジュールのインポート
2. **4-5行目**: APIバージョン検証
3. **11-16行目**: ExportNamespaceSpecifierのインデックス決定
4. **18-23行目**: ExportDefaultSpecifierの分離処理
5. **26-31行目**: 一意な識別子の生成
6. **33-40行目**: ImportDeclarationとExportNamedDeclarationの生成
7. **43-45行目**: 残りのspecifierの処理
8. **47-48行目**: replaceWithMultipleとスコープ登録

#### Step 3: 変換ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts (33-40行目) | `packages/babel-plugin-transform-export-namespace-from/src/index.ts` | ImportDeclarationとExportNamedDeclarationの生成 |

**主要処理フロー**:
- **34-37行目**: `t.importDeclaration([t.importNamespaceSpecifier(uid)], source)`
- **38-40行目**: `t.exportNamedDeclaration(null, [t.exportSpecifier(uid, exported)])`

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

```
@babel/plugin-transform-export-namespace-from/src/index.ts
    │
    └─ visitor.ExportNamedDeclaration()
           │
           ├─ t.isExportDefaultSpecifier() チェック
           │
           ├─ t.isExportNamespaceSpecifier() チェック
           │
           ├─ scope.generateUidIdentifier()
           │
           ├─ t.importDeclaration()
           │      └─ t.importNamespaceSpecifier(uid)
           │
           ├─ t.exportNamedDeclaration()
           │      └─ t.exportSpecifier(uid, exported)
           │
           └─ path.replaceWithMultiple()
                  └─ path.scope.registerDeclaration()
```

### データフロー図

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

export * as ns      ─▶  ExportNamedDeclaration     ─▶  import * as _ns from "mod";
from "mod"               visitor                        export { _ns as ns };
                              │
                              ├─ generateUidIdentifier()
                              ├─ importDeclaration()
                              └─ exportNamedDeclaration()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-export-namespace-from/src/index.ts` | ソース | プラグインエントリーポイント、変換ロジック |
| package.json | `packages/babel-plugin-transform-export-namespace-from/package.json` | 設定 | パッケージ依存関係定義 |
| test/index.js | `packages/babel-plugin-transform-export-namespace-from/test/index.js` | テスト | テストランナー設定 |
| fixtures/export-namespace/ | `packages/babel-plugin-transform-export-namespace-from/test/fixtures/export-namespace/` | テスト | 変換テストケース |
