Gå til indhold

Arkitektur

TailwindPHP er en 1:1-portering. Kodebasen afspejler TailwindCSSs egen struktur — samme filnavne, samme organisering — og isolerer de dele, der ikke kan porteres direkte (PHP har ingen Rust og ingen V8), under src/_tailwindphp/. Denne side gennemgår kompileringspipelinen, kildelayoutet, genimplementeringen af lightningcss og konventionen for dokumentation af afvigelser.

Pipelineforløbet

Generering af CSS består af en række trin. Der er intet separat buildtrin — hvert kald til tw::generate() kører hele pipelinen.

Kode
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

Parse. css-parser.php læser CSS-inputtet — @import, @theme, @utility, @layer og rå regler — ind i et abstrakt syntakstræ med ast.php-noder (stilregler, at-regler, deklarationer). @import-direktiver for virtuelle moduler (tailwindcss, tailwindcss/preflight, …) og filstier afklares og indsættes på dette trin.

Byg designsystemet. theme.php afklarer temaværdier (farver, afstande, brudpunkter) fra de fortolkede @theme-blokke plus standardværdierne. design-system.php er det centrale register, der forbinder temaet med opslagene for værktøjer og varianter, som defineres i utilities.php og variants.php.

Scan indhold. candidate.php udtrækker kandidater til klassenavne fra det angivne indhold (HTML, skabeloner) og opdeler hver kandidat i dens dele — basisværktøj, varianter, modifikatorer, vilkårlige værdier og vigtigt-flag.

Kompilér. compile.php omdanner hver kandidat til AST-noder ved at slå den op i designsystemet og anvende dens varianter og modifikatorer. Kandidater, der ikke svarer til et reelt værktøj, kasseres.

Serialisér og optimér. ast.phps toCss() gennemløber træet (hjælpefunktioner i walk.php) og udsender CSS-strengen. Transformationerne svarende til lightningcss i _tailwindphp/LightningCss.php anvendes, så outputtet matcher det, TailwindCSS producerer efter sin efterbehandlingsfase med Rust.

Minificér. Når minify er aktiveret, udsender toCss() minificeret CSS under serialisering. _tailwindphp/CssMinifier.php står bag den selvstændige tw::minify()-strengbehandling. Se Caching og minificering.

Kildelayout

src/ afspejler TailwindCSS. Den eneste strukturelle ændring: TailwindCSSs utilities.ts fylder 6,000+ linjer, så den er opdelt i src/utilities/ med én fil pr. kategori for at lette vedligeholdelsen.

Kode
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-ækvivalenten

TailwindCSS overlader sin efterbehandling af CSS — nesting, håndtering af media queries og forenkling af værdier — til lightningcss, en parser/transformer/minificerer skrevet i Rust. PHP kan ikke indlæse et Rust-bibliotek, så src/_tailwindphp/LightningCss.php genimplementerer de transformationer, som TailwindPHP faktisk bruger, og producerer byteidentisk output for de tilfælde, som testsuiten dækker.

Bekræftede transformationer omfatter:

Transformation Hvad den gør
Udfladning af nesting Afklarer &-selektorer med referencens :is(…)-regler og udflader indlejrede regler (handleNesting() i ast.php, en portering af passet TailwindCSS); transformNesting nedgraderer den resterende nesting under det første niveau med deklarationer
Udfladning af betingede at-regler Udflader indlejrede @media, @supports, @container og @starting-style på stedet, bevarer kilderækkefølgen og sammenfletter kun direkte tilstødende søskende med identiske betingelser
Rækkefølge af deklarationer Omarrangerer deklarationer efter lightningcss' kæde af deklarationsbehandlere, så egenskaberne følger referencens rækkefølge (reorderDeclarations)
Forenkling af calc() Forenkler calc()-udtryk (simplifyCalcExpressions)
Fjernelse af indledende nul 0.5 → .5 (normalizeLeadingZeros)
Afstand i transform-funktioner Normaliserer mellemrum i transform-funktioner (normalizeTransformFunctions)
Normalisering af grid-værdier Tilføjer mellemrum omkring / i span-værdier, bare heltal → px for grid-template-* (normalizeGridValues)
Normalisering af farver Normaliserer farvesyntaks og evaluerer color-mix() til oklab() (normalizeColors, evaluateColorMix)
Citering af URL url(./x.jpg) → url("./x.jpg") (normalizeUrlQuoting)
Leverandørpræfikser Præfiksering svarende til Autoprefixer (addVendorPrefixes)

Denne fil er bevidst placeret i karantæne under _tailwindphp/ og markeret @port-deviation:replacement — den repræsenterer en ekstern afhængighed i stedet for at portere TailwindCSS-kildekode.

Markører for porteringsafvigelser

Hver implementeringsfil indeholder @port-deviation:*-markører i sin docblock, der angiver, hvor og hvorfor PHP-implementeringen afviger fra originalen i TypeScript. Målet er, at læsere, der sammenligner PHP med TailwindCSS-kildekode, aldrig skal være i tvivl om, hvorvidt en forskel er tilsigtet.

Markør Betydning
@port-deviation:none Direkte 1:1-portering uden væsentlige afvigelser
@port-deviation:async PHP bruger synkron kode i stedet for async/await
@port-deviation:storage Forskellige datastrukturer (PHP-array mod JS Map/Set)
@port-deviation:types PHPDoc-annoteringer i stedet for TypeScript-typer
@port-deviation:sourcemaps Sporing af source maps udeladt
@port-deviation:enum PHP-konstanter i stedet for TypeScript-enumtyper
@port-deviation:errors Anderledes fejlhåndtering
@port-deviation:replacement PHP-implementering erstatter et eksternt bibliotek (e.g. lightningcss)
@port-deviation:helper Hjælpefunktion specifik for PHP, som ikke findes i originalen
@port-deviation:performance Optimering specifik for PHP, der bevarer identisk output
@port-deviation:omitted Hele modulet/funktionen er ikke porteret (uden for omfanget)

Se Ydeevne og test for markørerne @port-deviation:performance og for at se, hvordan paritet håndhæves.