Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve nasıl çözdüğümü anlatacağım. Tailwind CSS ile proje geliştirirken, sık kullandığım bileşenler için @apply direktifiyle custom class'lar oluşturuyordum. Hem okunabilirlik artıyor hem de tekrar önlüyordu, harika! Ta ki production build alıp da o güzelim butonlarımın, kartlarımın stilinin BUHAR OLUP UÇTUĞUNU görene kadar. Meğerse PurgeCSS, bu dinamik olarak oluşturduğum class'ları "kullanılmıyor" zannedip temizliyormuş. İlk gördüğümde gerçekten kafayı yemiştim.
Sorunun Tam Olarak Nerede?
Sorun şu: Tailwind, PurgeCSS'i (Tailwind v3'ten sonra content konfigürasyonu) kullanarak kullanılmayan stilleri temizler. Bu tarama işlemi sırasında, CSS dosyanızda @apply btn-primary gibi bir kullanım görür ama HTML, JS, Blade dosyalarınızda btn-primary diye bir class ismi arayamaz. Bulamayınca da "Bu class kullanılmıyor, kes at!" diyerek stil kurallarını final CSS'den siliyor. Laravel Mix veya başka bir build aracı kullanıyor olsanız da temel mantık aynı.
Çözüm: Laravel Mix ve PurgeCSS Özel Ayarları
Benim projemde build aracı olarak Laravel Mix kullanılıyordu. Çözüm, PurgeCSS'e "Bak, bu class'ları SAKIN ATMA, bunlar benim özel component'larım" diye özel olarak bildirmekten geçiyor. İşte benim webpack.mix.js dosyama eklediğim, işi çözen konfigürasyon:
Buradaki sihirli kısım safelist özelliği. standard anahtarında, RegEx (düzenli ifade) pattern'ları kullanarak hangi class'ların korunacağını belirtebiliyoruz. Benim örneğimde:
- /^btn-/: "btn-" ile başlayan TÜM class'lar (btn-primary, btn-secondary, btn-lg) korunacak.
- /^card-/: "card-" ile başlayan TÜM class'lar.
- /^badge-/: "badge-" ile başlayan TÜM class'lar.
Eğer belirli, tek bir class'ı korumak isterseniz, direkt string olarak da ekleyebilirsiniz: standard: ['btn-primary', 'scroll-lock']
Alternatif & Daha Basit Yöntem: Tailwind v3+ Content Bildirimi
Eğer projenizde Tailwind CSS v3 veya üzeri kullanıyorsanız (ki büyük ihtimalle öyle), işler daha da kolay. PurgeCSS artık Tailwind'in içine entegre ve tailwind.config.js[/COLOR] dosyasındaki content kısmından yönetiliyor. Bu durumda, özel class'larınızı kullandığınız dosya türlerini doğru belirtmek genellikle yeterli oluyor. Ama yine de sorun yaşarsanız, safelist özelliği burada da mevcut:
Bu yöntemde safelist daha gelişmiş. Pattern'ın yanı sıra variants (durum varyantları) da belirtebiliyorsunuz. Bu da responsive (lg:, md
veya state (hover:, focus
class'larınızı da güvence altına alıyor.
İşte benim kullandığım en temiz çözüm bu oldu. Artık @apply ile oluşturduğum tüm özel component class'larım production'da da sapasağlam duruyor. Siz Laravel Mix veya farklı bir build aracı (Vite, Webpack) ile benzer bir sorun yaşadınız mı? Ya da @apply kullanmak yerine farklı bir component yönetim stratejiniz var mı? Yorumlarda paylaşırsanız çok sevinirim!
Sorun şu: Tailwind, PurgeCSS'i (Tailwind v3'ten sonra content konfigürasyonu) kullanarak kullanılmayan stilleri temizler. Bu tarama işlemi sırasında, CSS dosyanızda @apply btn-primary gibi bir kullanım görür ama HTML, JS, Blade dosyalarınızda btn-primary diye bir class ismi arayamaz. Bulamayınca da "Bu class kullanılmıyor, kes at!" diyerek stil kurallarını final CSS'den siliyor. Laravel Mix veya başka bir build aracı kullanıyor olsanız da temel mantık aynı.
Benim projemde build aracı olarak Laravel Mix kullanılıyordu. Çözüm, PurgeCSS'e "Bak, bu class'ları SAKIN ATMA, bunlar benim özel component'larım" diye özel olarak bildirmekten geçiyor. İşte benim webpack.mix.js dosyama eklediğim, işi çözen konfigürasyon:
JavaScript:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
])
.options({
postCss: [
require('@fullhuman/postcss-purgecss')({
content: [
'./resources//.blade.php',
'./resources//.js',
'./resources//.vue',
],
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
safelist: {
standard: [/^btn-/, /^card-/, /^badge-/],
deep: [],
greedy: []
}
})
]
});
Buradaki sihirli kısım safelist özelliği. standard anahtarında, RegEx (düzenli ifade) pattern'ları kullanarak hangi class'ların korunacağını belirtebiliyoruz. Benim örneğimde:
- /^btn-/: "btn-" ile başlayan TÜM class'lar (btn-primary, btn-secondary, btn-lg) korunacak.
- /^card-/: "card-" ile başlayan TÜM class'lar.
- /^badge-/: "badge-" ile başlayan TÜM class'lar.
Eğer belirli, tek bir class'ı korumak isterseniz, direkt string olarak da ekleyebilirsiniz: standard: ['btn-primary', 'scroll-lock']
Eğer projenizde Tailwind CSS v3 veya üzeri kullanıyorsanız (ki büyük ihtimalle öyle), işler daha da kolay. PurgeCSS artık Tailwind'in içine entegre ve tailwind.config.js[/COLOR] dosyasındaki content kısmından yönetiliyor. Bu durumda, özel class'larınızı kullandığınız dosya türlerini doğru belirtmek genellikle yeterli oluyor. Ama yine de sorun yaşarsanız, safelist özelliği burada da mevcut:
JavaScript:
// tailwind.config.js
module.exports = {
content: [
'./resources//.blade.php',
'./resources//.js',
'./resources//.vue',
// Özel class'larınızı içeren CSS dosyanızı da ekleyin!
'./resources/css//.css',
],
safelist: [
'btn-primary',
'btn-secondary',
{ pattern: /^bg-/, variants: ['hover', 'focus'] }, // bg-red-500, hover:bg-red-700 gibi
{ pattern: /^text-/, variants: ['lg'] }, // text-xl, lg:text-2xl gibi
],
theme: {
extend: {},
},
plugins: [],
}
Bu yöntemde safelist daha gelişmiş. Pattern'ın yanı sıra variants (durum varyantları) da belirtebiliyorsunuz. Bu da responsive (lg:, md
İşte benim kullandığım en temiz çözüm bu oldu. Artık @apply ile oluşturduğum tüm özel component class'larım production'da da sapasağlam duruyor. Siz Laravel Mix veya farklı bir build aracı (Vite, Webpack) ile benzer bir sorun yaşadınız mı? Ya da @apply kullanmak yerine farklı bir component yönetim stratejiniz var mı? Yorumlarda paylaşırsanız çok sevinirim!