# 機能設計書 59-v3→v4アップグレードツール（@tailwindcss/upgrade）

## 概要

本ドキュメントは、Tailwind CSS v3プロジェクトをv4に自動マイグレーションするツール `@tailwindcss/upgrade` の機能設計を記述する。CSS、テンプレート、設定ファイル、PostCSS設定の変換を行う。

### 本機能の処理概要

**業務上の目的・背景**：Tailwind CSS v3からv4への移行には、CSSディレクティブの変更、設定ファイル形式の変更、クラス名の更新等、多数の変換作業が必要となる。`@tailwindcss/upgrade` は、これらの変換作業を自動化し、手動での移行作業に伴うリスクと工数を大幅に削減する。

**機能の利用シーン**：`npx @tailwindcss/upgrade` コマンドを実行し、プロジェクト全体のTailwind CSS v3→v4マイグレーションを自動実行する。Git作業ディレクトリがクリーンであることが前提（--forceで回避可能）。

**主要な処理内容**：
1. バージョン検証：インストール済みTailwind CSSバージョンとpackage.jsonの一致確認
2. CSSスタイルシートの検出と読み込み
3. スタイルシート解析（analyzeStylesheets）
4. 設定ファイルのリンク（linkConfigsToStylesheets）
5. JavaScriptコンフィグのマイグレーション（migrateJsConfig）
6. CSSスタイルシートのマイグレーション（migrateStylesheet）
7. スタイルシートの分割（splitStylesheets）
8. テンプレートファイルのマイグレーション（migrateTemplate）
9. PostCSS設定のマイグレーション（migratePostCSSConfig）
10. 依存パッケージの更新
11. 出力フォーマットとファイル書き込み

**関連システム・外部連携**：tailwindcss コアライブラリ、@tailwindcss/oxide（Scanner）、PostCSS、globby（ファイル検索）、picocolors（出力色付け）、パッケージマネージャ（npm/yarn/pnpm/bun）

**権限による制御**：--force フラグによりGitクリーンチェックをバイパス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIツールのため関連画面なし |

## 機能種別

コード変換 / マイグレーション / バッチ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --config / -c | string | No | 設定ファイルパス | - |
| --help / -h | boolean | No | ヘルプ表示 | - |
| --force / -f | boolean | No | Gitクリーンチェックをスキップ | - |
| --version / -v | boolean | No | バージョン表示 | - |
| _ (positional) | string[] | No | マイグレーション対象CSSファイル。未指定時は全CSSファイルを検索 | - |

### 入力データソース

- ファイルシステム上のCSSファイル（globbyで検索またはコマンドライン引数で指定）
- tailwind.config.js/ts設定ファイル
- postcss.config.js設定ファイル
- テンプレートファイル（Scanner経由で検出）
- package.json（バージョン情報・依存関係）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| マイグレーション済みCSSファイル | ファイル | v4形式に変換されたCSSファイル |
| マイグレーション済みテンプレート | ファイル | v4クラス名に更新されたテンプレートファイル |
| 更新済みpackage.json | ファイル | 最新バージョンの依存関係 |
| 更新済みPostCSS設定 | ファイル | v4対応のPostCSS設定 |

### 出力先

ファイルシステム（既存ファイルの上書き）

## 処理フロー

### 処理シーケンス

```
1. Gitクリーンチェック
   └─ isRepoDirty() で作業ディレクトリの状態確認（--forceでスキップ）
2. バージョン検証
   └─ installedTailwindVersion === expectedTailwindVersion の確認
3. CSSファイル検出
   └─ 引数指定 or globby(['**/*.css']) で検索
4. スタイルシート読み込み・解析
   └─ Stylesheet.load() → analyzeStylesheets()
5. 設定ファイルリンク（v3→v4時）
   └─ linkConfigsToStylesheets(): CSSとconfigの関連付け
6. JSコンフィグマイグレーション
   └─ prepareConfig() → migrateJsConfig(): JS設定のv4変換
7. CSSスタイルシートマイグレーション
   └─ migrateStylesheet(): CSSディレクティブの変換
8. スタイルシート分割（v3→v4時）
   └─ splitStylesheets(): 必要に応じてファイル分割
9. 出力フォーマット
   └─ sortBuckets() + formatNodes(): CSSの整形
10. ファイル書き込み
    └─ fs.writeFile() で各ファイルを出力
11. 依存パッケージ更新
    └─ パッケージマネージャ経由で@latestに更新
12. テンプレートマイグレーション
    └─ Scanner → migrateTemplate(): テンプレートのクラス名変換
13. PostCSS設定マイグレーション（v3→v4時）
    └─ migratePostCSSConfig()
14. クリーンアップ
    └─ 完全マイグレーション済みconfigファイルの削除
```

### フローチャート

```mermaid
flowchart TD
    A[npx @tailwindcss/upgrade] --> B{Git dirty?}
    B -->|Yes & !force| C[エラー終了]
    B -->|No or force| D{バージョン一致?}
    D -->|No| E[エラー: npm install必要]
    D -->|Yes| F[CSSファイル検出]
    F --> G[Stylesheet.load & analyze]
    G --> H{v3→v4?}
    H -->|Yes| I[linkConfigsToStylesheets]
    H -->|No| J[skip]
    I --> K[migrateJsConfig]
    J --> K
    K --> L[migrateStylesheet]
    L --> M{v3→v4?}
    M -->|Yes| N[splitStylesheets]
    M -->|No| O[formatNodes]
    N --> O
    O --> P[ファイル書き込み]
    P --> Q[依存パッケージ更新]
    Q --> R[テンプレートマイグレーション]
    R --> S{v3→v4?}
    S -->|Yes| T[migratePostCSSConfig]
    S -->|No| U[クリーンアップ]
    T --> U
    U --> V[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-59-01 | Gitクリーン要求 | Gitリポジトリが未コミットの変更を含む場合、マイグレーションを拒否 | 起動時（--forceで回避可能） |
| BR-59-02 | バージョン一致検証 | package.jsonのtailwindcssバージョンとnode_modulesのインストール済みバージョンが一致する必要がある | 起動時 |
| BR-59-03 | v3判定分岐 | メジャーバージョンが3の場合のみ、configリンク・スタイルシート分割・PostCSS設定マイグレーションを実行 | version.isMajor(3)の場合 |
| BR-59-04 | configファイル削除 | JSコンフィグが完全にマイグレーション可能な場合、マイグレーション後にconfigファイルを削除 | migrateJsConfigがnullでない場合 |
| BR-59-05 | CSSファイルのみフィルタ | 検出されたファイルから.css拡張子のファイルのみを処理対象 | ファイル検出後 |
| BR-59-06 | テンプレート重複除外 | 複数のTailwind rootから同じテンプレートファイルが検出された場合、重複を排除 | テンプレートマイグレーション時 |
| BR-59-07 | 変更検出 | 元のCSS文字列と変換後のCSS文字列を比較し、変更がある場合のみフォーマット処理を実行 | formatNodes適用前 |
| BR-59-08 | layer()クリーンアップ | @utility含むインポート済みシートの@import layer()修飾子を除去 | v3→v4マイグレーション時 |

### 計算ロジック

特になし

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Git dirty | 未コミット変更がある場合 | エラーメッセージを表示してprocess.exit(1) |
| - | バージョン不一致 | installed !== expected | "npm install"を促すメッセージを表示してprocess.exit(1) |
| - | ファイル読み込みエラー | CSSファイルの読み込みに失敗 | エラーを出力し、該当ファイルをスキップして続行 |
| - | マイグレーションエラー | 個別ファイルのマイグレーションに失敗 | エラーを出力して続行（プロセスは中断しない） |

### リトライ仕様

該当なし。マイグレーションはワンショット実行。

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

該当なし（ファイルシステムへの書き込みは個別実行。Gitでの復元が前提）

## パフォーマンス要件

- Promise.allSettledによるスタイルシートの並行読み込み
- Promise.allによるスタイルシートの並行マイグレーション
- Scannerによる高速なテンプレートファイル検出

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

- gitignoreに基づいてnode_modulesフォルダを除外
- パッケージマネージャコマンドの実行（add @latest）

## 備考

- v3→v4とv4内マイナーアップグレードの両方に対応
- migrateJsConfig、migrateStylesheet、migrateTemplateの各変換は別モジュールに分割されている
- 最終的にGit変更があったかを確認し、結果をユーザーに報告する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | CLIオプション定義（27-33行目）とフラグ解析 |

**読解のコツ**: run()関数が全体のオーケストレーションを行う。stylesheets配列がマイグレーション対象の中心的なデータ構造。configBySheetとjsConfigMigrationBySheetのMapが設定ファイル情報を保持する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | run()関数（43-360行目）がマイグレーションの全フローを制御 |

**主要処理フロー**:
1. **51-59行目**: Gitクリーンチェック
2. **62-85行目**: バージョン検証
3. **91-103行目**: CSSファイル検出
4. **108-128行目**: スタイルシート読み込み・解析
5. **132-141行目**: 設定ファイルリンク（v3のみ）
6. **144-177行目**: JSコンフィグマイグレーション
7. **183-210行目**: CSSスタイルシートマイグレーション
8. **213-241行目**: スタイルシート分割とlayer()クリーンアップ
9. **244-247行目**: 出力フォーマット
10. **250-258行目**: ファイル書き込み
11. **260-278行目**: 依存パッケージ更新
12. **283-343行目**: テンプレートマイグレーション
13. **346-349行目**: PostCSS設定マイグレーション（v3のみ）
14. **352行目**: クリーンアップ実行

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

```
run() [メインオーケストレーション]
    |
    +-- isRepoDirty()
    +-- version.installedTailwindVersion()
    |
    +-- globby(['**/*.css'])
    +-- Stylesheet.load(filepath)
    +-- analyzeStylesheets(stylesheets)
    |
    +-- [v3のみ] linkConfigsToStylesheets()
    |
    +-- prepareConfig(configPath)
    +-- migrateJsConfig(designSystem, configFilePath)
    |
    +-- migrateStylesheet(sheet, options)
    |
    +-- [v3のみ] splitStylesheets(stylesheets)
    |
    +-- postcss([sortBuckets(), formatNodes()]).process()
    |
    +-- fs.writeFile(sheet.file, sheet.root.toString())
    |
    +-- pkg(base).add(dependencies)
    |
    +-- Scanner({ sources })
    +-- migrateTemplate(designSystem, userConfig, file)
    |
    +-- [v3のみ] migratePostCSSConfig(base)
```

### データフロー図

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

CSSファイル群          ───▶  Stylesheet.load      ───▶  Stylesheet[]
                                    |
tailwind.config.js     ───▶  prepareConfig       ───▶  designSystem, userConfig
                                    |
                             migrateJsConfig      ───▶  新CSS設定 (or null)
                                    |
Stylesheet[]           ───▶  migrateStylesheet   ───▶  変換済みCSS
                                    |
                             splitStylesheets     ───▶  分割済みCSS
                                    |
                             formatNodes          ───▶  整形済みCSS → ファイル書き込み
                                    |
テンプレートファイル    ───▶  migrateTemplate     ───▶  変換済みテンプレート → ファイル書き込み
                                    |
postcss.config.js      ───▶  migratePostCSSConfig ───▶  変換済み設定 → ファイル書き込み
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | ソース | メインエントリーポイント・オーケストレーション |
| stylesheet.ts | `packages/@tailwindcss-upgrade/src/stylesheet.ts` | ソース | Stylesheetクラス定義 |
| analyze.ts | `packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts` | ソース | スタイルシート解析 |
| link.ts | `packages/@tailwindcss-upgrade/src/codemods/css/link.ts` | ソース | 設定ファイルリンク |
| migrate.ts | `packages/@tailwindcss-upgrade/src/codemods/css/migrate.ts` | ソース | CSSマイグレーション |
| split.ts | `packages/@tailwindcss-upgrade/src/codemods/css/split.ts` | ソース | スタイルシート分割 |
| migrate-js-config.ts | `packages/@tailwindcss-upgrade/src/codemods/config/migrate-js-config.ts` | ソース | JSコンフィグマイグレーション |
| migrate-postcss.ts | `packages/@tailwindcss-upgrade/src/codemods/config/migrate-postcss.ts` | ソース | PostCSS設定マイグレーション |
| migrate.ts | `packages/@tailwindcss-upgrade/src/codemods/template/migrate.ts` | ソース | テンプレートマイグレーション |
| prepare-config.ts | `packages/@tailwindcss-upgrade/src/codemods/template/prepare-config.ts` | ソース | コンフィグ準備 |
