# 機能設計書 21-babel-preset-jest

## 概要

本ドキュメントは、Jest用Babelプリセット（babel-preset-jest）の機能設計を記述する。このプリセットは、Jestテスト環境でBabelを使用する際に必要なプラグインとプリセットを一括で提供する。

### 本機能の処理概要

babel-preset-jestは、Jestテスティングフレームワークで使用するBabelプリセットである。babel-jestパッケージを使用する際に自動的に適用され、テストコードの変換に必要な機能を提供する。

**業務上の目的・背景**：モダンなJavaScript/TypeScriptプロジェクトでは、ESM構文やJSXなど、Node.jsがネイティブにサポートしていない構文を使用することが多い。Jestでテストを実行する際、これらの構文をNode.jsで実行可能な形式に変換する必要がある。また、`jest.mock()`呼び出しはモジュールのインポート前に実行される必要があるため、コードの「ホイスティング」（巻き上げ）処理が必要となる。babel-preset-jestは、これらの課題を解決するためのBabel設定を一括で提供する。

**機能の利用シーン**：
- Jestでテストを実行する際に自動的に適用される（babel-jest経由）
- Babelの設定ファイル（babel.config.js）で明示的にプリセットとして指定
- CLIからBabelを使用する際にプリセットとして指定

**主要な処理内容**：
1. babel-plugin-jest-hoistプラグインの適用（jest.mock()のホイスティング）
2. babel-preset-current-node-syntaxプリセットの適用（現在のNode.jsバージョンがサポートする構文の有効化）
3. Babelプリセットとしてのエクスポート（関数形式）

**関連システム・外部連携**：
- @babel/core: Babelのコアライブラリ（ピア依存）
- babel-jest: Jestのデフォルトコード変換器
- babel-plugin-jest-hoist: jest.mock()のホイスティング処理

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

## 関連画面

本パッケージはCLIおよびプログラムから使用されるため、直接的な関連画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

コード変換（トランスパイル）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 本プリセットはパラメータを受け取らない | - |

### 入力データソース

- Babelによる変換対象のJavaScript/TypeScriptソースコード
- @babel/coreからの呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| plugins | Array | 適用するBabelプラグインの配列（babel-plugin-jest-hoist） |
| presets | Array | 適用するBabelプリセットの配列（babel-preset-current-node-syntax） |

### 出力先

@babel/coreに対してプリセット設定オブジェクトを返却

## 処理フロー

### 処理シーケンス

```
1. @babel/coreからプリセット関数が呼び出される
   └─ module.exports（jestPresetPlugin関数）の実行

2. jestPreset設定オブジェクトを返却
   └─ plugins: ['babel-plugin-jest-hoist']
   └─ presets: ['babel-preset-current-node-syntax']

3. Babelがプリセットの設定に従ってコード変換を実行
   └─ babel-plugin-jest-hoistによるjest.mock()のホイスティング
   └─ babel-preset-current-node-syntaxによる構文サポート
```

### フローチャート

```mermaid
flowchart TD
    A[Babel変換開始] --> B[babel-preset-jest呼び出し]
    B --> C[jestPreset設定オブジェクト生成]
    C --> D[babel-plugin-jest-hoist適用]
    C --> E[babel-preset-current-node-syntax適用]
    D --> F[jest.mock/unmock/deepUnmock呼び出しをホイスト]
    E --> G[現在のNode.js構文サポートを有効化]
    F --> H[変換済みコード出力]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-21-01 | ホイスティング対象関数 | jest.mock, jest.unmock, jest.deepUnmock, jest.enableAutomock, jest.disableAutomockがホイスティング対象 | 常時 |
| BR-21-02 | モックファクトリ制約 | jest.mock()の第2引数（ファクトリ関数）はインライン関数である必要がある | jest.mock()に第2引数を渡す場合 |
| BR-21-03 | スコープ外変数制約 | モックファクトリ内でスコープ外の変数を参照する場合、許可リストに含まれる変数か「mock」プレフィックスを持つ変数のみ使用可能 | モックファクトリ内 |

### 計算ロジック

計算処理は存在しない（コード変換処理）。

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

### 操作別データベース影響一覧

データベース操作は存在しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型エラー | jest.mock()の第2引数がインライン関数でない場合 | 第2引数をインライン関数に変更 |
| ReferenceError | 参照エラー | モックファクトリ内でスコープ外の許可されていない変数を参照した場合 | 変数名を「mock」プレフィックスに変更するか、許可リスト内の変数を使用 |

### リトライ仕様

リトライ処理は存在しない（ビルド時処理）。

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

トランザクション処理は存在しない。

## パフォーマンス要件

ビルド時処理のため、明確なパフォーマンス要件は定義されていない。Babelの変換処理の一部として実行される。

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

特になし。ビルド時処理であり、実行時のセキュリティリスクは存在しない。

## 備考

- babel-preset-jestはbabel-jestを使用する際に自動的に適用される
- 直接Babelの設定ファイルで指定することも可能
- @babel/core 7.11.0以上または8.0.0-beta.1以上が必要

---

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

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

### 推奨読解順序

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

babel-preset-jestはシンプルなプリセット設定オブジェクトを返す。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.js | `packages/babel-preset-jest/index.js` | プリセット設定オブジェクトの構造（plugins, presets） |

**読解のコツ**: Babelプリセットは`{ plugins: [], presets: [] }`形式のオブジェクトを返す関数として定義される。@babel/coreの仕様により関数形式でエクスポートする必要がある。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `packages/babel-preset-jest/index.js` | プリセット関数のエクスポート |

**主要処理フロー**:
1. **8-11行目**: jestPreset設定オブジェクトの定義（pluginsとpresetsを含む）
2. **14行目**: jestPresetPlugin関数の定義（jestPresetを返す）
3. **15行目**: module.exportsによるエクスポート

#### Step 3: 依存プラグインを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-plugin-jest-hoist/src/index.ts` | jest.mock()のホイスティング処理の実装 |

**主要処理フロー**:
- **25-27行目**: JEST_GLOBAL_NAME等の定数定義
- **36-96行目**: ALLOWED_IDENTIFIERS（モックファクトリ内で使用可能な識別子のリスト）
- **118-203行目**: FUNCTIONS.mock - jest.mock()の検証とホイスティング判定
- **304-404行目**: jestHoist関数 - Babelプラグインのメイン実装

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

```
@babel/core
    │
    └─ babel-preset-jest (index.js)
           │
           ├─ babel-plugin-jest-hoist
           │      └─ extractJestObjExprIfHoistable()
           │      └─ FUNCTIONS.mock/unmock/deepUnmock()
           │
           └─ babel-preset-current-node-syntax
```

### データフロー図

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

JavaScript/             babel-preset-jest                  変換済み
TypeScriptコード ───▶   ├─ babel-plugin-jest-hoist ───▶   JavaScript
                       │   (jest.mock()ホイスト)           コード
                       │
                       └─ babel-preset-current-node-syntax
                           (構文サポート)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `packages/babel-preset-jest/index.js` | ソース | プリセットのメインエントリーポイント |
| package.json | `packages/babel-preset-jest/package.json` | 設定 | パッケージ定義と依存関係 |
| README.md | `packages/babel-preset-jest/README.md` | ドキュメント | 使用方法の説明 |
| index.ts | `packages/babel-plugin-jest-hoist/src/index.ts` | ソース | jest.mock()ホイスティングプラグインの実装 |
