Alpine.js: küçük etkileşimler için hafif bir seçim
Alpine.js'i ne zaman seçmeli, ne zaman seçmemeli? Tam framework gerektirmeyen arayüz ihtiyaçları için doğru ölçeği tartışıyorum.
Bir Blade şablonunda dropdown menü açmak istiyorsunuz. Ya da bir accordion sekme. Ya da form alanını koşullu göstermek. Bu işler için Vue ya da React kurmak araç-görev uyumsuzluğunun ders kitabı örneği. jQuery yazmak da 2020’de iyi hissettirmiyor. Alpine.js bu boşluğu dolduran, HTML’e yapışık kalan bir kütüphane.
Alpine.js (alpinejs.dev), Tailwind CSS’in JavaScript karşılığı olarak tanıtılıyor. HTML attribute’larını kullanarak doğrudan şablonda reaktif davranış tanımlamanızı sağlıyor. Script dosyası ~7KB, zero build step, NPM zorunlu değil.
Temel kullanım
Bir dropdown örneği:
<div x-data="{ open: false }">
<button @click="open = !open">Menü</button>
<ul x-show="open" @click.away="open = false">
<li>Profilim</li>
<li>Ayarlar</li>
<li>Çıkış</li>
</ul>
</div>
x-data bileşenin state’ini tanımlıyor. @click event listener. x-show görünürlüğü duruma bağlıyor. @click.away Alpine’ın event modifier’ı — bileşenin dışına tıklandığında kapanıyor. Bunların tamamı saf HTML attribute’ı; JavaScript dosyası açılmıyor.
Koşullu form alanları
Karmaşık form senaryolarında Alpine gerçekten değer katıyor:
<div x-data="{ type: 'individual' }">
<select x-model="type">
<option value="individual">Bireysel</option>
<option value="corporate">Kurumsal</option>
</select>
<div x-show="type === 'corporate'">
<label>Şirket Adı</label>
<input type="text" name="company_name">
</div>
<div x-show="type === 'individual'">
<label>T.C. Kimlik No</label>
<input type="text" name="tc_no">
</div>
</div>
x-model two-way binding yapıyor. Seçim değiştiğinde ilgili alan otomatik gösteriliyor ya da gizleniyor. Hiç JavaScript yazmadan.
Bu senaryo, tam anlamıyla Alpine’ın tatlı noktası. Formda koşullu alanlar genellikle küçük ama can sıkıcı bir jQuery karmaşası gerektirirdi; Alpine ile birkaç satır HTML attribute’ına iniyor.
Alpine vs. Vue: ölçek farkı
Alpine ile Vue arasındaki fark araç kalitesi değil, ölçek. Vue bir framework; bileşen sistemi, router, state management, build adımı. Alpine bunların hiçbirini sunmuyor çünkü sunmak zorunda değil.
Şablonun içinde birkaç bağımsız etkileşim varsa Alpine doğru seçim. Sayfalar arası durum taşımanız gerekiyorsa, bileşenler karmaşık iletişim kuruyorsa, build adımı zaten varsa Vue ya da React daha uygun.
Benim pratiğim şöyle: Laravel + Blade projelerinde arayüz etkileşimi alpine ile başlıyor. Bir sayfa Vue uygulamasına dönüşmeye başladığında o sayfayı Vue ile yazıyorum. İkisi aynı projede yan yana yaşayabiliyor.
Livewire ile birlikte kullanmak
Alpine ile Livewire kombinasyonu iyi çalışıyor. Livewire sunucu tarafını yönetiyor, Alpine istemci tarafındaki anlık tepkileri karşılıyor. Livewire’ın round-trip’ini beklemeden bir modal’ı açmak ya da bir form alanını geçici saklamak için Alpine yeterli.
<div x-data="{ modalOpen: false }" wire:ignore.self>
<button @click="modalOpen = true">Düzenle</button>
<div x-show="modalOpen" x-transition>
<livewire:edit-form :item="$item" />
<button @click="modalOpen = false">Kapat</button>
</div>
</div>
wire:ignore.self Livewire’ın bu bileşenin dışını DOM farklamasından dışlamasını sağlıyor.
Pratikte en çok işe yarayan kombinasyon şu: kullanıcı bir düğmeye tıklıyor, Alpine modal’ı anında açıyor, Livewire arka planda veriye erişiyor. Kullanıcı gecikme hissetmiyor; siz de istemci tarafına ayrı bir state management katmanı eklemek zorunda kalmıyorsunuz.
Sınırlar
Alpine’ın sınırları var ve bunları bilmek önemli. Global durum yönetimi yok; iki ayrı x-data bloğu arasında doğrudan veri paylaşımı mümkün değil (her biri kendi kapsamında). TypeScript desteği yok. Karmaşık asenkron işlemler için fetch + Alpine birleşimi hızla okunaksızlaşabiliyor.
Bir kenar durum da şu: x-data içinde çok fazla mantık biriktirmeye başlarsanız Alpine, jQuery’nin dağınık $(document).ready() bloklarına dönüşüyor. Şablon içine iş mantığı sızdırmak yerine x-data="sepet()" şeklinde bir Alpine component tanımı yapıp mantığı ayrı bir JS dosyasına taşımak daha temiz kalıyor.
Bu sınırları göz ardı edip her yerde Alpine kullanmaya çalışmak, jQuery döneminin hatalarını farklı bir sözdizimi ile tekrar etmek olur. Araç doğru görev eşleşmesinde çok temiz; yanlış görevde acı çektirir.
Alpine.js için kararım şu: jQuery’nin yerini almak için değil, Vue’nun her projeye sokulmaması için. Tam framework gerekmeden bir arayüze hareket katmak istediğimde ilk denediğim araç haline geldi. Küçüklüğü güçlü yanı, aynı zamanda sınırı.