# 機能設計書 19-babel-jest

## 概要

本ドキュメントは、Jestテスティングフレームワークにおける`babel-jest`パッケージの機能設計を記述する。このパッケージは、Babelを使用してJavaScript/TypeScriptコードをトランスパイルする`@jest/transform`用のトランスフォーマープラグインである。

### 本機能の処理概要

**業務上の目的・背景**：Jestでテストを実行する際、ESModules、JSX、TypeScript、最新のECMAScript構文などを使用したコードは、Node.jsが直接実行できる形式に変換する必要がある。`babel-jest`は、Babelのエコシステムを活用してこの変換を行い、豊富なBabelプラグイン/プリセットを利用可能にする。

**機能の利用シーン**：
- ES6+構文のES5への変換
- JSX/TSXの変換
- TypeScriptの変換（@babel/preset-typescript使用時）
- カスタムBabel設定の適用
- コードカバレッジのためのinstrumentation

**主要な処理内容**：
1. `createTransformer()` - トランスフォーマーファクトリ関数
2. `process()` - 同期コード変換
3. `processAsync()` - 非同期コード変換
4. `getCacheKey()` / `getCacheKeyAsync()` - キャッシュキー生成
5. `babel-preset-jest`の自動適用
6. `babel-plugin-istanbul`によるinstrumentation
7. ソースマップ生成

**関連システム・外部連携**：`@babel/core`、`babel-preset-jest`、`babel-plugin-istanbul`と連携する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | Code Transformationページ | 参照画面 | babel-jest設定の説明 |
| 12 | Configurationページ | 参照画面 | transform設定でのbabel-jest使用 |

## 機能種別

コード変換 / Babelトランスフォーマー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sourceText | string | Yes | 変換対象ソースコード | 文字列 |
| sourcePath | string | Yes | ソースファイルパス | 有効なファイルパス |
| transformOptions | JestTransformOptions | Yes | Jest変換オプション | オブジェクト |
| transformerConfig | TransformerConfig | No | babel-jest設定 | BabelTransformOptions拡張 |

### 入力データソース

`@jest/transform`からの呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | string | 変換後のコード |
| map | RawSourceMap \| null | ソースマップ |

### 出力先

`@jest/transform`

## 処理フロー

### 処理シーケンス

```
1. createTransformer()呼び出し
2. transformerConfig解析（excludeJestPreset等）
3. Babel設定のマージ
   - caller情報設定
   - jest-presetの追加（excludeJestPreset=true以外）
   - sourceMaps: 'both'設定
4. process()/processAsync()呼び出し
5. Babel設定ロード（loadPartialConfig）
6. instrument判定とbabel-plugin-istanbul追加
7. babelTransform()/babelTransformAsync()実行
8. TransformResult返却
```

### フローチャート

```mermaid
flowchart TD
    A[createTransformer呼び出し] --> B[transformerConfig解析]
    B --> C[デフォルトオプション設定]
    C --> D[Transformer返却]

    E[process呼び出し] --> F[Babel設定ロード]
    F --> G{Babel設定存在?}
    G -->|No| H[エラースロー]
    G -->|Yes| I{instrument必要?}
    I -->|Yes| J[istanbul plugin追加]
    I -->|No| K[babelTransform実行]
    J --> K
    K --> L{変換成功?}
    L -->|Yes| M[{code, map}返却]
    L -->|No| N[{code: sourceText}返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | jest-preset自動追加 | babel-preset-jestを自動でpresetsに追加 | excludeJestPreset!=true |
| BR-02 | caller設定 | name='babel-jest'でBabelにJestコンテキストを通知 | 常時 |
| BR-03 | instrumentation | transformOptions.instrument=trueでIstanbul適用 | カバレッジ計測時 |
| BR-04 | 設定ファイル検出 | babel.config.js等の設定ファイルを自動検出 | 常時 |

### 計算ロジック

キャッシュキー: SHA1ハッシュ（THIS_FILE + babelOptions + sourceText + sourcePath + configString + configPath + instrument + NODE_ENV + BABEL_ENV + process.version）

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | Error | Babelがファイルを無視 | transformIgnorePatternsに追加 |
| N/A | SyntaxError | 構文エラー | ソースコード修正 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

Babel設定はキャッシュされ、同一設定での再パースを回避。

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

特になし

## 備考

- canInstrument: trueでinstrumentation機能を宣言
- compact: falseで可読性の高い出力
- sourceMaps: 'both'でインラインとファイル両方のソースマップ生成

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-jest/src/index.ts` | createTransformerファクトリ |

**主要処理フロー**:
- **29-32行目**: TransformerConfig型定義（BabelTransformOptions + excludeJestPreset）
- **33-35行目**: THIS_FILE, jestPresetPath, babelIstanbulPlugin定数
- **37-51行目**: assertLoadedBabelConfig - 設定検証
- **53-77行目**: addIstanbulInstrumentation - Istanbul plugin追加
- **159-285行目**: createTransformer - メインファクトリ関数

#### Step 2: トランスフォーマー設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-jest/src/index.ts` | オプション構築 |

**主要処理フロー**:
- **163行目**: excludeJestPresetの分離
- **165-182行目**: デフォルトオプション設定
  - caller.name = 'babel-jest'
  - compact = false
  - presets = [...inputOptions.presets, jestPresetPath]（excludeJestPreset=falseの場合）
  - sourceMaps = 'both'
- **184-211行目**: mergeBabelTransformOptions - Jestオプションとのマージ

#### Step 3: 変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-jest/src/index.ts` | process/processAsync |

**主要処理フロー**:
- **243-261行目**: process - 同期変換
  - loadBabelOptions呼び出し
  - babelTransform実行
- **262-283行目**: processAsync - 非同期変換
  - loadBabelOptionsAsync呼び出し
  - babelTransformAsync実行

#### Step 4: キャッシュキー生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/babel-jest/src/index.ts` | getCacheKey |

**主要処理フロー**:
- **79-111行目**: getCacheKeyFromConfig - SHA1ハッシュ生成
  - THIS_FILE（babel-jestのコード自体）
  - babelOptions.options
  - sourceText
  - relative sourcePath
  - configString
  - config/babelrc paths
  - instrument flag
  - NODE_ENV, BABEL_ENV
  - process.version

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

```
createTransformer (index.ts:159)
    │
    └─ Transformer返却
           │
           ├─ process (index.ts:243)
           │      │
           │      ├─ loadBabelOptions (index.ts:137)
           │      │      │
           │      │      ├─ loadBabelConfig (index.ts:113)
           │      │      │      └─ loadPartialConfigSync (@babel/core)
           │      │      │
           │      │      └─ addIstanbulInstrumentation (index.ts:53)
           │      │
           │      └─ babelTransform (@babel/core)
           │
           ├─ processAsync (index.ts:262)
           │      │
           │      ├─ loadBabelOptionsAsync (index.ts:148)
           │      │      │
           │      │      ├─ loadBabelConfigAsync (index.ts:125)
           │      │      │      └─ loadPartialConfigAsync (@babel/core)
           │      │      │
           │      │      └─ addIstanbulInstrumentation
           │      │
           │      └─ babelTransformAsync (@babel/core)
           │
           ├─ getCacheKey (index.ts:215)
           │      │
           │      ├─ loadBabelConfig
           │      │
           │      └─ getCacheKeyFromConfig (index.ts:79)
           │
           └─ getCacheKeyAsync (index.ts:229)
                  │
                  ├─ loadBabelConfigAsync
                  │
                  └─ getCacheKeyFromConfig

transformerFactory.createTransformer (index.ts:287-291)
    │
    └─ createTransformer
```

### データフロー図

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

sourceText ─────────────▶ process() ──────────────────▶ {code, map}
    │                         │
    │                         ├── Babel設定ロード
    │                         │
    │                         ├── Istanbul追加（instrument=true時）
    │                         │
    │                         └── babelTransform

transformerConfig ──────▶ createTransformer() ─────────▶ Transformer
    │                         │
    │                         ├── excludeJestPreset分離
    │                         │
    │                         ├── デフォルトオプション設定
    │                         │
    │                         └── jest-preset追加
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-jest/src/index.ts` | ソース | メイン実装 |
| babel.ts | `packages/babel-jest/src/babel.ts` | ソース | @babel/coreラッパー |
