
# 架构

TailwindPHP 是一个 1:1 移植版。代码库复现了 TailwindCSS 自身的结构——文件名和组织方式都相同——并将无法直接移植的部分隔离在 `src/_tailwindphp/` 下（PHP 没有 Rust，也没有 V8）。本页将介绍编译流程、源代码布局、`lightningcss` 的重新实现，以及用于记录差异的约定。

## 处理流程

生成 CSS 是一个分阶段的过程。没有单独的构建步骤——每次调用 `tw::generate()` 都会运行完整流程。

```
CSS input          (@import "tailwindcss"; @theme { … })
  │
  ▼
┌──────────────┐
│  Parse CSS   │  css-parser.php → ast.php nodes
└──────┬───────┘
       ▼  design system (theme, utilities, variants)
┌──────────────┐
│ Scan content │  candidate.php — extract class names from HTML
└──────┬───────┘
       ▼  candidates
┌──────────────┐
│   Compile    │  compile.php — candidate → AST, via design-system.php
└──────┬───────┘
       ▼  AST
┌──────────────┐
│   Optimize   │  _tailwindphp/LightningCss.php — nesting, @media, calc()
└──────┬───────┘
       ▼
┌──────────────┐
│  Serialize   │  ast.php toCss()   (minified when requested)
└──────┬───────┘
       ▼
CSS output
```

**解析。** `css-parser.php` 将 CSS 输入（`@import`、`@theme`、`@utility`、`@layer` 原始规则）解析为由 `ast.php` 节点（样式规则、at 规则、声明）组成的抽象语法树。此阶段会解析并替换虚拟模块（`tailwindcss`、`tailwindcss/preflight`、…）和文件路径对应的 `@import` 指令。

**构建设计系统。** `theme.php` 根据已解析的 `@theme` 代码块和默认值解析主题值（颜色、间距、断点）。`design-system.php` 是核心注册表，将主题与 `utilities.php` 和 `variants.php` 中定义的实用工具及变体查找关联起来。

**扫描内容。** `candidate.php` 从提供的内容（HTML、模板）中提取类名候选项，并将每项解析为其组成部分：基础实用工具、变体、修饰符、任意值和重要标记。

**编译。** `compile.php` 在设计系统中查找每个候选项，并应用其变体和修饰符，将其转换为 AST 节点。无法解析为实际实用工具的候选项会被丢弃。

**序列化并优化。** `ast.php` 的 `toCss()` 遍历语法树（使用 `walk.php` 中的辅助函数），并生成 CSS 字符串。应用 `_tailwindphp/LightningCss.php` 中与 `lightningcss` 等效的转换，使输出与 TailwindCSS 经过 Rust 后处理后生成的内容一致。

**压缩。** 启用 `minify` 时，`toCss()` 会在序列化期间生成压缩后的 CSS。`_tailwindphp/CssMinifier.php` 为独立的 `tw::minify()` 字符串处理流程提供支持。请参阅[缓存和压缩](https://tailwindphp.inline0.dev/zh/docs/advanced/caching)。

## 源码布局

`src/` 与 TailwindCSS 保持一致。结构上的唯一变化是：TailwindCSS 的 `utilities.ts` 有 6,000 多行，因此按类别拆分为 `src/utilities/`，每个类别一个文件，便于维护。

```
src/
├── _tailwindphp/                # PHP-specific — NOT part of the TailwindCSS port
│   ├── LightningCss.php         # CSS transforms (lightningcss Rust library equivalent)
│   ├── CssMinifier.php          # CSS minification
│   └── lib/                     # Companion library ports (TailwindPHP\Lib\*)
│       ├── clsx/                # clsx port
│       ├── tailwind-merge/      # tailwind-merge port
│       └── cva/                 # CVA port
│
├── plugin/                      # Plugin system
│   └── plugins/
│       ├── typography-plugin.php  # @tailwindcss/typography port
│       └── forms-plugin.php       # @tailwindcss/forms port
│
├── utilities/                   # Split from TailwindCSS utilities.ts (one file per category)
│   ├── accessibility.php        # sr-only, forced-colors
│   ├── backgrounds.php          # bg-*, gradient-*, from-*, via-*, to-*
│   ├── borders.php              # border-*, rounded-*, divide-*, outline-*
│   ├── effects.php              # shadow-*, opacity-*, mix-blend-*
│   ├── filters.php              # blur-*, brightness-*, contrast-*, …
│   ├── flexbox.php              # flex-*, grid-*, gap-*, justify-*, align-*
│   ├── interactivity.php        # cursor-*, scroll-*, touch-*, select-*
│   ├── layout.php               # display, position, z-*, overflow-*, …
│   ├── masks.php                # mask-linear-*, mask-radial-*, mask-conic-*
│   ├── sizing.php               # w-*, h-*, min-*, max-*, size-*
│   ├── spacing.php              # m-*, p-*, space-*
│   ├── svg.php                  # fill-*, stroke-*
│   ├── tables.php               # border-collapse, table-layout
│   ├── transforms.php           # translate-*, rotate-*, scale-*, skew-*
│   ├── transitions.php          # transition-*, duration-*, ease-*, delay-*
│   └── typography.php           # font-*, text-*, leading-*, tracking-*
│
├── utils/                       # Helper functions (ported from utils/)
│
├── index.php                    # Main entry — compile(), cn(), variants(), merge(), join()
├── ast.php                      # AST nodes and toCss()
├── candidate.php                # Candidate parsing (class name → parts)
├── compile.php                  # Candidate to CSS compilation
├── css-functions.php            # theme(), --theme(), --spacing(), --alpha()
├── css-parser.php               # CSS parsing
├── design-system.php            # Central registry for utilities/variants
├── plugin.php                   # Plugin system (PluginInterface, PluginAPI, PluginManager)
├── theme.php                    # Theme value resolution
├── utilities.php                # Utility registration and lookup
├── value-parser.php             # CSS value parsing
├── variants.php                 # Variant handling (hover, focus, responsive, …)
└── walk.php                     # AST traversal
```

## lightningcss 的等效实现

TailwindCSS 将其 CSS 后处理（嵌套、媒体查询处理、值简化）交给 [lightningcss](https://lightningcss.dev/)，这是一个用 Rust 编写的解析器、转换器和压缩器。PHP 无法加载 Rust 库，因此 `src/_tailwindphp/LightningCss.php` 重新实现 TailwindPHP 实际依赖的转换，并针对测试套件覆盖的情况生成逐字节一致的输出。

已确认的转换包括：

| 转换 | 作用 |
|-----------|--------------|
| 展平嵌套规则 | 按照参考实现的 `:is(…)` 规则解析 `&` 选择器并展平嵌套规则（`ast.php` 中的 `handleNesting()`，是 TailwindCSS 处理流程的移植）；`transformNesting` 将首个包含声明的层级以下剩余的嵌套规则降级处理 |
| 展平条件 at 规则 | 就地展平嵌套的 `@media`、`@supports`、`@container` 和 `@starting-style`，保留源码顺序，并且只合并条件相同且直接相邻的同级规则 |
| 声明排序 | 按照 lightningcss 的声明处理器链重新排序声明，使属性顺序与参考实现一致（`reorderDeclarations`） |
| `calc()` 简化 | 简化 `calc()` 表达式（`simplifyCalcExpressions`） |
| 移除前导零 | `0.5` → `.5`（`normalizeLeadingZeros`） |
| 转换函数间距 | 规范化转换函数内部的间距（`normalizeTransformFunctions`） |
| 网格值规范化 | 在跨列值中的 `/` 两侧添加空格，并将 `grid-template-*` 的裸整数转换为 px（`normalizeGridValues`） |
| 颜色规范化 | 规范化颜色语法，并将 `color-mix()` 计算为 `oklab()`（`normalizeColors`、`evaluateColorMix`） |
| URL 引号处理 | `url(./x.jpg)` → `url("./x.jpg")`（`normalizeUrlQuoting`） |
| 厂商前缀 | 等效于 Autoprefixer 的前缀处理（`addVendorPrefixes`） |

此文件有意隔离在 `_tailwindphp/` 下，并标记为 `@port-deviation:replacement`；它代表外部依赖，而非移植 TailwindCSS 源码。

## 移植偏差标记

每个实现文件的文档块中都带有 `@port-deviation:*` 标记，说明 PHP 实现与原始 TypeScript 有何差异以及原因。这样，读者对照 PHP 和 TailwindCSS 源码时，无需猜测差异是否有意为之。

| 标记 | 含义 |
|--------|---------|
| `@port-deviation:none` | 直接移植 1:1，没有显著偏差 |
| `@port-deviation:async` | PHP 使用同步代码，而非 async/await |
| `@port-deviation:storage` | 数据结构不同（PHP 数组，而非 JS Map/Set） |
| `@port-deviation:types` | 使用 PHPDoc 注解，而非 TypeScript 类型 |
| `@port-deviation:sourcemaps` | 未实现源码映射跟踪 |
| `@port-deviation:enum` | 使用 PHP 常量，而非 TypeScript 枚举 |
| `@port-deviation:errors` | 错误处理方式不同 |
| `@port-deviation:replacement` | 使用 PHP 实现替代外部库（e.g. lightningcss） |
| `@port-deviation:helper` | 原实现中没有的 PHP 专用辅助函数 |
| `@port-deviation:performance` | PHP 专用优化，可保持输出一致 |
| `@port-deviation:omitted` | 整个模块或功能未移植（不在范围内） |

关于 `@port-deviation:performance` 标记以及如何确保一致性，请参阅[性能与测试](https://tailwindphp.inline0.dev/zh/docs/advanced/performance)。
