# 機能設計書 18-@jest/transform

## 概要

本ドキュメントは、Jestテスティングフレームワークにおける`@jest/transform`パッケージの機能設計を記述する。このパッケージは、テスト実行前にソースコードを変換（トランスパイル）する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：モダンなJavaScript/TypeScript開発では、ESModules、TypeScript、JSXなど、Node.jsが直接実行できない構文が使用される。`@jest/transform`は、これらのソースコードをテスト実行可能な形式に変換することで、開発者が最新の言語機能を活用しながらテストを実行できる環境を提供する。

**機能の利用シーン**：
- TypeScriptコードのJavaScriptへの変換
- JSX/TSXの変換
- ESModulesのCommonJSへの変換
- カスタムファイル形式（.vue、.svelte等）の変換
- コードカバレッジ計測のためのinstrumentation

**主要な処理内容**：
1. `ScriptTransformer` - 変換処理のメインクラス
2. `transform()` / `transformAsync()` - ソースコード変換
3. `createScriptTransformer()` - トランスフォーマーインスタンス生成
4. `createTranspilingRequire()` - 動的require with変換
5. `shouldInstrument()` - instrumentation判定
6. キャッシュ機能 - 変換結果のディスクキャッシュ
7. ソースマップサポート

**関連システム・外部連携**：`babel-jest`、`ts-jest`などのトランスフォーマー実装、`jest-haste-map`（キャッシュディレクトリ）、`babel-plugin-istanbul`（カバレッジ）と連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | Code Transformationページ | 参照画面 | トランスフォーマー設定の説明 |
| 12 | Configurationページ | 参照画面 | transform設定項目の説明 |

## 機能種別

コード変換 / トランスパイル / キャッシュ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | string | Yes | 変換対象ファイルパス | 有効なファイルパス |
| options | Options | Yes | 変換オプション | オブジェクト |
| fileSource | string | No | ファイル内容（指定時はファイル読み込みをスキップ） | 文字列 |
| config | ProjectConfig | Yes | プロジェクト設定 | Config.ProjectConfig |

### 入力データソース

ファイルシステム、Jest設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | string | 変換後のコード |
| originalCode | string | 変換前のコード |
| sourceMapPath | string \| null | ソースマップファイルパス |

### 出力先

テストランタイム、キャッシュディレクトリ

## 処理フロー

### 処理シーケンス

```
1. transform()呼び出し
2. ファイル内容の取得（fileSourceまたはファイル読み込み）
3. shebang除去
4. キャッシュキー計算
5. キャッシュ確認
6. 変換対象判定（transformIgnorePatterns）
7. トランスフォーマー取得と実行
8. instrumentation判定と適用（カバレッジ）
9. ソースマップ処理
10. キャッシュ保存
11. TransformResult返却
```

### フローチャート

```mermaid
flowchart TD
    A[transform呼び出し] --> B[ファイル内容取得]
    B --> C[shebang除去]
    C --> D[キャッシュキー計算]
    D --> E{キャッシュ存在?}
    E -->|Yes| F[キャッシュから返却]
    E -->|No| G{変換対象?}
    G -->|No| H[コードそのまま]
    G -->|Yes| I[トランスフォーマー実行]
    I --> J{instrumentation必要?}
    J -->|Yes| K[Istanbul適用]
    J -->|No| L[ソースマップ処理]
    K --> L
    H --> L
    L --> M[キャッシュ保存]
    M --> N[TransformResult返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パターンマッチング | transformで指定された正規表現にマッチするファイルを変換 | 常時 |
| BR-02 | 無視パターン | transformIgnorePatternsにマッチするファイルは変換しない | 常時 |
| BR-03 | キャッシュ有効期限 | ファイルmtimeとキャッシュキーで判定 | cache=true時 |
| BR-04 | instrumentation | coverageProvider='babel'かつshouldInstrument=trueの場合 | カバレッジ計測時 |

### 計算ロジック

キャッシュキー: SHA1ハッシュ（ファイル内容 + 設定 + transformerCacheKey + instrument）

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

該当なし（ファイルシステムキャッシュ使用）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | Error | トランスフォーマーが無効な戻り値 | 正しいTransformedSourceを返す |
| N/A | SyntaxError | 変換中の構文エラー | ソースコード修正 |
| N/A | Error | トランスフォーマー未ロード | loadTransformers()を先に呼び出す |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- キャッシュによる変換の省略
- ファイル書き込みはwrite-file-atomicで原子性確保
- SHA1チェックサムでキャッシュ破損検出

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

特になし

## 備考

- piratesライブラリでrequireフックを実装
- 非同期トランスフォーマーはprocessAsyncメソッドで実装

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/jest-transform/src/index.ts` | エクスポート構造 |

**主要処理フロー**:
- **8-12行目**: createScriptTransformer, createTranspilingRequireのエクスポート
- **13行目**: shouldInstrumentのエクスポート
- **14-26行目**: 型定義のエクスポート

#### Step 2: ScriptTransformerクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ScriptTransformer.ts | `packages/jest-transform/src/ScriptTransformer.ts` | メイン実装 |

**主要処理フロー**:
- **85-112行目**: ScriptTransformerコンストラクタ - projectCache設定
- **114-136行目**: _buildCacheKeyFromFileInfo - キャッシュキー生成
- **276-308行目**: loadTransformers - トランスフォーマーの非同期ロード
- **310-339行目**: _getTransformer - ファイルパターンに応じたトランスフォーマー取得
- **341-384行目**: _instrumentFile - Istanbul適用
- **481-535行目**: transformSource - 同期変換
- **537-600行目**: transformSourceAsync - 非同期変換
- **722-749行目**: transform - メイン変換メソッド
- **694-720行目**: transformAsync - 非同期メイン変換
- **840-845行目**: shouldTransform - 変換対象判定

#### Step 3: キャッシュ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ScriptTransformer.ts | `packages/jest-transform/src/ScriptTransformer.ts` | キャッシュ関連 |

**主要処理フロー**:
- **897-919行目**: writeCodeCacheFile - チェックサム付きキャッシュ書き込み
- **908-919行目**: readCodeCacheFile - チェックサム検証付き読み込み
- **927-942行目**: writeCacheFile - 原子的ファイル書き込み

**読解のコツ**: キャッシュファイルはチェックサム(32文字) + 改行 + コードの形式。

#### Step 4: トランスフォーマーインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | types.ts | `packages/jest-transform/src/types.ts` | Transformer型定義 |

**主要処理フロー**:
- Transformer: process, processAsync, getCacheKey, getCacheKeyAsync, canInstrument

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

```
createScriptTransformer (ScriptTransformer.ts:1031)
    │
    ├─ new ScriptTransformer(config, cacheFS)
    │
    └─ transformer.loadTransformers()
           │
           └─ requireOrImportModule (jest-util)

ScriptTransformer.transform() (ScriptTransformer.ts:722)
    │
    ├─ shouldInstrument()
    │
    └─ _transformAndBuildScript() (ScriptTransformer.ts:648)
           │
           ├─ fs.readFileSync (or cacheFS.get)
           │
           ├─ stripShebang()
           │
           └─ transformSource() (ScriptTransformer.ts:481)
                  │
                  ├─ _getFileCachePath()
                  │      └─ _getCacheKey()
                  │
                  ├─ readCodeCacheFile() - キャッシュ確認
                  │
                  ├─ _getTransformer()
                  │
                  ├─ transformer.process()
                  │
                  └─ _buildTransformResult()
                         │
                         ├─ _instrumentFile() (if needed)
                         │      └─ babelTransform + istanbul
                         │
                         └─ writeCodeCacheFile()
```

### データフロー図

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

filename ──────────────▶ transform() ─────────────────▶ TransformResult
    │                         │                              │
    │                         ├── ファイル読み込み          ├── code
    │                         │                              │
    │                         ├── shebang除去               ├── originalCode
    │                         │                              │
    │                         ├── キャッシュ確認            └── sourceMapPath
    │                         │
    │                         ├── トランスフォーマー実行
    │                         │
    │                         ├── instrumentation
    │                         │
    │                         └── キャッシュ保存

config.transform ──────▶ loadTransformers() ─────────▶ トランスフォーマーMap
                              │
                              └── requireOrImportModule
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/jest-transform/src/index.ts` | ソース | エクスポート定義 |
| ScriptTransformer.ts | `packages/jest-transform/src/ScriptTransformer.ts` | ソース | メイン実装 |
| shouldInstrument.ts | `packages/jest-transform/src/shouldInstrument.ts` | ソース | instrumentation判定 |
| types.ts | `packages/jest-transform/src/types.ts` | ソース | 型定義 |
| enhanceUnexpectedTokenMessage.ts | `packages/jest-transform/src/enhanceUnexpectedTokenMessage.ts` | ソース | エラーメッセージ強化 |
| runtimeErrorsAndWarnings.ts | `packages/jest-transform/src/runtimeErrorsAndWarnings.ts` | ソース | エラー/警告メッセージ |
