# 機能設計書 5-jest-config

## 概要

本ドキュメントは、Jestテスティングフレームワークの設定読み込みと正規化を担当する「jest-config」の機能設計を記述したものである。

### 本機能の処理概要

jest-configパッケージは、Jestの設定ファイル（jest.config.js、jest.config.ts、package.json等）を読み込み、検証し、正規化するモジュールである。異なる形式の設定ファイルを統一的なConfigオブジェクトに変換し、デフォルト値の適用、パスの解決、プリセットのマージなどを行う。

**業務上の目的・背景**：Jestは多くの設定オプションを持ち、複数のプロジェクトを同時にテストするモノレポ環境もサポートする必要がある。jest-configは、様々な形式の設定ファイルを柔軟に受け入れながら、内部で一貫した形式に正規化することで、他のJestパッケージが設定の詳細を意識せずに動作できるようにする。

**機能の利用シーン**：
- `jest.config.js`からJavaScript設定を読み込む
- `jest.config.ts`からTypeScript設定を読み込む
- `package.json`のjestフィールドから設定を読み込む
- `--config`オプションで指定された設定ファイルを読み込む
- プリセット（jest-preset.js）のマージ
- 複数プロジェクト（projects）の設定管理

**主要な処理内容**：
1. 設定ファイルの探索と読み込み
2. JSON文字列または設定オブジェクトの解析
3. プリセットの解決とマージ
4. デフォルト値の適用
5. パスの正規化（rootDir相対パスの解決）
6. GlobalConfigとProjectConfigへの分離
7. 非推奨オプションの警告

**関連システム・外部連携**：
- jest-resolve: プリセットやリゾルバーの解決
- jest-validate: 設定値の検証
- cosmiconfig: 設定ファイルの探索（内部実装）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | N/A | N/A | 本機能は設定読み込みであり、画面は存在しない |

## 機能種別

設定管理 / バリデーション / パス解決

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| configPath | string | No | 設定ファイルパス | 存在するファイル |
| packageRoot | string | No | プロジェクトルート | 存在するディレクトリ |
| argv | Config.Argv | No | CLIオプション | jest-cliで検証済み |

### 入力データソース

- jest.config.js / jest.config.ts / jest.config.mjs / jest.config.cjs
- package.jsonのjestフィールド
- CLIの--configオプション
- JSON文字列（CLIから直接渡された場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| globalConfig | Config.GlobalConfig | グローバル設定（全プロジェクト共通） |
| projectConfig | Config.ProjectConfig | プロジェクト固有設定 |
| hasDeprecationWarnings | boolean | 非推奨オプション使用フラグ |
| configPath | string | null | 読み込んだ設定ファイルパス |

### 出力先

@jest/coreおよびその他のJestパッケージ

## 処理フロー

### 処理シーケンス

```
1. 設定ファイル探索
   └─ resolveConfigPath で設定ファイルを特定
2. 設定読み込み
   └─ readConfigFileAndSetRootDir で設定を読み込み
3. 設定検証
   └─ jest-validate で設定値を検証
4. プリセット解決
   └─ setupPreset でプリセットをマージ
5. デフォルト適用
   └─ Defaults.ts のデフォルト値を適用
6. 正規化
   └─ normalize で全ての設定を正規化
7. 設定分離
   └─ groupOptions で GlobalConfig と ProjectConfig に分離
```

### フローチャート

```mermaid
flowchart TD
    A[設定読み込み開始] --> B{設定パス指定?}
    B -->|Yes| C[指定パスから読み込み]
    B -->|No| D[設定ファイル探索]
    D --> E{jest.config.* 存在?}
    E -->|Yes| C
    E -->|No| F{package.json jest存在?}
    F -->|Yes| G[package.json から読み込み]
    F -->|No| H[デフォルト設定使用]
    C --> I{プリセット指定?}
    G --> I
    H --> I
    I -->|Yes| J[プリセット解決・マージ]
    I -->|No| K[設定検証]
    J --> K
    K --> L{検証OK?}
    L -->|No| M[エラー終了]
    L -->|Yes| N[正規化処理]
    N --> O[GlobalConfig/ProjectConfig分離]
    O --> P[設定オブジェクト返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 設定ファイル優先順位 | .js > .ts > .mjs > .cjs > .json > package.json | 複数存在時 |
| BR-002 | プリセット継承 | ユーザー設定はプリセット設定を上書きする | preset指定時 |
| BR-003 | rootDir必須 | rootDirが指定されていない場合はエラー | 常時 |
| BR-004 | パス正規化 | <rootDir>プレースホルダは実際のパスに置換される | パス設定時 |
| BR-005 | 重複設定禁止 | testMatchとtestRegexは同時指定不可 | 常時 |

### 計算ロジック

maxWorkersの算出（getMaxWorkers.ts）:
```javascript
// 未指定時
const cpus = os.cpus().length;
const maxWorkers = Math.max(cpus - 1, 1);

// 割合指定時（例: "50%"）
const percentage = parseFloat(value) / 100;
const maxWorkers = Math.ceil(cpus * percentage);
```

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

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

データベース操作は本パッケージでは行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| VALIDATION_ERROR | 設定エラー | 無効な設定値 | エラーメッセージに従い設定を修正 |
| MULTIPLE_CONFIGS | 設定重複 | 複数の設定ファイル検出 | 1つに統一 |
| PRESET_NOT_FOUND | プリセット不存在 | プリセットが見つからない | npm install |
| ROOTDIR_NOT_FOUND | rootDir不存在 | rootDirディレクトリが存在しない | パスを確認 |

### リトライ仕様

設定読み込みにリトライ処理はない

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

トランザクション処理は本パッケージには存在しない

## パフォーマンス要件

- 設定ファイルの読み込みは1回のみ実行
- TypeScript設定ファイルはts-nodeで動的コンパイル

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

- 設定ファイルはJavaScriptとして実行される
- 信頼できるソースの設定ファイルのみを使用すべき

## 備考

- defineConfig ヘルパー関数で型補完を有効化可能
- mergeConfig で複数設定のマージが可能

---

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

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

### 推奨読解順序

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

設定オブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Config.ts | `packages/@jest/types/src/Config.ts` | GlobalConfigとProjectConfigの定義 |
| 1-2 | Defaults.ts | `packages/jest-config/src/Defaults.ts` | デフォルト設定値 |

**読解のコツ**: GlobalConfigは複数プロジェクトで共有される設定、ProjectConfigはプロジェクト固有の設定。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/jest-config/src/index.ts` | 公開APIと主要関数 |

**主要処理フロー**:
1. **50-60行目**: defineConfig関数（型ヘルパー）
2. **66-78行目**: mergeConfig関数（設定マージ）
3. **80-121行目**: readConfig関数（単一設定読み込み）
4. **390-481行目**: readConfigs関数（複数プロジェクト設定読み込み）

#### Step 3: 設定ファイル解決の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | resolveConfigPath.ts | `packages/jest-config/src/resolveConfigPath.ts` | 設定ファイル探索ロジック |

**主要処理フロー**:
- 設定ファイルの優先順位に従った探索
- 複数設定ファイル検出時の警告

#### Step 4: 正規化処理の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | normalize.ts | `packages/jest-config/src/normalize.ts` | 設定の正規化処理 |

**主要処理フロー**:
- **122-209行目**: setupPreset（プリセット解決）
- **211-250行目**: setupBabelJest（Babelトランスフォーム設定）
- **482-1182行目**: normalize関数（メイン正規化処理）

#### Step 5: 設定分離の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | index.ts | `packages/jest-config/src/index.ts` | groupOptions関数 |

**主要処理フロー**:
- **123-259行目**: groupOptions関数でGlobalConfigとProjectConfigに分離

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

```
jest-config/index.ts
    │
    ├─ readConfig / readConfigs (エントリポイント)
    │      │
    │      ├─ readInitialOptions
    │      │      │
    │      │      ├─ resolveConfigPath (設定ファイル探索)
    │      │      │
    │      │      └─ readConfigFileAndSetRootDir
    │      │
    │      ├─ normalize (設定正規化)
    │      │      │
    │      │      ├─ setupPreset (プリセット解決)
    │      │      │
    │      │      ├─ jest-validate (設定検証)
    │      │      │
    │      │      └─ 各設定項目の正規化
    │      │
    │      └─ groupOptions (GlobalConfig/ProjectConfig分離)
    │
    └─ defineConfig / mergeConfig (ヘルパー関数)
```

### データフロー図

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

jest.config.* ───────────▶ resolveConfigPath ─────▶ 設定ファイルパス
        │                        │
        ▼                        ▼
設定ファイル ────────────▶ readConfigFileAndSetRootDir ─▶ InitialOptions
        │                        │
        ▼                        ▼
preset設定 ──────────────▶ setupPreset ─────────────▶ マージ済みOptions
        │                        │
        ▼                        ▼
CLIオプション ───────────▶ normalize ───────────────▶ NormalizedOptions
        │                        │
        ▼                        ▼
                          groupOptions ─────────────▶ GlobalConfig
                                │                     ProjectConfig
                                ▼
                          @jest/core へ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/jest-config/src/index.ts` | ソース | エントリポイント |
| normalize.ts | `packages/jest-config/src/normalize.ts` | ソース | 設定正規化 |
| Defaults.ts | `packages/jest-config/src/Defaults.ts` | ソース | デフォルト値定義 |
| Deprecated.ts | `packages/jest-config/src/Deprecated.ts` | ソース | 非推奨オプション |
| ValidConfig.ts | `packages/jest-config/src/ValidConfig.ts` | ソース | 有効な設定キー定義 |
| resolveConfigPath.ts | `packages/jest-config/src/resolveConfigPath.ts` | ソース | 設定ファイル探索 |
| readConfigFileAndSetRootDir.ts | `packages/jest-config/src/readConfigFileAndSetRootDir.ts` | ソース | 設定ファイル読み込み |
| getMaxWorkers.ts | `packages/jest-config/src/getMaxWorkers.ts` | ソース | maxWorkers算出 |
