# 機能設計書 14-@babel/standalone

## 概要

本ドキュメントは、Babelの@babel/standaloneパッケージの機能設計を記述する。@babel/standaloneは、ブラウザ環境でBabelを直接実行するためのスタンドアロンビルドである。

### 本機能の処理概要

@babel/standaloneは、ブラウザ環境でNode.jsを介さずにBabelによるコード変換を実行するためのパッケージである。CDNから読み込んで使用でき、text/babelタイプのスクリプトタグを自動検出して変換する機能も備える。

**業務上の目的・背景**：プロトタイピング、教育用途、オンラインエディタ（CodePen、JSFiddle等）などでは、ビルドステップなしでモダンJavaScriptやJSXを即座に実行したいニーズがある。@babel/standaloneは、ブラウザに読み込むだけでBabelのフル機能を利用可能にし、開発環境のセットアップ無しでES6+/JSX/TypeScriptコードを実行できるようにする。

**機能の利用シーン**：オンラインコードエディタ、REPLツール、ドキュメンテーションサイトのライブデモ、教育用インタラクティブチュートリアル、プロトタイプの素早い検証などで利用される。

**主要な処理内容**：
1. Babel core APIのブラウザ向けラッピング（transform, transformAsync等）
2. 全ての標準プラグイン・プリセットをバンドルして提供
3. text/babelスクリプトタグの自動検出と変換実行
4. カスタムプラグイン・プリセットの動的登録
5. 外部スクリプトファイル（src属性）のXHR読み込みと変換

**関連システム・外部連携**：CDN（unpkg、cdnjs等）からの配信、@babel/core、@babel/preset-env、@babel/preset-react、@babel/preset-typescriptなど全てのBabelパッケージをバンドル。

**権限による制御**：本機能に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Babelトランスフォームデモ | 主機能 | Babel APIを直接呼び出し、入力欄のES2015/JSXコードをリアルタイム変換する |
| 2 | インラインスクリプトタグデモ | 主機能 | text/babelタイプのscriptタグを自動検出し変換実行 |
| 3 | 外部スクリプトタグデモ | 主機能 | 外部JSファイル（src属性）をXHRで読み込みBabel変換を実行 |
| 4 | カスタムスクリプトタグデモ | 主機能 | disableScriptTags/transformScriptTagsによる手動変換制御 |
| 5 | スクリプト無効化デモ | 主機能 | Babel.disableScriptTagsでtext/babelスクリプトの自動変換を無効化 |

## 機能種別

ユーティリティ / ブラウザ向けトランスパイラ

## 入力仕様

### 入力パラメータ

#### transform関数

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code | string | Yes | 変換対象のソースコード | 空文字列も許容 |
| options | InputOptions | No | Babel設定オプション | - |
| options.presets | array | No | 使用するプリセット | 文字列または[名前, オプション]形式 |
| options.plugins | array | No | 使用するプラグイン | 文字列または[名前, オプション]形式 |
| options.filename | string | No | ファイル名 | ソースマップ用 |

#### registerPlugin関数

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | プラグイン名 | 重複時は警告 |
| plugin | function | Yes | プラグイン関数 | Babelプラグイン形式 |

#### registerPreset関数

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | プリセット名 | 重複時は警告 |
| preset | function | Yes | プリセット関数 | Babelプリセット形式 |

### 入力データソース

- JavaScript API呼び出し
- HTMLのtext/babel/text/jsxスクリプトタグ
- data-presets/data-plugins属性による設定
- XHRによる外部スクリプト読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result.code | string | 変換後のJavaScriptコード |
| result.map | object | ソースマップ（オプション） |
| result.ast | object | 変換後のAST（オプション） |

### 出力先

- transform関数: 戻り値として返却
- transformScriptTags: 新しいscript要素としてDOMに挿入

## 処理フロー

### 処理シーケンス

```
1. ページ読み込み時
   └─ DOMContentLoadedイベントをリッスン

2. 自動変換（DOMContentLoaded）
   └─ transformScriptTags呼び出し
       └─ text/babel, text/jsxのスクリプトタグを収集
       └─ 各スクリプトに対して変換実行
           └─ インラインコンテンツまたはXHRで取得
           └─ data-presets/data-plugins属性を解析
           └─ transform関数で変換
           └─ 新しいscript要素を作成してheadに追加

3. API呼び出し（手動）
   └─ Babel.transform(code, options)
       └─ processOptions: プリセット/プラグイン名を解決
       └─ babelTransformSync: @babel/core呼び出し
       └─ 変換結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[ページ読み込み] --> B[DOMContentLoaded]
    B --> C{disableScriptTags?}
    C -->|No| D[transformScriptTags]
    C -->|Yes| E[何もしない]
    D --> F[text/babel/jsxタグを収集]
    F --> G{スクリプトあり?}
    G -->|Yes| H[loadScripts]
    G -->|No| E
    H --> I{src属性?}
    I -->|Yes| J[XHRで読み込み]
    I -->|No| K[innerHTML取得]
    J --> L[transform実行]
    K --> L
    L --> M[script要素作成]
    M --> N[headに追加]
    N --> O{次のスクリプト?}
    O -->|Yes| I
    O -->|No| P[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | スクリプトタイプ検出 | text/babel, text/jsxを変換対象とする | transformScriptTags |
| BR-02 | 実行順序保証 | スクリプトはDOM順で順次実行 | 複数スクリプト時 |
| BR-03 | デフォルトプリセット | 指定なしの場合env, reactプリセットを使用 | presets未指定時 |
| BR-04 | babelrc無効化 | スタンドアロン環境ではbabelrcを参照しない | 常時 |
| BR-05 | ソースマップ | インラインソースマップを生成 | 常時 |
| BR-06 | 警告表示 | プロダクション利用の警告をconsoleに出力 | transformScriptTags使用時 |

### 計算ロジック

プリセット/プラグイン解決:
```javascript
// 文字列の場合
"react" -> availablePresets["react"]

// 配列の場合
["env", { modules: false }] -> [availablePresets["env"], { modules: false }]

// 見つからない場合
throw new Error("Invalid preset specified in Babel options: ...")
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | 未登録のプリセット/プラグイン指定 | registerPreset/registerPluginで登録 |
| - | XHR Error | 外部スクリプト読み込み失敗 | URLを確認、CORS設定を確認 |
| - | SyntaxError | 変換対象コードの構文エラー | ソースコードを修正 |

### リトライ仕様

XHR読み込みに対するリトライは実装されていない。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- 初期読み込み: パッケージサイズは約2MB（minified）
- 変換時間: コードサイズに依存するが、プロダクション利用は非推奨
- 警告: 「Be sure to precompile your scripts for production」と表示

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

- XHRで外部スクリプトを読み込む際はCORS制約に従う
- text/babelスクリプトは即座に実行されるため、信頼できるソースのみ使用
- CSPとの互換性に注意（eval使用の可能性）

## 備考

- プロダクション環境での使用は非推奨
- Hermes parserはサポートされない（IS_STANDALONE定数で判定）
- レガシープラグインエイリアスもサポート

---

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

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

### 推奨読解順序

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

まず、メインのエクスポートとAPI構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-standalone/src/index.ts` | 全てのAPI関数と初期化処理 |

**読解のコツ**:
- **1-7行目**: JSDocコメントでパッケージの目的を説明
- **12-20行目**: @babel/coreからの関数インポート
- **50-56行目**: availablePluginsにall（全プラグイン）を登録
- **60-87行目**: availablePresetsの定義（env, react, typescript等）
- **178-184行目**: transform関数の実装（processOptionsでオプション処理）
- **206-213行目**: registerPlugin関数の実装
- **260-268行目**: DOMContentLoadedイベントハンドラ
- **274-278行目**: transformScriptTags関数
- **283-285行目**: disableScriptTags関数

#### Step 2: オプション処理を理解する

プリセット/プラグイン名の解決処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-standalone/src/index.ts` | processOptions, loadBuiltin関数 |

**主要処理フロー**:
- **102-113行目**: loadBuiltin関数。文字列または配列からプリセット/プラグインを解決
- **134-176行目**: processOptions関数。presetsとpluginsを解決してbabelrcを無効化

#### Step 3: スクリプトタグ変換を理解する

text/babelスクリプトの自動変換処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | transformScriptTags.ts | `packages/babel-standalone/src/transformScriptTags.ts` | スクリプトタグ処理の実装 |

**主要処理フロー**:
- **9行目**: scriptTypesセット（text/jsx, text/babel）
- **38-54行目**: transformCode関数。ソースとBabelオプションを構築して変換
- **60-99行目**: buildBabelOptions関数。data-presets/data-plugins属性の解析
- **105-115行目**: run関数。変換結果を新しいscript要素としてDOMに追加
- **120-144行目**: load関数。XHRで外部スクリプトを読み込み
- **173-234行目**: loadScripts関数。複数スクリプトの順次処理
- **240-270行目**: runScripts関数。エントリーポイント

#### Step 4: プラグイン定義を理解する

バンドルされたプラグインの定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | generated/plugins.ts | `packages/babel-standalone/src/generated/plugins.ts` | 自動生成されたプラグイン一覧 |
| 4-2 | packages.ts | `packages/babel-standalone/src/packages.ts` | 公開パッケージの定義 |

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

```
ブラウザ
    │
    └─ @babel/standalone ロード
           │
           ├─ registerPlugins(all)  ← 全プラグイン登録
           │
           ├─ DOMContentLoaded
           │      └─ transformScriptTags
           │             ├─ runScripts
           │             │      └─ loadScripts
           │             │             ├─ load (XHR)
           │             │             └─ transformCode
           │             │                    └─ transform
           │             │                           └─ processOptions
           │             │                                  └─ loadBuiltin
           │             │
           │             └─ run (script要素作成)
           │
           └─ Babel.transform 呼び出し（手動）
                  └─ processOptions
                         └─ babelTransformSync (@babel/core)
```

### データフロー図

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

text/babelスクリプト ─────> runScripts ─────> loadScripts ──┐
                                                            │
src属性付きスクリプト ────> XHR load ─────────────────────────┤
                                                            │
data-presets属性 ─────────> buildBabelOptions ───────────────┼──> transform ──> script要素
data-plugins属性 ─────────> parseFromScriptAttribute ────────┤        │
                                                            │        └──> headに追加
Babel.transform(code) ────> processOptions ─────────────────┘
                                   │
                                   └──> { code, map, ast }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-standalone/src/index.ts` | ソース | メインエントリーポイント、API定義 |
| transformScriptTags.ts | `packages/babel-standalone/src/transformScriptTags.ts` | ソース | スクリプトタグ変換処理 |
| generated/plugins.ts | `packages/babel-standalone/src/generated/plugins.ts` | ソース | バンドルプラグイン一覧（自動生成） |
| packages.ts | `packages/babel-standalone/src/packages.ts` | ソース | 公開パッケージ定義 |
| preset-es2015.ts | `packages/babel-standalone/src/preset-es2015.ts` | ソース | ES2015プリセット |
| preset-stage-0.ts | `packages/babel-standalone/src/preset-stage-0.ts` | ソース | Stage 0プリセット |
| preset-stage-1.ts | `packages/babel-standalone/src/preset-stage-1.ts` | ソース | Stage 1プリセット |
| preset-stage-2.ts | `packages/babel-standalone/src/preset-stage-2.ts` | ソース | Stage 2プリセット |
| preset-stage-3.ts | `packages/babel-standalone/src/preset-stage-3.ts` | ソース | Stage 3プリセット |
| package.json | `packages/babel-standalone/package.json` | 設定 | パッケージ設定 |
| examples/example.js | `packages/babel-standalone/examples/example.js` | サンプル | 使用例 |
