# 機能設計書 43-@babel/plugin-transform-modules-systemjs

## 概要

本ドキュメントは、BabelプラグインであるES2015モジュールからSystemJS形式への変換機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：
SystemJSは動的モジュールローダーであり、ES2015モジュール、AMD、CommonJSなど様々なモジュール形式をブラウザで読み込むことができる。特にAngular 1.xやJSPM（JavaScript Package Manager）エコシステムで広く使用されていた。本プラグインは、ES2015モジュール構文をSystemJS形式（System.register）に変換することで、これらの環境との互換性を提供する。

**機能の利用シーン**：
- SystemJSローダーを使用するプロジェクトでの開発
- JSPMベースのワークフローでのモジュール管理
- 動的インポートと循環依存を正しく処理する必要がある場合
- import.metaやTop-Level Await（TLA）を使用するプロジェクト

**主要な処理内容**：
1. ES2015のimport/export文をSystem.register形式に変換
2. セッター（setters）配列によるインポートバインディングの動的更新
3. execute関数内への元コードの移動
4. 動的インポート（import()）のSystemJS context.import()への変換
5. import.metaのcontext.metaへの変換
6. エクスポート値の再代入時の自動更新処理

**関連システム・外部連携**：
@babel/helper-module-transformsと連携。@babel/helper-validator-identifierで識別子の検証を実施。

**権限による制御**：
プラグインオプション（systemGlobal、allowTopLevelThis）による動作制御が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLI/APIから利用されるプラグインのため、直接の画面関連なし |

## 機能種別

データ変換（AST変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| allowTopLevelThis | boolean | No | トップレベルのthisをundefinedに変換しない（デフォルト: false） | - |
| systemGlobal | string | No | SystemJSグローバル変数名（デフォルト: "System"） | - |

### 入力データソース

ES2015モジュール構文を含むJavaScriptソースコード（AST形式）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | t.Program | SystemJS形式に変換されたAST |
| System.register | t.CallExpression | SystemJSの登録関数呼び出し |

### 出力先

変換されたAST（@babel/coreに返却）

## 処理フロー

### 処理シーケンス

```
1. Program.enterビジター
   └─ contextIdent生成、stringSpecifiers初期化
   └─ allowTopLevelThis=falseならthisを書き換え
2. CallExpression/ImportExpressionビジター
   └─ 動的importをcontext.import()に変換
3. MetaPropertyビジター
   └─ import.metaをcontext.metaに変換
4. ReferencedIdentifierビジター
   └─ __moduleNameをcontext.idに変換
5. Program.exitビジター
   └─ import/export文を解析
   └─ setters配列を構築
   └─ execute関数を構築
   └─ System.register呼び出しを生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Program.enter]
    B --> C[contextIdent生成]
    C --> D{allowTopLevelThis?}
    D -->|No| E[thisをundefinedに書き換え]
    D -->|Yes| F[そのまま]
    E --> G[import/export解析]
    F --> G
    G --> H[インポート用setters構築]
    H --> I[エクスポートバインディング設定]
    I --> J[再代入ビジター適用]
    J --> K{TLAあり?}
    K -->|Yes| L[execute関数をasyncに]
    K -->|No| M[execute関数を通常に]
    L --> N[System.register生成]
    M --> N
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-01 | SystemJS形式変換 | import/exportをSystem.register形式に変換 | ESモジュール構文検出時 |
| BR-43-02 | セッター生成 | 各インポートソースに対してセッター関数を生成 | インポート文検出時 |
| BR-43-03 | エクスポート追跡 | エクスポート変数の再代入時にexport関数を呼び出し | エクスポート変数更新時 |
| BR-43-04 | TLA対応 | Top-Level Awaitを検出した場合、execute関数をasyncに | awaitキーワード検出時 |
| BR-43-05 | 動的import変換 | import()をcontext.import()に変換 | 動的import検出時 |

### 計算ロジック

特になし（構文変換のみ）

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

該当なし（ファイルシステム操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| MISSING_DYNAMIC_IMPORT_PLUGIN | 設定エラー | 動的import使用時にプラグイン未設定 | @babel/plugin-transform-dynamic-importを追加 |
| INVALID_EXPORT_SPECIFIER | 構文エラー | 無効なエクスポート指定子 | エクスポート構文を修正 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

特定のパフォーマンス要件なし（変換処理は同期的に実行）

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

- allowTopLevelThis=falseでトップレベルthisを無効化し、グローバルオブジェクトへの意図しないアクセスを防止

## 備考

- SystemJSは循環依存を正しく処理できる唯一のモジュール形式の1つ
- セッター関数によりライブバインディング（Live Bindings）を実現
- Top-Level Await（TLA）のサポートによりES2022+のコードも変換可能

---

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

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

### 推奨読解順序

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

まず、プラグインの状態型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-modules-systemjs/src/index.ts` | PluginState型（62-69行目）とModuleMetadata型（71-75行目） |

**読解のコツ**: `stringSpecifiers`はUnicode識別子をサポートするためのセット。`contextIdent`はSystemJSのコンテキストオブジェクト参照用。

#### Step 2: テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-modules-systemjs/src/index.ts` | buildTemplateテンプレート（12-21行目） |

**主要処理フロー**:
- **12-21行目**: System.register形式のテンプレート構造
- **23-27行目**: export * fromのためのforループテンプレート

#### Step 3: 再代入ビジターを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-plugin-transform-modules-systemjs/src/index.ts` | reassignmentVisitor（177-249行目） |

**主要処理フロー**:
- **177-249行目**: AssignmentExpression/UpdateExpressionを検出してエクスポート更新コードを注入
- **221-237行目**: ポストインクリメント（x++）の特別処理

#### Step 4: Program.exitビジターを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/babel-plugin-transform-modules-systemjs/src/index.ts` | Program.exit（325-694行目） |

**主要処理フロー**:
- **325-328行目**: exportIdent、contextIdent、stringSpecifiersの取得
- **377-404行目**: ImportDeclarationの処理
- **407-527行目**: ExportDeclarationの処理
- **529-615行目**: setters配列の構築
- **663-694行目**: System.register呼び出しの生成

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

```
@babel/plugin-transform-modules-systemjs/src/index.ts
    │
    ├─ @babel/helper-plugin-utils/declare()
    │      └─ プラグイン定義の標準化
    │
    ├─ @babel/helper-module-transforms
    │      ├─ buildDynamicImport()
    │      ├─ getModuleName()
    │      └─ rewriteThis()
    │
    ├─ @babel/helper-validator-identifier
    │      └─ isIdentifierName()
    │
    └─ @babel/core/template
           ├─ buildTemplate (System.register)
           └─ buildExportAll (for-in loop)
```

### データフロー図

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

ESModuleソースコード  ──▶  Parser (AST生成)
                              │
                              ▼
                      Import/Export解析
                              │
                     ┌────────┼────────┐
                     ▼        ▼        ▼
               setters   exports   execute
                 配列      map      関数
                     │        │        │
                     └────────┼────────┘
                              │
                              ▼
                      System.register()
                              │
                              ▼
                    SystemJSモジュールAST ──▶ Generator ──▶ SystemJS形式コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-modules-systemjs/src/index.ts` | ソース | メインプラグイン実装（700行） |
| package.json | `packages/babel-plugin-transform-modules-systemjs/package.json` | 設定 | 依存関係・メタデータ |
| helper-module-transforms | `packages/babel-helper-module-transforms/src/` | ソース | モジュール変換共通ヘルパー |
| helper-validator-identifier | `packages/babel-helper-validator-identifier/src/` | ソース | 識別子検証ユーティリティ |
