# アーキテクチャ設計書

## 概要

本ドキュメントは、Tailwind CSS v4.2.1 のアーキテクチャ設計を記載する。Tailwind CSS はユーティリティファーストの CSS フレームワークであり、TypeScript（コアエンジン）と Rust（高速スキャナー）のハイブリッド構成による monorepo プロジェクトである。pnpm ワークスペースと Cargo ワークスペースを併用し、複数のパッケージ・クレートで構成される。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図](./アーキテクチャ構成図.md) を参照。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| Vite | Vite Plugin API | `@tailwindcss/vite` プラグインによるビルド時 CSS 生成 |
| PostCSS | PostCSS Plugin API | `@tailwindcss/postcss` プラグインによる CSS 変換パイプライン統合 |
| webpack | webpack Loader API | `@tailwindcss/webpack` ローダーによる CSS 変換 |
| Node.js ファイルシステム | `fs`/`enhanced-resolve` | ソースファイルスキャン、モジュール解決、スタイルシート読み込み |
| Lightning CSS | ライブラリ呼び出し | CSS 最適化・minify・ネスティング展開・ブラウザターゲット変換 |
| N-API (napi-rs) | FFI | Rust 製 Oxide エンジンと Node.js 間の橋渡し |
| jiti | ライブラリ呼び出し | TypeScript プラグイン/設定ファイルの動的インポート |

## レイヤー構成

### アーキテクチャスタイル

**パイプライン型 + モジュラーモノリス**

Tailwind CSS はクリーンアーキテクチャや DDD のような階層型ではなく、CSS 入力を受け取り、候補抽出 -> パース -> コンパイル -> 最適化 というパイプライン処理を行うコンパイラ型アーキテクチャを採用している。各処理ステップが独立したモジュールとして実装され、monorepo 内の複数パッケージに分割されている。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Integration Layer（統合層） | ビルドツール・エコシステムとの統合インターフェース | `@tailwindcss/vite`, `@tailwindcss/postcss`, `@tailwindcss/cli`, `@tailwindcss/webpack`, `@tailwindcss/browser` |
| Node Adapter Layer（Node アダプタ層） | Node.js 環境固有のファイル解決・モジュールロード・CSS 最適化 | `@tailwindcss/node`（`compile.ts`, `optimize.ts`, `urls.ts`） |
| Core Engine Layer（コアエンジン層） | CSS パース・候補コンパイル・テーマ管理・バリアント/ユーティリティ登録 | `tailwindcss`（`index.ts`, `compile.ts`, `design-system.ts`, `ast.ts`, `candidate.ts`, `utilities.ts`, `variants.ts`） |
| Scanner Layer（スキャナー層） | ソースファイルからの候補文字列抽出（Rust 実装） | `@tailwindcss/oxide`（Rust crate `tailwindcss-oxide`） |
| Compatibility Layer（互換性層） | v3 プラグイン・設定ファイルとの後方互換 | `tailwindcss/src/compat/`（`apply-compat-hooks.ts`, `plugin-api.ts`, `config/` 等） |

### レイヤー間の依存関係ルール

- **Integration Layer -> Node Adapter Layer -> Core Engine Layer**: 統合層は Node アダプタ層を介してコアエンジンを呼び出す。コアエンジンに直接依存することも許可されている（AST 型の利用等）。
- **Integration Layer -> Scanner Layer**: Vite/PostCSS/CLI プラグインは Oxide Scanner を直接利用してファイルスキャンを行う。
- **Node Adapter Layer -> Core Engine Layer**: `@tailwindcss/node` は `tailwindcss` コアの `compile`/`compileAst` 関数をラップし、Node.js 固有のモジュール解決と最適化を追加する。
- **Core Engine Layer -> Scanner Layer**: コアエンジン自体は Oxide Scanner に直接依存しない。スキャン結果は Integration Layer から候補文字列として渡される。
- **Compatibility Layer <- Core Engine Layer**: 互換性層はコアエンジンの一部として組み込まれ、`@plugin`/`@config` ディレクティブの処理時に呼び出される。
- **禁止**: Scanner Layer からコアエンジン/Node アダプタ層への依存は禁止されている。Rust クレートは独立して動作する。

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| CSS パース | CSS テキストを AST に変換 | `css-parser.ts`, `ast.ts`, `value-parser.ts` |
| 候補パース | ユーティリティクラス文字列を構造化された候補オブジェクトに変換 | `candidate.ts` |
| コンパイル | 候補オブジェクトから CSS AST ノードを生成 | `compile.ts`, `design-system.ts` |
| ユーティリティ | ユーティリティクラスの定義と CSS 生成ロジック | `utilities.ts` |
| バリアント | バリアント（`hover:`, `md:` 等）の定義と適用ロジック | `variants.ts` |
| テーマ | CSS カスタムプロパティベースのデザイントークン管理 | `theme.ts` |
| @import 解決 | `@import`/`@reference` ディレクティブのインライン展開 | `at-import.ts` |
| @apply 処理 | `@apply` ディレクティブのユーティリティ展開 | `apply.ts` |
| CSS 関数 | `theme()`, `--spacing()`, `--alpha()` 等のカスタム関数解決 | `css-functions.ts` |
| AST 走査 | AST ノードの再帰走査・変換ユーティリティ | `walk.ts` |
| ソースマップ | ソースマップの生成と管理 | `source-maps/` |
| ファイルスキャン | ソースファイルの glob マッチ・候補文字列抽出 | Oxide crate（`scanner/`, `extractor/`, `glob.rs`） |
| 最適化 | 生成 CSS の最適化・minify | `@tailwindcss/node/optimize.ts`（Lightning CSS 利用） |
| 互換性 | v3 プラグイン API・設定ファイルの後方互換 | `compat/` ディレクトリ |
| IntelliSense | エディタ補完用のクラスリスト・バリアントリスト生成 | `intellisense.ts`, `canonicalize-candidates.ts` |

### パッケージ構造

```
tailwindcss-main/
├── packages/
│   ├── tailwindcss/                    # コアエンジン (TypeScript)
│   │   └── src/
│   │       ├── index.ts                # メインエントリ (compile, compileAst)
│   │       ├── compile.ts              # 候補コンパイラ
│   │       ├── design-system.ts        # DesignSystem 構築
│   │       ├── ast.ts                  # CSS AST 型定義と操作
│   │       ├── css-parser.ts           # CSS パーサー
│   │       ├── candidate.ts            # 候補パーサー
│   │       ├── utilities.ts            # ユーティリティ定義 (~214KB)
│   │       ├── variants.ts             # バリアント定義 (~38KB)
│   │       ├── theme.ts                # テーマ管理
│   │       ├── walk.ts                 # AST 走査
│   │       ├── css-functions.ts        # CSS カスタム関数
│   │       ├── apply.ts                # @apply 処理
│   │       ├── at-import.ts            # @import 処理
│   │       ├── intellisense.ts         # IntelliSense API
│   │       ├── canonicalize-candidates.ts # 候補正規化
│   │       ├── sort.ts                 # クラスソート
│   │       ├── plugin.ts               # プラグイン API エントリ
│   │       ├── source-maps/            # ソースマップ生成
│   │       ├── compat/                 # v3 互換性レイヤー
│   │       │   ├── apply-compat-hooks.ts
│   │       │   ├── plugin-api.ts
│   │       │   ├── config/
│   │       │   ├── dark-mode.ts
│   │       │   ├── legacy-utilities.ts
│   │       │   └── ...
│   │       └── utils/                  # 汎用ユーティリティ
│   │           ├── escape.ts
│   │           ├── segment.ts
│   │           ├── default-map.ts
│   │           ├── infer-data-type.ts
│   │           ├── brace-expansion.ts
│   │           └── ...
│   ├── @tailwindcss-node/              # Node.js アダプタ
│   │   └── src/
│   │       ├── index.ts                # エントリ (re-export)
│   │       ├── compile.ts              # Node.js 向けコンパイララッパー
│   │       ├── optimize.ts             # Lightning CSS による最適化
│   │       ├── urls.ts                 # URL リライト
│   │       ├── env.ts                  # 環境変数
│   │       └── instrumentation.ts      # 計測
│   ├── @tailwindcss-vite/              # Vite プラグイン
│   ├── @tailwindcss-postcss/           # PostCSS プラグイン
│   ├── @tailwindcss-cli/               # CLI ツール
│   ├── @tailwindcss-webpack/           # webpack ローダー
│   ├── @tailwindcss-browser/           # ブラウザ向けバンドル
│   ├── @tailwindcss-standalone/        # スタンドアロン CLI (Bun バンドル)
│   └── @tailwindcss-upgrade/           # v3 -> v4 マイグレーションツール
├── crates/
│   ├── oxide/                          # Rust コアスキャナー
│   │   └── src/
│   │       ├── lib.rs                  # エントリ
│   │       ├── scanner/                # ファイルスキャナー
│   │       │   ├── mod.rs              # Scanner 構造体
│   │       │   ├── auto_source_detection.rs
│   │       │   ├── detect_sources.rs
│   │       │   └── sources.rs
│   │       ├── extractor/              # 候補文字列抽出器
│   │       │   ├── mod.rs
│   │       │   ├── candidate_machine.rs
│   │       │   ├── utility_machine.rs
│   │       │   ├── variant_machine.rs
│   │       │   └── ...
│   │       ├── glob.rs                 # Glob パターンマッチ
│   │       ├── cursor.rs               # テキストカーソル
│   │       ├── fast_skip.rs            # 高速スキップ
│   │       └── paths.rs                # パス操作
│   ├── node/                           # N-API バインディング
│   │   └── src/
│   │       ├── lib.rs                  # napi-derive による FFI 定義
│   │       └── utf16.rs                # UTF-16 インデックス変換
│   ├── classification-macros/          # Rust マクロ
│   └── ignore/                         # gitignore 互換ライブラリ
├── integrations/                       # 統合テスト
├── playgrounds/                        # 開発用プレイグラウンド
└── scripts/                            # ビルド・リリーススクリプト
```

### コンポーネント依存関係

コアパッケージ間の依存関係は以下の通りである。

- `@tailwindcss/vite` -> `@tailwindcss/node`, `@tailwindcss/oxide`, `tailwindcss`
- `@tailwindcss/postcss` -> `@tailwindcss/node`, `@tailwindcss/oxide`, `tailwindcss`
- `@tailwindcss/cli` -> `@tailwindcss/node`, `@tailwindcss/oxide`, `tailwindcss`
- `@tailwindcss/webpack` -> `@tailwindcss/node`, `@tailwindcss/oxide`, `tailwindcss`
- `@tailwindcss/node` -> `tailwindcss`, `lightningcss`, `enhanced-resolve`, `jiti`
- `@tailwindcss/standalone` -> `@tailwindcss/cli`, `tailwindcss`
- `@tailwindcss/browser` -> `tailwindcss`
- `tailwindcss` -> `@tailwindcss/oxide`（devDependency として）, `lightningcss`（AST 最適化用）
- `@tailwindcss/oxide` (npm) -> `tailwindcss-oxide` (Rust crate、N-API 経由)
- `tailwindcss-oxide` (Rust) -> `classification-macros`, `ignore` crate

## ミドルウェア構成

### データベース

本プロジェクトはデータベースを使用しない。CSS コンパイラ/ビルドツールであり、永続化はファイルシステムへの CSS 出力のみである。

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| `@alloc/quick-lru` | ^5.2.0 | PostCSS プラグインのコンパイル結果キャッシュ（LRU、最大50エントリ） | ファイル mtime ベースの無効化 |
| `DefaultMap`（自作） | - | 候補パース結果・バリアントパース結果・コンパイル済み AST ノードのメモ化 | プロセスライフタイム |
| `enhanced-resolve` `CachedInputFileSystem` | - | ファイルシステム解決結果のキャッシュ（4000ms TTL） | 4000ms |

### メッセージキュー

本プロジェクトはメッセージキューを使用しない。

### 検索エンジン

本プロジェクトは検索エンジンを使用しない。

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Lightning CSS | 1.31.1 | CSS 最適化・minify・ネスティング展開・ブラウザ互換変換 |
| `@parcel/watcher` | ^2.5.1 | CLI の `--watch` モードにおけるファイル変更監視 |
| `enhanced-resolve` | ^5.19.0 | Node.js モジュール解決（CSS/JS ファイル） |
| `jiti` | ^2.6.1 | TypeScript プラグイン/設定ファイルの実行時インポート |
| `magic-string` | ^0.30.21 | ソースマップ保持文字列置換 |
| `@jridgewell/remapping` | ^2.3.5 | ソースマップのリマッピング・結合 |

## データフロー

### リクエスト処理の流れ

Tailwind CSS のメイン処理パイプラインは以下の通りである。

1. **CSS 入力の受け取り**: ユーザーの CSS ファイル（`@tailwind utilities`, `@theme`, `@import` 等を含む）が入力として渡される
2. **CSS パース** (`css-parser.ts`): CSS テキストを AST（抽象構文木）にパースする。`StyleRule`, `AtRule`, `Declaration`, `Comment`, `Context`, `AtRoot` の6種のノード型を持つ
3. **@import 解決** (`at-import.ts`): `@import`/`@reference` ディレクティブを再帰的に解決し、外部スタイルシートの内容をインラインに展開する
4. **AST 走査と構造解析** (`index.ts` の `parseCss`): AST を走査し、以下を収集・処理する
   - `@theme` ブロックからテーマ変数を `Theme` オブジェクトに登録
   - `@tailwind utilities` ノードの位置を記録
   - `@custom-variant` からカスタムバリアントを登録
   - `@utility` からカスタムユーティリティを登録
   - `@source` からスキャン対象パスを収集
   - `important` 設定の検出
5. **DesignSystem 構築** (`design-system.ts`): `Theme`, `Utilities`, `Variants` の3つのレジストリを持つ `DesignSystem` オブジェクトを構築する
6. **互換性フック適用** (`compat/apply-compat-hooks.ts`): `@plugin`/`@config` ディレクティブを処理し、v3 互換のプラグイン・設定を適用する
7. **CSS 関数解決** (`css-functions.ts`): `theme()`, `--spacing()`, `--alpha()`, `--theme()` 等のカスタム関数を解決・展開する
8. **@variant 置換** (`variants.ts`): `@variant` ディレクティブを実際のバリアントルールに展開する
9. **@apply 置換** (`apply.ts`): `@apply` ディレクティブをユーティリティの実際の CSS に展開する
10. **ソースファイルスキャン** (Oxide Scanner): Integration Layer が Rust 製 Scanner を使用してソースファイルから候補文字列（クラス名）を抽出する
11. **候補コンパイル** (`compile.ts`): 抽出された候補文字列を `designSystem.parseCandidate()` でパースし、`compileCandidates()` で CSS AST ノードに変換する。バリアントの適用、`!important` 処理、プロパティ順序によるソートが行われる
12. **AST 最適化** (`ast.ts` の `optimizeAst`): ポリフィル挿入（`@property` フォールバック、`color-mix` フォールバック）、空ノード除去等の最適化を行う
13. **CSS 出力** (`ast.ts` の `toCss`): 最適化された AST を CSS テキストに変換する
14. **CSS 後最適化** (`@tailwindcss/node/optimize.ts`): Lightning CSS を使用してネスティング展開、ブラウザターゲット変換、minify を行う。2パス処理により隣接ルールのマージを最適化する

### 非同期処理の流れ

1. **ファイル監視** (CLI `--watch` モード): `@parcel/watcher` がファイル変更を検知し、変更されたファイルの候補文字列を再抽出する
2. **Vite HMR**: Vite Dev Server がファイル変更を検知し、CSS モジュールのホットリロードをトリガーする。変更されたファイルの候補が再スキャンされ、CSS が再生成される
3. **インクリメンタルビルド**: `build()` 関数は前回のビルド結果をキャッシュし、新しい候補が追加された場合のみ再コンパイルを行う。候補セットに変更がなければキャッシュされた CSS をそのまま返す

### データ永続化の流れ

1. **CSS 出力**: コンパイル済み CSS は CLI の場合はファイルに書き出され、Vite/PostCSS/webpack の場合はビルドパイプラインに渡される
2. **ソースマップ**: `buildSourceMap()` によりデコード済みソースマップが生成され、元の CSS ファイルへのマッピングが提供される

## 横断的関心事

### 認証・認可

本プロジェクトは CSS コンパイラであり、認証・認可の仕組みは存在しない。

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| デバッグログ | `env.DEBUG` フラグによる条件付き出力 | 標準出力/標準エラー |
| Rust トレーシング | `tracing` / `tracing-subscriber` クレート、`SHOULD_TRACE` フラグ | 標準出力 |
| 最適化警告 | Lightning CSS の `errorRecovery` モードによる警告出力 | 標準エラー（`console.warn`） |
| インストルメンテーション | `@tailwindcss/node/instrumentation.ts` | - |

### エラーハンドリング

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| CSS 構文エラー | `CssSyntaxError` 例外（ソース位置情報付き） | ファイル名・行・列番号を含むエラーメッセージ |
| 無効なユーティリティ名 | `@utility` 解析時の `throw new Error` | 具体的な問題と正しい形式を示すメッセージ |
| 循環依存 | カスタムバリアントのトポロジカルソートで検出 | 循環パスを視覚的に表示するエラーメッセージ |
| モジュール解決失敗 | `enhanced-resolve` による解決失敗時の例外 | `Could not resolve '...' from '...'` |
| @import 循環参照 | 再帰深度制限（100）による検出 | `Exceeded maximum recursion depth` |
| 無効な候補文字列 | `designSystem.invalidCandidates` セットで追跡、無視 | エラーなし（サイレント無視） |
| Lightning CSS 変換エラー | `errorRecovery: true` で警告に降格 | 警告出力、処理は継続 |

### トランザクション管理

本プロジェクトはデータベーストランザクションを使用しない。代わりに、CSS コンパイルにおけるイミュータブルなデータフローとインクリメンタルビルドのキャッシュ整合性管理が行われている。

| 範囲 | 管理方式 | 備考 |
| --- | --- | --- |
| コンパイル結果キャッシュ | ファイル mtime による無効化 | PostCSS プラグインの `CacheEntry` |
| 候補セット管理 | 追加のみ（削除なし） | `allValidCandidates` は単調増加 |
| AST ノードキャッシュ | `DefaultMap` によるメモ化 | 候補 -> AST ノードの変換結果をキャッシュ |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| パイプラインパターン | CSS コンパイル全体 | `parseCss` -> `compileCandidates` -> `optimizeAst` -> `toCss` |
| ビジターパターン | AST 走査 | `walk()` 関数による AST ノードの再帰走査（`WalkAction` による制御） |
| レジストリパターン | ユーティリティ・バリアント管理 | `Utilities` クラス、`Variants` クラスによるプラグイン登録 |
| メモ化パターン | パース結果・コンパイル結果 | `DefaultMap` を使用した遅延評価キャッシュ |
| ファサードパターン | DesignSystem | 各種機能（Theme, Utilities, Variants, パーサー等）を統合した単一インターフェース |
| アダプタパターン | ビルドツール統合 | `@tailwindcss/vite`, `@tailwindcss/postcss`, `@tailwindcss/webpack` が各ツールの API に適合 |
| FFI ブリッジパターン | Rust/Node.js 連携 | `crates/node` が napi-derive で Rust コアを Node.js に公開 |
| インクリメンタルビルド | `build()` 関数 | 候補セットの差分検出により不要な再コンパイルを回避 |
| ビットフラグパターン | Feature/Polyfill/ThemeOptions 管理 | `enum Features`, `enum Polyfills`, `enum ThemeOptions` でビット演算による効率的な状態管理 |

### コーディング規約

- **言語**: TypeScript（コアエンジン・統合層）、Rust（スキャナー・候補抽出）
- **フォーマッター**: Prettier（`semi: false`, `singleQuote: true`, `printWidth: 100`）
- **ビルドツール**: tsup（TypeScript バンドル）、Cargo（Rust ビルド）、Turbo（monorepo タスクランナー）
- **テスト**: Vitest（単体テスト）、Playwright（UI テスト）、`cargo test`（Rust テスト）
- **パッケージマネージャ**: pnpm 9.6.0（workspace プロトコル使用）
- **Rust ツールチェーン**: Rust 1.85.0（stable）、LTO 有効（リリースプロファイル）
- **命名規則**: TypeScript は camelCase、Rust は snake_case（標準規約に準拠）
- **export 方針**: コアパッケージ（`tailwindcss`）は `compile`/`compileAst` を主要エントリポイントとし、内部モジュールは直接エクスポートしない
- **テスト配置**: テストファイル（`*.test.ts`）はソースファイルと同ディレクトリに配置するコロケーション方式

## 備考

- Tailwind CSS v4 は v3 から大幅にアーキテクチャが刷新され、CSS-first のアプローチ（`tailwind.config.js` から CSS ディレクティブへの移行）を採用している
- Rust 製 Oxide エンジンの導入により、ファイルスキャンと候補文字列抽出のパフォーマンスが大幅に向上している
- `@tailwindcss/browser` パッケージにより、ブラウザ上での直接実行（CDN 利用等）にも対応している
- `@tailwindcss/upgrade` パッケージは tree-sitter を使用した AST ベースのコード変換ツールであり、v3 から v4 への自動マイグレーションを提供する
- `@tailwindcss/standalone` は Bun を使用してシングルバイナリとしてバンドルされ、Node.js なしで実行可能である
