# 機能設計書 44-設定ファイル解決（resolveConfig）

## 概要

本ドキュメントは、v3形式の `tailwind.config.js` 設定ファイルを解決・マージする `resolveConfig` 関数の設計を記述する。複数の設定ファイル・プラグイン設定・プリセットを再帰的に収集し、単一のResolvedConfigオブジェクトに統合する。

### 本機能の処理概要

resolveConfigは、複数のConfigFileエントリを受け取り、v3形式の設定ファイルのマージ規則に従ってテーマ値・プラグイン・トップレベル設定を統合する機能である。

**業務上の目的・背景**：Tailwind CSS v3の設定システムでは、`tailwind.config.js`にテーマのカスタマイズ、プラグインの登録、darkMode・prefix等のトップレベル設定を記述する。v4では `@config` ディレクティブを通じてこれらの設定を読み込むため、v3形式の設定ファイルをv4内部のResolvedConfig形式に変換する必要がある。

**機能の利用シーン**：`applyCompatibilityHooks` の `upgradeToFullPluginSupport` 関数内で、compat config、ユーザープラグイン設定、ユーザーconfig設定、ダークモードプラグインを引数として呼び出される。2回呼び出され、1回目は全体設定、2回目はユーザー設定のみの解決を行う。

**主要な処理内容**：
1. 各ConfigFileから設定を再帰的に抽出（extractConfigs）
2. プリセットの再帰的展開
3. プラグインの正規化（PluginFn/PluginWithConfig/PluginWithOptions）
4. contentファイルの収集
5. トップレベル設定のマージ（darkMode, prefix, blocklist, important）
6. テーマのマージ（浅いマージ + extend のディープマージ）
7. テーマ関数の解決（遅延評価）
8. screens設定の正規化（{min: '123px'} -> '123px'）

**関連システム・外部連携**：createThemeFnを通じてDesignSystemのテーマシステムと連携。colorsモジュールからデフォルトカラーパレットを取得。

**権限による制御**：referenceフラグにより、一部の設定がリファレンスモードで処理される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面には直接関連しない。コンパイルパイプライン内部で使用 |

## 機能種別

データ連携 / 計算処理（設定マージ・解決）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| design | DesignSystem | Yes | テーマ解決に使用するデザインシステム | 有効なDesignSystem |
| files | ConfigFile[] | Yes | 設定ファイルエントリの配列 | path, base, config, reference, srcを持つ |

### 入力データソース

- `@config` ディレクティブで指定された設定ファイル（loadModuleでロード済み）
- `@plugin` ディレクティブで指定されたプラグインの設定部分
- `createCompatConfig` で生成されたデフォルト互換設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| resolvedConfig | ResolvedConfig | マージ・解決済み設定オブジェクト |
| replacedThemeKeys | Set<string> | 置き換えられたテーマキーの集合 |

### 出力先

- `upgradeToFullPluginSupport` 内で使用される
- `applyConfigToTheme` に渡される

## 処理フロー

### 処理シーケンス

```
1. ResolutionContextの初期化
   └─ 空のminimal設定でresultを初期化

2. extractConfigs（再帰的設定抽出）
   ├─ プラグインの正規化（PluginFn/PluginWithConfig/PluginWithOptions）
   ├─ プリセットの再帰処理
   ├─ プラグインの設定再帰処理
   ├─ contentファイルの収集
   └─ configの追加

3. トップレベル設定マージ
   ├─ darkMode（最後の設定が勝つ）
   ├─ prefix（最後の設定が勝つ）
   ├─ blocklist（最後の設定が勝つ）
   └─ important（最後の設定が勝つ）

4. mergeTheme（テーマのマージ）
   ├─ 各configのthemeを浅いマージ（最後が勝つ）
   ├─ extendキーの収集
   ├─ extendキーのディープマージ（deepMerge + mergeThemeExtension）
   ├─ テーマ関数の解決（resolveValue）
   └─ screens正規化（{min:'123px'} -> '123px'）
```

### フローチャート

```mermaid
flowchart TD
    A[resolveConfig開始] --> B[ResolutionContext初期化]
    B --> C[各ConfigFileに対してextractConfigs]
    C --> D[プリセット再帰展開]
    D --> E[プラグイン正規化・設定再帰展開]
    E --> F[contentファイル収集]
    F --> G[トップレベル設定マージ]
    G --> H[mergeTheme]
    H --> I[themeの浅いマージ]
    I --> J[extendのディープマージ]
    J --> K[テーマ関数の解決]
    K --> L[screens正規化]
    L --> M[ResolvedConfig + replacedThemeKeys返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | 空プリセット禁止 | `presets: []` は非対応でエラーになる | config.presetsが空配列 |
| BR-44-02 | テーマ浅いマージ | themeのトップレベルキーは後の設定で完全上書きされる | 同一テーマキーが複数configに存在 |
| BR-44-03 | extend深いマージ | theme.extendのキーはディープマージで統合される | extendキーに同名エントリが存在 |
| BR-44-04 | テーマ関数遅延評価 | テーマ値が関数の場合、マージ後にthemeユーティリティで解決される | 関数型のテーマ値 |
| BR-44-05 | screens正規化 | `{min:'768px'}` は `'768px'` に簡略化される | screens設定にminのみのオブジェクト |
| BR-44-06 | プラグイン処理順序 | プリセット → プラグイン設定 → 本体設定の順でマージされる | 全config |

### 計算ロジック

テーママージのロジック:
1. **浅いマージ**: `Object.assign(ctx.theme, theme)` で後勝ち
2. **extend収集**: 各configのextend内のキーを配列に蓄積
3. **ディープマージ**: `deepMerge({}, values, mergeThemeExtension)` で配列はoverride、オブジェクトは再帰的マージ
4. **関数解決**: `resolveValue(value)` でテーマ関数をthemeユーティリティで評価

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | 空のpreset配列 | エラーメッセージを投げる |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- テーマ関数は遅延評価され、実際にアクセスされるまで解決されない
- structuredCloneでminimal設定を複製して初期化

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

- 設定ファイルはJavaScriptコードとして実行されるため、信頼されたファイルのみ使用すべきである

## 備考

- mergeThemeExtensionはカスタマイザー関数で、配列値のマージ時にdeepMergeではなくoverride動作を選択する
- replacedThemeKeysは `applyConfigToTheme` でデフォルトテーマ名前空間のクリアに使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/tailwindcss/src/compat/config/types.ts` | UserConfig/ResolvedConfig/ThemeConfig/DarkModeStrategy型の定義 |
| 1-2 | resolve-config.ts | `packages/tailwindcss/src/compat/config/resolve-config.ts` | ConfigFile/ResolutionContext型の定義（15-31行目） |

**読解のコツ**: types.tsではTypeScriptのinterface mergingが多用されており、UserConfigとResolvedConfigが段階的に拡張されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | resolve-config.ts | `packages/tailwindcss/src/compat/config/resolve-config.ts` | resolveConfig関数（47-100行目） |

**主要処理フロー**:
1. **51-63行目**: ResolutionContextの初期化
2. **65-67行目**: extractConfigsの反復呼び出し
3. **70-86行目**: トップレベル設定のマージ
4. **89行目**: mergeTheme呼び出し

#### Step 3: extractConfigsを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | resolve-config.ts | `packages/tailwindcss/src/compat/config/resolve-config.ts` | extractConfigs関数（135-196行目） |

**主要処理フロー**:
- **142-158行目**: プラグインの正規化（3パターン: withOptions/handler/plain function）
- **161-169行目**: プリセットの再帰的展開
- **172-184行目**: プラグイン設定の再帰的展開
- **187-192行目**: contentファイルの収集
- **195行目**: configの追加

#### Step 4: mergeThemeを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | resolve-config.ts | `packages/tailwindcss/src/compat/config/resolve-config.ts` | mergeTheme関数（198-273行目） |

**主要処理フロー**:
- **200-205行目**: themeFnとcolorsの設定
- **215-235行目**: 浅いマージとextend収集
- **242-251行目**: ディープマージの遅延実行
- **253-255行目**: テーマ関数の解決
- **258-270行目**: screens正規化

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

```
resolveConfig(design, files)
    │
    ├─ extractConfigs(ctx, file)  [再帰的]
    │      ├─ プラグイン正規化
    │      ├─ extractConfigs(ctx, preset)  [プリセット]
    │      ├─ extractConfigs(ctx, plugin.config)  [プラグイン設定]
    │      └─ ctx.configs.push(config)
    │
    ├─ トップレベル設定マージ
    │
    └─ mergeTheme(ctx)
           ├─ createThemeFn()
           ├─ Object.assign(ctx.theme, theme)  [浅いマージ]
           ├─ deepMerge({}, values, mergeThemeExtension)  [extend]
           └─ resolveValue()  [テーマ関数解決]
```

### データフロー図

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

ConfigFile[] ─────▶ extractConfigs() ────▶ ctx.configs[]
                                            ctx.plugins[]
                                            ctx.content.files[]
                         │
                         ▼
                   トップレベルマージ ────▶ result.darkMode
                                            result.prefix
                                            result.blocklist
                                            result.important
                         │
                         ▼
                   mergeTheme() ──────────▶ ctx.theme
                                            replacedThemeKeys
                         │
                         ▼
                   ResolvedConfig ────────▶ upgradeToFullPluginSupport
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| resolve-config.ts | `packages/tailwindcss/src/compat/config/resolve-config.ts` | ソース | 設定ファイルの解決・マージ本体 |
| types.ts | `packages/tailwindcss/src/compat/config/types.ts` | ソース | UserConfig/ResolvedConfig型定義 |
| create-compat-config.ts | `packages/tailwindcss/src/compat/config/create-compat-config.ts` | ソース | v3互換デフォルト設定生成 |
| deep-merge.ts | `packages/tailwindcss/src/compat/config/deep-merge.ts` | ソース | ディープマージユーティリティ |
| plugin-functions.ts | `packages/tailwindcss/src/compat/plugin-functions.ts` | ソース | createThemeFn（テーマ関数解決） |
| plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | ソース | PluginWithConfig/Plugin型定義 |
| colors.ts | `packages/tailwindcss/src/compat/colors.ts` | ソース | デフォルトカラーパレット |
