Arhitectură
TailwindPHP este o portare 1:1. Baza de cod reproduce propria structură a TailwindCSS — aceleași nume de fișiere, aceeași organizare — și izolează sub src/_tailwindphp/ părțile care nu pot fi portate direct (PHP nu are Rust și nici V8). Această pagină parcurge pipeline-ul de compilare, structura sursei, reimplementarea lightningcss și convenția folosită pentru documentarea abaterilor.
Procesul de lucru
Generarea CSS este o succesiune de etape. Nu există o etapă de compilare separată — fiecare apel către tw::generate() rulează întregul pipeline.
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
Analizare. css-parser.php citește intrarea CSS — @import, @theme, @utility, @layer, reguli brute — într-un arbore sintactic abstract de noduri ast.php (reguli de stil, reguli at, declarații). Directivele @import pentru module virtuale (tailwindcss, tailwindcss/preflight, …) și căile fișierelor sunt rezolvate și înlocuite în această etapă.
Construirea sistemului de design. theme.php rezolvă valorile temei (culori, spațiere, puncte de întrerupere) din blocurile @theme analizate și din valorile implicite. design-system.php este registrul central care leagă tema de căutările de utilitare și variante definite în utilities.php și variants.php.
Scanarea conținutului. candidate.php extrage candidați pentru nume de clase din conținutul furnizat (HTML, șabloane) și îi analizează pe fiecare în componentele sale — utilitar de bază, variante, modificatori, valori arbitrare, indicator important.
Compilare. compile.php transformă fiecare candidat în noduri AST, căutându-l în sistemul de design și aplicându-i variantele și modificatorii. Candidații care nu corespund unui utilitar real sunt eliminați.
Serializare și optimizare. toCss() din ast.php parcurge arborele (cu ajutoare din walk.php) și emite șirul CSS. Se aplică transformările echivalente cu lightningcss din _tailwindphp/LightningCss.php, astfel încât rezultatul să corespundă celui produs de TailwindCSS după etapa de postprocesare Rust.
Minificare. Când minify este activată, toCss() emite CSS minificat în timpul serializării. _tailwindphp/CssMinifier.php asigură etapa autonomă de procesare a șirului tw::minify(). Consultați Memorare în cache și minificare.
Structura sursei
src/ reproduce structura din TailwindCSS. Singura modificare structurală: utilities.ts din TailwindCSS are peste 6,000 de linii, așa că este împărțit în src/utilities/, câte un fișier per categorie, pentru mentenabilitate.
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
Echivalentul lightningcss
TailwindCSS deleagă către lightningcss, un analizator/transformator/minificator scris în Rust, postprocesarea CSS — gestionarea imbricării, a interogărilor media și simplificarea valorilor. PHP nu poate încărca o bibliotecă Rust, așa că src/_tailwindphp/LightningCss.php reimplementează transformările de care chiar are nevoie TailwindPHP, producând rezultate identice la nivel de octeți pentru cazurile acoperite de suita de teste.
Transformările confirmate includ:
| Transformare | Ce face |
|---|---|
| Aplatizarea imbricării | Rezolvă selectorii & folosind regulile :is(…) ale referinței și aplatizează regulile imbricate (handleNesting() în ast.php, o portare a etapei TailwindCSS); transformNesting coboară nivelul imbricării rămase sub primul nivel care conține declarații |
| Aplatizarea regulilor at condiționale | Aplatizează în loc regulile @media, @supports, @container și @starting-style imbricate, păstrând ordinea sursei și combinând doar elementele surori direct alăturate cu condiții identice |
| Ordonarea declarațiilor | Reordonează declarațiile conform lanțului de gestionare a declarațiilor din lightningcss, astfel încât proprietățile să apară în ordinea referinței (reorderDeclarations) |
Simplificarea calc() |
Simplifică expresiile calc() (simplifyCalcExpressions) |
| Eliminarea zerourilor inițiale | 0.5 → .5 (normalizeLeadingZeros) |
| Spațierea funcțiilor de transformare | Normalizează spațierea din funcțiile de transformare (normalizeTransformFunctions) |
| Normalizarea valorilor grid | Adaugă spații în jurul lui / în valorile span; transformă numerele întregi simple în px pentru grid-template-* (normalizeGridValues) |
| Normalizarea culorilor | Normalizează sintaxa culorilor și evaluează color-mix() la oklab() (normalizeColors, evaluateColorMix) |
| Ghilimele pentru URL | url(./x.jpg) → url("./x.jpg") (normalizeUrlQuoting) |
| Prefixe de furnizor | Prefixare echivalentă cu Autoprefixer (addVendorPrefixes) |
Acest fișier este plasat intenționat în carantină sub _tailwindphp/ și marcat @port-deviation:replacement — ține locul unei dependențe externe, în loc să porteze sursa TailwindCSS.
Marcaje pentru abaterile portării
Fiecare fișier de implementare conține marcaje @port-deviation:* în blocul de documentare, care precizează unde și de ce implementarea PHP se abate de la originalul TypeScript. Scopul este ca cititorul care compară PHP cu sursa TailwindCSS să nu fie nevoit să se întrebe dacă o diferență este intenționată.
| Marcaj | Semnificație |
|---|---|
@port-deviation:none |
Portare 1:1 directă, fără abateri semnificative |
@port-deviation:async |
PHP folosește cod sincron în loc de async/await |
@port-deviation:storage |
Structuri de date diferite (tablou PHP față de Map/Set JS) |
@port-deviation:types |
Adnotări PHPDoc în locul tipurilor TypeScript |
@port-deviation:sourcemaps |
Urmărirea hărților sursă este omisă |
@port-deviation:enum |
Constante PHP în locul enumerărilor TypeScript |
@port-deviation:errors |
Abordare diferită pentru tratarea erorilor |
@port-deviation:replacement |
Implementare PHP care înlocuiește o bibliotecă externă (e.g. lightningcss) |
@port-deviation:helper |
Funcție ajutătoare specifică PHP, absentă din original |
@port-deviation:performance |
Optimizare specifică PHP care păstrează rezultatul identic |
@port-deviation:omitted |
Modul/funcționalitate complet neportată (în afara domeniului) |
Pentru marcajele @port-deviation:performance și modul în care este impusă paritatea, consultați Performanță și testare.