# 機能設計書 6-@babel/node

## 概要

本ドキュメントは、BabelのNode.js統合ツールである`@babel/node`パッケージの設計仕様を記述する。このパッケージは、Node.jsのCLIをラップして、実行前にBabelによるコード変換を自動的に適用する。開発環境で最新のJavaScript構文を直接実行可能にする。

### 本機能の処理概要

**業務上の目的・背景**：開発中にESM構文やTypeScript等の最新言語機能を使用したスクリプトを、事前のビルドなしに直接実行したい場合がある。@babel/nodeは、Node.jsの実行環境をBabelで拡張し、スクリプト実行前に自動的にトランスパイルを行うことで、シームレスな開発体験を提供する。

**機能の利用シーン**：開発中のスクリプト実行、REPLでのインタラクティブなコード試行、evalモードでのワンライナー実行に利用される。

**主要な処理内容**：
1. @babel/registerの設定とNode.jsへの統合
2. スクリプトファイルの実行
3. REPL（Read-Eval-Print Loop）の提供
4. evalモードでのコード評価
5. Top-Level Awaitのサポート

**関連システム・外部連携**：@babel/core（変換処理）、@babel/register（require hookの登録）、Node.js vm/repl モジュールと連携する。

**権限による制御**：Node.js実行環境の権限に準ずる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLI/REPL（コマンドラインインターフェース）として動作 |

## 機能種別

ランタイム実行ツール

## 入力仕様

### 入力パラメータ（コマンドラインオプション）

| パラメータ名 | 型 | 必須 | 説明 | デフォルト |
|-------------|-----|-----|------|---------|
| [script.js] | string | No | 実行するスクリプトファイル | - |
| [arguments...] | string[] | No | スクリプトに渡す引数 | - |
| -e, --eval | string | No | 評価するスクリプト | - |
| -p, --print | string | No | 評価して結果を出力 | - |
| -r, --require | string | No | 事前にrequireするモジュール | - |
| --no-babelrc | boolean | No | .babelrcを使用しない | false |
| -o, --only | string[] | No | コンパイル対象のglobパターン | - |
| -i, --ignore | string[] | No | スキップするglobパターン | - |
| -x, --extensions | string[] | No | フック対象の拡張子 | .es6,.js,.es,.jsx,.mjs |
| --config-file | string | No | Babel設定ファイルのパス | - |
| --env-name | string | No | 環境名 | BABEL_ENV \|\| NODE_ENV \|\| "development" |
| --root-mode | string | No | ルート解決モード | root |
| -w, --plugins | string[] | No | 使用するプラグイン | - |
| -b, --presets | string[] | No | 使用するプリセット | - |

### 入力データソース

- コマンドライン引数
- スクリプトファイル
- REPL入力
- evalモードの文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| スクリプト実行結果 | any | スクリプトの戻り値/出力 |
| REPL出力 | any | REPL評価結果 |
| 標準出力 | stdout | console.log等の出力 |
| 標準エラー | stderr | エラー出力 |

### 出力先

- 標準出力
- 標準エラー出力
- REPLプロンプト

## 処理フロー

### 処理シーケンス

```
1. CLIエントリーポイント (_babel-node.ts)
   └─ commander.program.parse(process.argv)
2. @babel/registerの設定
   └─ babelOptionsの構築
   └─ register(babelOptions)
3. 処理モード分岐
   ├─ --eval / --print モード
   │      └─ babel.transformSyncでコード変換
   │      └─ vm.runInThisContextで実行
   ├─ スクリプトファイル実行モード
   │      └─ requireArgsで事前モジュール読み込み
   │      └─ Module.runMain()でスクリプト実行
   └─ REPLモード
          └─ replStart()
          └─ 各入力をbabel.transformSyncで変換
          └─ vm.runInThisContextで実行
```

### フローチャート

```mermaid
flowchart TD
    A[babel-node実行] --> B[program.parse]
    B --> C[register: @babel/register設定]
    C --> D{実行モード?}
    D -->|--eval/--print| E[_eval関数]
    E --> F[babel.transformSync]
    F --> G{hasTopLevelAwait?}
    G -->|Yes| H[async IIFEでラップ]
    G -->|No| I[そのまま実行]
    H --> J[vm.runInThisContext]
    I --> J
    J --> K{--print?}
    K -->|Yes| L[結果を出力]
    K -->|No| M[終了]
    D -->|script.js| N[requireArgs]
    N --> O[Module.runMain]
    O --> M
    D -->|REPL| P[replStart]
    P --> Q[repl.start]
    Q --> R[replEval]
    R --> E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Top-Level Await | REPLでTop-Level Awaitをサポート、async IIFEでラップ | hasTopLevelAwait時 |
| BR-02 | モジュール非対応 | REPLではimport/export文を使用不可 | REPLモード |
| BR-03 | allowAwaitOutsideFunction | パーサーオプションで有効化 | 常時 |
| BR-04 | caller設定 | @babel/nodeをcaller.nameに設定 | 常時 |
| BR-05 | 履歴保存 | REPLの入力履歴はNODE_REPL_HISTORYに保存 | REPLモード |

### 計算ロジック

特になし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | モジュールエラー | REPLでimport/export使用 | エラーメッセージ表示 |
| - | 構文エラー | 無効なJavaScript | Babelのエラーメッセージ表示 |
| - | 実行時エラー | スクリプト実行中のエラー | Node.jsのエラーハンドリング |

### リトライ仕様

- REPLモードではエラー後も継続して入力を受け付ける

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

該当なし

## パフォーマンス要件

- @babel/registerを通じた実行時コンパイルのため、事前ビルドに比べて起動が遅くなる場合がある
- 開発環境での使用を想定、本番環境では事前ビルドを推奨

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

- evalモードは任意のコードを実行可能なため、信頼できる入力のみを使用すること
- vm.runInThisContextで現在のコンテキストでコードを実行

## 備考

- core-js/stableがデフォルトでimportされポリフィルが適用される
- REPLプロンプトは "babel > "

---

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

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

### 推奨読解順序

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

まず、コマンドラインオプションの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | program-setup.ts | `packages/babel-node/src/program-setup.ts` | オプション定義（1-64行目） |

**読解のコツ**: commanderライブラリのオプション定義パターンを理解することで、CLIの入力仕様が把握できる。

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

処理の起点となるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | _babel-node.ts | `packages/babel-node/src/_babel-node.ts` | メインエントリーポイント（1-249行目） |

**主要処理フロー**:
1. **18行目**: program.parse(process.argv)でCLI引数解析
2. **21-38行目**: babelOptionsの構築
3. **46行目**: register(babelOptions)で@babel/registerを設定
4. **119-140行目**: --eval/--printモードの処理
5. **141-190行目**: スクリプトファイル実行モード
6. **186-189行目**: REPLモードの開始

#### Step 3: コード評価処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | _babel-node.ts | `packages/babel-node/src/_babel-node.ts` | _eval関数（95-117行目） |

**主要処理フロー**:
- **101-108行目**: babel.transformSyncでコード変換
- **110-112行目**: Top-Level Awaitの処理（async IIFEでラップ）
- **114-116行目**: vm.runInThisContextで実行

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | _babel-node.ts | `packages/babel-node/src/_babel-node.ts` | replPlugin（50-93行目）、replStart関数（235-248行目） |

**主要処理フロー**:
- **50-93行目**: replPluginでASTを変換（Top-Level Await対応、import/export禁止）
- **202-233行目**: replEval関数でREPL入力を評価
- **235-248行目**: replStart関数でREPLサーバー起動

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

```
babel-node (_babel-node.ts)
    │
    ├─ program.parse (program-setup.ts)
    │      └─ commander
    │
    ├─ register (@babel/register)
    │      └─ require hook設定
    │
    └─ 実行モード
           │
           ├─ --eval / --print
           │      └─ _eval
           │             ├─ babel.transformSync
           │             │      └─ replPlugin
           │             └─ vm.runInThisContext
           │
           ├─ script.js
           │      ├─ requireArgs
           │      └─ Module.runMain
           │
           └─ REPL
                  └─ replStart
                         ├─ repl.start
                         └─ replEval
                                └─ _eval
```

### データフロー図

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

CLI引数 ───────▶ program.parse ───────▶ opts
                                            │
                                    @babel/register
                                            │
スクリプト ───────▶ babel.transformSync ───────▶ 変換済みコード
                           │
                      replPlugin
                           │
                   vm.runInThisContext ───────▶ 実行結果
                                                     │
REPL入力 ───────▶ replEval ───────────────────▶ REPL出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| _babel-node.ts | `packages/babel-node/src/_babel-node.ts` | ソース | メインエントリーポイント |
| program-setup.ts | `packages/babel-node/src/program-setup.ts` | ソース | CLIオプション定義 |
