# 機能設計書 18-@babel/preset-flow

## 概要

本ドキュメントは、Babelの@babel/preset-flowパッケージの機能設計を記述する。@babel/preset-flowは、Flow型アノテーションを削除するためのプリセットである。

### 本機能の処理概要

@babel/preset-flowは、Flowの型アノテーションをソースコードから削除し、純粋なJavaScriptコードに変換する。Flowはfacebook製の静的型チェッカーであり、型チェック後にJavaScriptとして実行するためには型情報の削除が必要である。

**業務上の目的・背景**：FlowはJavaScriptに型アノテーションを追加する静的型チェッカーであり、Metaが開発した。Flowで書かれたコードはブラウザやNode.jsで直接実行できないため、型アノテーションを削除する必要がある。@babel/preset-flowは、Flowコードをビルドパイプラインに組み込み、他のBabelプラグインと組み合わせて使用できるようにする。

**機能の利用シーン**：Flowプロジェクトのビルド、React NativeアプリケーションのFlowコード変換、レガシーFlowプロジェクトのメンテナンスなどで利用される。

**主要な処理内容**：
1. Flow型アノテーションの削除（@babel/plugin-transform-flow-strip-types）
2. TypeScriptファイル（.ts/.tsx）の自動除外
3. Hermesパーサーのオプションサポート
4. すべてのファイルでFlowを強制するオプション（all）

**関連システム・外部連携**：@babel/plugin-transform-flow-strip-types、babel-plugin-syntax-hermes-parserと連携。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし | - | CLIおよびAPIとして利用 |

## 機能種別

プリセット / Flow型削除

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| all | boolean | No | すべてのファイルでFlowを強制 | デフォルト: false |
| ignoreExtensions | boolean | No | 拡張子による自動除外を無効化 | デフォルト: false |
| experimental_useHermesParser | boolean | No | Hermesパーサーを使用 | デフォルト: false |

### 入力データソース

- Babel設定ファイル（babel.config.js, .babelrc等）
- API呼び出しのオプション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| plugins | array | 適用するプラグインの配列 |
| overrides | array | ファイル拡張子別の設定（ignoreExtensions: false時） |

### 出力先

Babelコア(@babel/core)に対してプラグイン配列とoverridesを返却する。

## 処理フロー

### 処理シーケンス

```
1. オプションの正規化
   └─ normalizeOptions: デフォルト値設定

2. プラグインの構築
   └─ transform-flow-strip-typesプラグインを追加
   └─ allオプションを渡す

3. Hermesパーサーの設定（オプション）
   └─ experimental_useHermesParser: true
       └─ Node.js 12以上を確認
       └─ スタンドアロン環境でないことを確認
       └─ syntax-hermes-parserプラグインを追加

4. 拡張子別設定
   └─ ignoreExtensions: true → プラグインのみ返却
   └─ ignoreExtensions: false → overridesで.ts/.tsx除外

5. 設定の返却
```

### フローチャート

```mermaid
flowchart TD
    A[preset-flow呼び出し] --> B[normalizeOptions]
    B --> C[flow-strip-typesプラグイン構築]
    C --> D{useHermesParser?}
    D -->|Yes| E{Node 12以上?}
    D -->|No| H{ignoreExtensions?}
    E -->|Yes| F{IS_STANDALONE?}
    E -->|No| G[Errorをthrow]
    F -->|Yes| G
    F -->|No| I[syntax-hermes-parser追加]
    I --> H
    H -->|Yes| J[pluginsのみ返却]
    H -->|No| K[overridesで.ts/.tsx除外]
    J --> L[返却]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | TypeScript除外 | .ts/.tsxファイルはFlow変換しない | ignoreExtensions: false |
| BR-02 | all オプション | @flow ディレクティブなしでもFlow構文を処理 | all: true |
| BR-03 | Hermes制限 | HermesパーサーはNode.js 12以上でのみ利用可能 | useHermesParser: true |
| BR-04 | Standalone制限 | Hermesパーサーはスタンドアロンビルドでサポートなし | IS_STANDALONE |

### 計算ロジック

Flow変換例:
```javascript
// 入力（Flow）
// @flow
function greet(name: string): string {
  return `Hello, ${name}!`;
}
type User = {
  name: string,
  age: number
};

// 出力（型アノテーション削除）
function greet(name) {
  return `Hello, ${name}!`;
}
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | Node.js 12未満でHermes使用 | Node.jsをアップグレード |
| - | Error | スタンドアロンでHermes使用 | Hermesを無効化 |
| - | SyntaxError | 不正なFlow構文 | コードを修正 |

### リトライ仕様

本機能にリトライ処理は存在しない。

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

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

## パフォーマンス要件

- 型削除のみのため高速
- Hermesパーサー使用時は追加のパースオーバーヘッド

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

- 入力コードの検証は行わない
- 変換のみを実行

## 備考

- TypeScriptが主流となり、Flow使用プロジェクトは減少傾向
- Metaの一部プロジェクト（React等）は依然としてFlowを使用
- Hermesパーサーは実験的機能

---

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

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

### 推奨読解順序

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

まず、プリセットのメイン処理を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-preset-flow/src/index.ts` | プリセットのメイン実装 |

**読解のコツ**:
- **1-3行目**: インポート文。transformFlowStripTypesをインポート
- **5-11行目**: declarePreset関数の開始とオプション取得
- **8-10行目**: オプションの分割代入（all, ignoreExtensions, useHermesParser）
- **13行目**: プラグイン配列の構築
- **15-27行目**: Hermesパーサーの条件付き追加

#### Step 2: Hermesパーサーの条件を理解する

Hermesパーサー使用時の制約を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-preset-flow/src/index.ts` | 15-27行目のuseHermesParser処理 |

**主要処理フロー**:
- **16-19行目**: Node.js 12未満でのエラー
- **20-23行目**: IS_STANDALONE環境でのエラー
- **26行目**: syntax-hermes-parserプラグインの追加

#### Step 3: 拡張子除外ロジックを理解する

TypeScriptファイルの自動除外を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-preset-flow/src/index.ts` | 29-40行目のoverrides設定 |

**主要処理フロー**:
- **29-30行目**: ignoreExtensions: trueの場合、プラグインのみ返却
- **33-39行目**: overridesでTypeScriptファイルを除外するテスト関数

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

```
@babel/preset-flow
    │
    ├─ declarePreset (@babel/helper-plugin-utils)
    │
    ├─ normalizeOptions
    │      └─ オプションの検証と正規化
    │
    └─ plugins[]
           │
           ├─ babel-plugin-syntax-hermes-parser (オプション)
           │
           └─ @babel/plugin-transform-flow-strip-types
                  └─ { all: boolean }
```

### データフロー図

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

Flowコード ────────────> normalizeOptions ───────────────┐
                                                        │
ファイル拡張子 ────────> test関数でマッチ ────────────────┤
                                                        │
                                                        └──> flow-strip-types
                                                                    │
                                                        型アノテーション削除
                                                        型宣言削除
                                                                    │
                                                        JavaScriptコード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-preset-flow/src/index.ts` | ソース | プリセットメイン実装 |
| normalize-options.ts | `packages/babel-preset-flow/src/normalize-options.ts` | ソース | オプション正規化 |
| package.json | `packages/babel-preset-flow/package.json` | 設定 | パッケージ設定 |
| test/flow.js | `packages/babel-preset-flow/test/flow.js` | テスト | ユニットテスト |
