Arsitektur
TailwindPHP adalah port 1:1. Basis kode mencerminkan struktur milik TailwindCSS sendiri — nama file dan pengorganisasian yang sama — serta mengisolasi bagian yang tidak dapat di-port langsung (PHP tidak memiliki Rust maupun V8) di bawah src/_tailwindphp/. Halaman ini menjelaskan alur kompilasi, tata letak sumber, implementasi ulang lightningcss, dan konvensi untuk mendokumentasikan penyimpangan.
Pipeline
Pembuatan CSS terdiri dari serangkaian tahap. Tidak ada langkah build terpisah — setiap pemanggilan tw::generate() menjalankan seluruh alur.
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
Parsing. css-parser.php membaca masukan CSS — @import, @theme, @utility, @layer, aturan mentah — menjadi pohon sintaks abstrak yang terdiri dari node ast.php (aturan gaya, at-rule, deklarasi). Direktif @import untuk modul virtual (tailwindcss, tailwindcss/preflight, …) dan jalur file diselesaikan dan disubstitusikan pada tahap ini.
Membangun sistem desain. theme.php menyelesaikan nilai tema (warna, jarak, breakpoint) dari blok @theme yang telah diurai beserta nilai default. design-system.php adalah registri pusat yang menghubungkan tema dengan pencarian utilitas dan varian yang ditentukan dalam utilities.php dan variants.php.
Memindai konten. candidate.php mengekstrak kandidat nama kelas dari konten yang diberikan (HTML, templat), lalu menguraikan setiap kandidat menjadi bagian-bagiannya — utilitas dasar, varian, modifier, nilai arbitrer, dan penanda important.
Mengompilasi. compile.php mengubah setiap kandidat menjadi node AST dengan mencarinya dalam sistem desain, lalu menerapkan varian dan modifier-nya. Kandidat yang tidak cocok dengan utilitas sungguhan akan dibuang.
Menyerialisasi dan mengoptimalkan. ast.php milik toCss() menelusuri pohon (dengan helper di walk.php) dan menghasilkan string CSS. Transformasi setara lightningcss di _tailwindphp/LightningCss.php diterapkan agar hasilnya cocok dengan keluaran TailwindCSS setelah tahap pascapemrosesan Rust.
Minifikasi. Saat minify diaktifkan, toCss() menghasilkan CSS yang diminifikasi selama serialisasi. _tailwindphp/CssMinifier.php mendukung tahap pemrosesan string mandiri tw::minify(). Lihat Caching & minifikasi.
Tata letak sumber
src/ mencerminkan TailwindCSS. Satu perubahan strukturalnya: TailwindCSS memiliki utilities.ts sebanyak 6,000+ baris, jadi dipecah menjadi src/utilities/ dengan satu file per kategori agar mudah dipelihara.
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
Padanan lightningcss
TailwindCSS menyerahkan pascapemrosesan CSS—nesting, penanganan media query, penyederhanaan nilai—kepada lightningcss, parser/transformer/minifier yang ditulis dalam Rust. PHP tidak dapat memuat pustaka Rust, jadi src/_tailwindphp/LightningCss.php mengimplementasikan ulang transformasi yang benar-benar digunakan TailwindPHP, sehingga menghasilkan keluaran yang identik byte demi byte untuk kasus yang dicakup rangkaian pengujian.
Transformasi yang dikonfirmasi mencakup:
| Transformasi | Fungsinya |
|---|---|
| Perataan nesting | Menyelesaikan selector & dengan aturan :is(…) dari referensi, lalu meratakan aturan yang bersarang (handleNesting() dalam ast.php, port dari tahap TailwindCSS); transformNesting menurunkan level nesting yang tersisa di bawah level pertama yang memuat deklarasi |
| Perataan at-rule bersyarat | Meratakan @media, @supports, @container, dan @starting-style yang bersarang di tempatnya, mempertahankan urutan sumber, dan hanya menggabungkan sibling yang berdekatan langsung dengan kondisi identik |
| Pengurutan deklarasi | Mengurutkan ulang deklarasi sesuai rantai penangan deklarasi lightningcss, sehingga properti mengikuti urutan referensi (reorderDeclarations) |
Penyederhanaan calc() |
Menyederhanakan ekspresi calc() (simplifyCalcExpressions) |
| Penghapusan nol di depan | 0.5 → .5 (normalizeLeadingZeros) |
| Spasi fungsi transform | Menormalkan spasi di dalam fungsi transform (normalizeTransformFunctions) |
| Normalisasi nilai grid | Menambahkan spasi di sekitar / pada nilai span, integer tanpa satuan → px untuk grid-template-* (normalizeGridValues) |
| Normalisasi warna | Menormalkan sintaks warna dan mengevaluasi color-mix() menjadi oklab() (normalizeColors, evaluateColorMix) |
| Pengutipan URL | url(./x.jpg) → url("./x.jpg") (normalizeUrlQuoting) |
| Prefiks vendor | Penambahan prefiks setara dengan Autoprefixer (addVendorPrefixes) |
File ini sengaja dikarantina di bawah _tailwindphp/ dan ditandai @port-deviation:replacement—file ini berfungsi sebagai pengganti dependensi eksternal, bukan mem-porting sumber TailwindCSS.
Penanda penyimpangan port
Setiap file implementasi memuat penanda @port-deviation:* dalam docblock yang menjelaskan di mana dan mengapa implementasi PHP menyimpang dari versi asli TypeScript. Tujuannya agar pembaca yang membandingkan PHP dengan sumber TailwindCSS tidak perlu bertanya-tanya apakah suatu perbedaan memang disengaja.
| Penanda | Arti |
|---|---|
@port-deviation:none |
Port langsung 1:1 tanpa penyimpangan signifikan |
@port-deviation:async |
PHP menggunakan kode sinkron alih-alih async/await |
@port-deviation:storage |
Struktur data berbeda (array PHP dibanding Map/Set JS) |
@port-deviation:types |
Anotasi PHPDoc alih-alih tipe TypeScript |
@port-deviation:sourcemaps |
Pelacakan source map dihilangkan |
@port-deviation:enum |
Konstanta PHP alih-alih enum TypeScript |
@port-deviation:errors |
Pendekatan penanganan error berbeda |
@port-deviation:replacement |
Implementasi PHP menggantikan pustaka eksternal (e.g. lightningcss) |
@port-deviation:helper |
Helper khusus PHP yang tidak ada di versi asli |
@port-deviation:performance |
Optimasi khusus PHP yang mempertahankan keluaran identik |
@port-deviation:omitted |
Seluruh modul/fitur tidak di-porting (di luar cakupan) |
Untuk penanda @port-deviation:performance dan cara memastikan kesetaraan, lihat Pengujian & performa.