Episode ini membahas migrasi proyek besar ke Tailwind: teknik incremental dari CSS tradisional, pertimbangan monorepo untuk berbagi config dan design token, serta strategi rollback dan pengujian kompatibilitas yang aman.

Migrasi basis kode besar ke Tailwind adalah proyek bertahun-tahun, bukan akhir pekan. Episode 21 membahas strategi yang realistis: konversi incremental komponen demi komponen, arsitektur monorepo untuk berbagi config dan token, serta rollback dan pengujian kompatibilitas agar perjalanan tetap aman.
Pola pikir yang benar: migrasi bukan "ganti semua CSS hari ini", melainkan "kurangi ketergantungan pada CSS lama secara terus-menerus sampai titik di mana menghapusnya menjadi murah". Setiap langkah harus bisa dibalik, terukur, dan tidak mengganggu pengguna.
Kunci keamanan: semua komponen baru langsung memakai Tailwind. Ini menghentikan pertumbuhan CSS lama sejak hari pertama.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -pSetelah itu output.css dari Tailwind di-import berdampingan dengan stylesheet lama. Tidak ada yang dihapus — hanya ditambahkan.
Konversi satu komponen pada satu waktu. Pola yang direkomendasikan: pindahkan utility langsung ke markup, lalu hapus aturan CSS lama setelah visual verified:
<!-- Sebelum -->
<button class="btn btn-primary">Simpan</button>
<!-- Sesudah -->
<button class="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
Simpan
</button>Untuk komponen yang CSS-nya kompleks, terjemahkan dulu ke @apply di layer components agar transisi bertahap — lalu sisihkan nanti bila markup sudah bersih.
Jalankan dua versi tampilan bersamaan memakai feature flag. Pengguna tertentu mendapat versi Tailwind, sisanya versi lama — bandingkan metrik dan bug report sebelum beralih penuh:
const useTailwind = featureFlags.isEnabled(user.id, "ui-tailwind");
const variant = useTailwind ? "tailwind" : "legacy";featureFlags.isEnabled(user.id, "ui-tailwind") memberi jalur untuk menguji perubahan pada sebagian pengguna, sambil menjaga sisa traffic tetap di versi stabil.
Di monorepo, config dan token dibagikan antar paket tanpa duplikasi. Susun preset di paket tersendiri:
packages/
ui/ -> komponen bersama
tailwind-preset/ -> token + plugin bersama
apps/
web/ -> aplikasi utama
admin/ -> aplikasi adminPreset dikonsumsi semua aplikasi:
module.exports = {
presets: [require("@org/tailwind-preset")],
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"../../packages/ui/src/**/*.{js,ts,jsx,tsx}",
],
};Perhatikan content mencakup ../../packages/ui/src/**/* — tanpa ini, class di komponen bersama tidak pernah dibangkitkan. Pola content: ["../../packages/ui/src/**/*"] adalah detail paling sering terlewat di setup monorepo.
Migrasi besar butuh jalan pulang. Beberapa jaring pengaman:
Contoh pengujian kompatibilitas sederhana:
npx playwright test --project=chromium --project=firefox --project=webkitnpx playwright test --project=chromium menjalankan seluruh suite di tiga engine browser sekaligus. Jika tampilan baru lolos di semua project dan metrik tidak menurun, komponen dianggap siap.
Warning
Jangan pernah menghapus CSS lama secara besar-besaran dalam satu commit. Baru hapus per komponen setelah versi Tailwind-nya lolos visual test dan berjalan stabil di produksi selama beberapa waktu. Perubahan kecil yang sering lebih aman daripada lompatan besar.
Episode 21 membuat migrasi besar terasa aman: komponen baru langsung memakai Tailwind, konversi per komponen dengan flag, arsitektur monorepo untuk berbagi preset, serta rollback dan pengujian kompatibilitas yang terus menerus.
Inti yang harus dibawa pulang:
content harus mencakup path ke paket komponen bersama.Di episode 22 selanjutnya — episode terakhir — kita akan membahas production hardening & best practices: checklist final build-size, CSP, SRI, caching, dan audit aksesibilitas, menghindari injeksi runtime Tailwind, serta mendokumentasikan konvensi untuk tim.