# 機能設計書 98-Jest統合

## 概要

本ドキュメントは、Next.jsのJest統合機能の設計について記述する。本機能は、Next.jsプロジェクトでJestを使用したテストを実行するためのトランスフォーマー・設定ヘルパーを提供し、SWCベースの高速トランスパイルとNext.js固有のモック設定を自動的に行う。

### 本機能の処理概要

**業務上の目的・背景**：Next.jsプロジェクトでJestを使用する場合、CSS/画像/フォントのモック設定、SWCトランスフォーマーの設定、node_modulesのトランスパイル設定など、多くの手動設定が必要である。`next/jest`はこれらの設定を自動的に行い、開発者がテスト実装に集中できるようにする。

**機能の利用シーン**：
- `jest.config.js` で `next/jest` を使用してJest設定を生成する場合
- Next.jsプロジェクトでユニットテストを実行する場合
- SWCを使用した高速テストトランスパイルが必要な場合

**主要な処理内容**：
1. Next.js設定（next.config.js）の読み込みとJest設定への反映
2. CSS/SASS/SCSSモジュールのモック（Proxy/空オブジェクト）
3. 画像ファイルのモック（fileMock）
4. next/fontのモック（nextFontMock）
5. server-onlyモジュールのモック（empty）
6. SWCベースのJestトランスフォーマー設定
7. transpilePackagesの自動設定（transformIgnorePatterns）
8. 環境変数（.env）の自動読み込み

**関連システム・外部連携**：Jest、SWC（next-swc）、Next.js設定ファイル、.envファイル。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Jest統合は画面を持たないテスト支援機能 |

## 機能種別

設定生成 / テスト支援

## 入力仕様

### 入力パラメータ

#### nextJest（ファクトリ関数）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dir | string | No | Next.jsプロジェクトのディレクトリパス | 有効なパス |

#### 返却関数（createJestConfig）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| customJestConfig | Config.InitialProjectOptions \| function | No | カスタムJest設定またはそれを返す関数 | - |

### 入力データソース

next.config.js、package.json、.envファイル、tsconfig.json/jsconfig.json。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Config.InitialProjectOptions | object | マージ済みJest設定オブジェクト |

### 出力先

Jest実行環境（jest.config.js経由でJestに渡される）。

## 処理フロー

### 処理シーケンス

```
1. nextJest({dir}) の呼び出し
   └─ createJestConfig関数を返却
2. createJestConfig(customConfig) の呼び出し
   └─ 非同期設定生成関数を返却
3. Jest起動時に非同期関数が実行
   a. Next.js設定の読み込み（loadConfig）
   b. package.json解析（ESMプロジェクト判定）
   c. ページディレクトリ検出（findPagesDir）
   d. 環境変数読み込み（loadEnvConfig）
   e. jsconfig/tsconfig解析（loadJsConfig）
   f. SWCバインディングのインストール
   g. カスタム設定の解決（関数の場合はawait）
   h. 設定のマージと返却
```

### フローチャート

```mermaid
flowchart TD
    A[nextJest options] --> B[createJestConfig返却]
    B --> C[Jest起動]
    C --> D{dir指定あり?}
    D -->|Yes| E[loadConfig]
    D -->|No| F[設定スキップ]
    E --> G[findPagesDir]
    G --> H[loadEnvConfig]
    H --> I[loadJsConfig]
    I --> J[installBindings SWC]
    J --> K[カスタム設定マージ]
    F --> K
    K --> L[Jest設定オブジェクト返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | CSSモジュールモック | `.module.(css\|sass\|scss)` ファイルはProxyオブジェクトでモック | 常時 |
| BR-02 | CSS非モジュールモック | `.css/.sass/.scss` ファイルは空スタイルモックでモック | 常時 |
| BR-03 | 画像モック | png/jpg/gif/webp等の画像ファイルはファイルパスモックでモック | 常時 |
| BR-04 | next/fontモック | `next/font/*` と `@next/font/*` はnextFontMockでモック | 常時 |
| BR-05 | server-onlyモック | `server-only` モジュールは空モジュールでモック | 常時 |
| BR-06 | SWCトランスフォーマー | `.js/.jsx/.ts/.tsx/.mjs` ファイルはSWC Jestトランスフォーマーで変換 | 常時 |
| BR-07 | transpilePackages反映 | next.config.jsのtranspilePackagesをtransformIgnorePatternsに反映 | transpilePackages設定時 |
| BR-08 | カスタム設定優先 | ユーザーのカスタム設定はデフォルト設定にマージ（カスタムが優先） | カスタム設定指定時 |
| BR-09 | .next除外 | .nextディレクトリはtestPathIgnorePatternsとwatchPathIgnorePatternsで除外 | 常時 |
| BR-10 | ESMプロジェクト判定 | package.jsonのtype: 'module'でESMプロジェクトと判定 | dir指定時 |

### 計算ロジック

transpilePackages と DEFAULT_TRANSPILED_PACKAGES の結合によるtransformIgnorePatterns生成：
- pnpm の .pnpm ディレクトリ構造も考慮（パッケージ名の `/` を `\\+` に変換）

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | package.json が5階層以内に見つからない | "Can't resolve main package.json file" エラー |
| - | SWCエラー | SWCバインディングのインストール失敗 | installBindings関数のエラーハンドリングに依存 |

### リトライ仕様

package.json検索は最大5階層まで親ディレクトリを辿ってリトライする（loadClosestPackageJson）。

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

該当なし。

## パフォーマンス要件

- SWCベースのトランスパイルにより、Babel比で高速なテスト実行を実現
- `installBindings` で事前にSWCバインディングを読み込み、テスト実行時の遅延を回避

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

- テスト実行環境でのみ使用される機能であり、本番環境には影響しない
- .envファイルの環境変数がテスト環境に読み込まれる（dev=falseで実行）

## 備考

- `lockfilePatchPromise.cur` の待機処理があり、pnpmのロックファイルパッチが完了するまで待つ
- next/fontのモックは `nextFontMock.ts` で実装され、フォント関連のCSSインジェクションをスキップする
- customJestConfigは関数としても渡せるため、非同期の設定生成にも対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | jest.ts | `packages/next/src/build/jest/jest.ts` | JestTransformerConfig型（110-119行目）の構造を理解する |

**読解のコツ**: nextJestはカリー化パターン（ファクトリ関数が設定生成関数を返し、それがさらに非同期関数を返す）を使用している。三重のネストに注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jest.ts | `packages/next/src/build/jest/jest.ts` | nextJest関数（61行目〜）がエントリーポイント |

**主要処理フロー**:
1. **61行目**: nextJestファクトリ関数の定義
2. **63-67行目**: createJestConfig（カスタム設定受け取り関数）の返却
3. **70行目**: Jest起動時に呼ばれる非同期関数の定義
4. **78-92行目**: Next.js設定の読み込み（dir指定時のみ）
5. **99-100行目**: SWCバインディングの事前インストール
6. **106-108行目**: transpilePackagesの結合
7. **120-195行目**: Jest設定オブジェクトの構築

#### Step 3: モックファイルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | object-proxy.ts | `packages/next/src/build/jest/object-proxy.ts` | CSSモジュール用Proxyモック |
| 3-2 | styleMock.ts | `packages/next/src/build/jest/__mocks__/styleMock.ts` | CSS非モジュール用空モック |
| 3-3 | fileMock.ts | `packages/next/src/build/jest/__mocks__/fileMock.ts` | 画像ファイル用モック |
| 3-4 | nextFontMock.ts | `packages/next/src/build/jest/__mocks__/nextFontMock.ts` | next/font用モック |
| 3-5 | empty.ts | `packages/next/src/build/jest/__mocks__/empty.ts` | server-only用空モック |

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

```
nextJest (jest.ts:61)
    └─ createJestConfig (jest.ts:63)
           └─ async () => Config (jest.ts:70)
                  │
                  ├─ loadConfig (server/config.ts)
                  ├─ loadClosestPackageJson (jest.ts:23)
                  ├─ findPagesDir (lib/find-pages-dir.ts)
                  ├─ loadEnvConfig (@next/env)
                  ├─ loadJsConfig (build/load-jsconfig.ts)
                  ├─ installBindings (build/swc/install-bindings.ts)
                  │
                  └─ Jest Config マージ
                         ├─ moduleNameMapper (CSS/画像/フォントモック)
                         ├─ transform (SWC Jestトランスフォーマー)
                         ├─ transformIgnorePatterns (transpilePackages)
                         └─ testPathIgnorePatterns (.next除外)
```

### データフロー図

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

next.config.js ─────────▶ loadConfig ──────────────▶ nextConfig
package.json ───────────▶ loadClosestPackageJson ──▶ isEsmProject
.env ───────────────────▶ loadEnvConfig ───────────▶ 環境変数設定
tsconfig.json ──────────▶ loadJsConfig ────────────▶ jsConfig

customJestConfig ───────▶ マージ処理 ──────────────▶ 最終Jest設定
                               │
                               └─ moduleNameMapper
                                  transform
                                  transformIgnorePatterns
                                  testPathIgnorePatterns
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| jest.ts | `packages/next/src/build/jest/jest.ts` | ソース | Jest統合のメインロジック |
| object-proxy.ts | `packages/next/src/build/jest/object-proxy.ts` | ソース | CSSモジュール用Proxyモック |
| styleMock.ts | `packages/next/src/build/jest/__mocks__/styleMock.ts` | モック | CSS用空モック |
| fileMock.ts | `packages/next/src/build/jest/__mocks__/fileMock.ts` | モック | 画像ファイル用モック |
| nextFontMock.ts | `packages/next/src/build/jest/__mocks__/nextFontMock.ts` | モック | next/font用モック |
| empty.ts | `packages/next/src/build/jest/__mocks__/empty.ts` | モック | server-only用空モック |
| jest-transformer.ts | `packages/next/src/build/swc/jest-transformer.ts` | ソース | SWC Jestトランスフォーマー |
