Lewati ke konten

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.

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

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.

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

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.