سلام دوستان! احتمالا اگر لاراول کار هستین اسم TALL Stack به گوشتون خورده. توسعه دهنده های لاراول همیشه سعی داشتن که شما رو توی یه اکوسیستم باحال و خفن قرار بدن که هم شما از کدنویسی لذت ببرین هم بتونین کدهای بقیه توسعه دهنده ها رو خیلی راحت بفهمین و حتی کدهاتون رو با اونها به اشتراک بزارین. یجورایی دوست دارن یه نظمی رو بین برنامه نویسایی که توی این حوزه هستن ایجاد کنن.
در واقع شما از یه سری ابزار برای Backend و Frontend سایت خودتون استفاده میکنین که خیلی از توسعه دهنده های دیگه هم دقیقا از همون ابزار ها استفاده میکنن و خیلی راحت تر میتونین با هم ارتباط برقرار کنین. (خودشون بهش میگن Stack!)
یکی از این استک ها که جدیدا خیلی بین برنامه نویس ها محبوب شده TALL Stack هستش؛ مخفف Tailwind Alpine Livewire Laravel. چهارتا غول که میتونن برنامه نویسی وب رو برای شما خیلی لذت بخش تر کنن!
خب بریم دونه دونه این ابزار ها رو با هم بررسی کنیم و درنهایت یاد بگیریم که چطوری میتونیم وارد این استک بشیم و خودمون رو جزو بچه های TALL Stack بدونیم ?
طبیعتا لاراول معرف حضور همگی هست! یه فریمورک بر پایه PHP که خودش رو به توسعه دهنده ها ثابت کرده و از حدود 10 سال پیش تا الان به محبوبیت خیلی زیادی بین توسعه دهنده ها رسیده. پس هسته اصلی TALL شد خود فریمورک لاراول عزیز.
وقتی که وبسایت رسمی Livewire رو باز میکنیم یه سری دیالوگ جالب نوشته:
building dynamic interfaces simple, without leaving the comfort of Laravel.
خیلی ساده بخوام بگم ساختن وبسایت های داینامیک، بدون ترک راحتی لاراول! Livewire در اصل یه فریمورک Full-Stack هست که بر روی لاراول سوار میشه و یجورایی یه پل میزنه بین Frontend و Backend سایت شما. خیلی از کارها مثل صفحه بندی داده ها، لایک کردن مطالب، ارسال نظر و... که اگر بخوایم با فریمورک هایی مثل vue و react و... پیاده کنیم کارمون یخورده سخت میشه رو لایووایر خیلی راحت با همون کدهایی که توی بک اند مینویسیم برامون هندل میکنه. نه نیازی به نوشتن API داریم نه هندل کردن اون توی فرانت و نه هیچ کار دیگه. فقط نوشتن یه تابع توی لایووایر و کال کردن اون توی فرانت ?
تکنولوژی ای که توی چند وقت اخیر خیلی سر و صدا کرده و عملا ما رو از نوشتن CSS خام بی نیاز میکنه و سرعت توسعه ما رو چند برابر میکنه. هرکاری که توی CSS مجبور بودین کلی کد براش بنویسین تبدیل شده به یه سری کلاس های از پیش تعریف شده توی Tailwind، استفاده کنین و لذت ببرین ❤️
وقتی از توسعه وب صحبت میکنیم غیر ممکنه سر و کارمون به JavaScript عزیز نیوفته. یه فریمورک خیلی سبک و جذاب که کارهای خسته کنندهای که به صورت دستی توی جاوا اسکرپت (یا حتی jQuery) انجام میدادیم رو خیلی برای ما راحت تر و لذت بخش تر میکنه. ترکیب این دوستمون با Tailwind و کامپوننت های Blade خیلی چیز جالبی در میاد.
خب حالا که همه این تکنولوژی های TALL رو معرفی کردیم بریم سراغ اینکه چجوری همه این ها رو روی یه پروژه لاراول سوار کنیم و از قابلیت هاشون لذت ببریم.
خب اول از همه بیاین یه پروژه جدید لاراول نصب کنیم، من اسم پروژه رو tall-stack میزارم:
composer create-project laravel/laravel tall-stack
خیلی راحت با این دستور کامپوزر میتونیم آخرین نسخه لاراول رو روی سیستم خودمون نصب کنیم. با دستور زیر میتونیم اپلیکیشن لاراولی خودمون رو روی لوکال ببینیم
php artisan serve
خب خیلی راحت لاراول رو نصب کردیم، حالا بریم سراغ بقیه بچه ها. اول از لایووایر شروع میکنیم
برای نصب لایووایر باید پکیج اون رو به پروژه خودمون اضافه کنیم
composer require livewire/livewire
برای اینکه لایووایر بتونه توی فرانت به درستی کار کنه باید استایل ها و اسکریپت هاش رو به صفحه خودمون اضافه کنیم. قبل از بسته شدن تگ head دایرکتیو (directive) زیر رو اضافه میکنیم تا استایل ها لود بشن:
@livewireStyles
و برای لود شدن کدهای جاوا اسکریپت لایووایر دایکتیو زیر رو به قبل از بسته شدن تگ body اضافه میکنیم
@livewireScripts
بیاین با هم یه کامپوننت ساده شمارنده با لایووایر بسازیم تا مطمعن شیم داره به درستی کار میکنه. لایووایر دستورات آرتیسان خوبی رو بهمون میده برای استفاده از قابلیت هاش. با دستور زیر یه کامپوننت به اسم Counter ایجاد میکنیم
php artisan make:livewire Counter
با این کار یه فایل ویو برای این کامپوننت توی پوشه Resources/views/livewire و یه فایل php برای تعامل با این کامپوننت توی پوشه app/Http/Livewire ایجاد میشه. دوتا فایل که قراره کلی کار ما رو راحت کنن کنار همدیگه.
اول از همه بریم توی فایل ویو و کدهای زیر رو که یه متن برای نمایش مقدار شمارنده، یک دکمه برای افزایش، یک دکمه برای کاهش و یک دکمه برای ریست هست رو داخلش قرار میدیم. (استایل دهی رو هم جلوتر انجام میدیم با هم)
<div> <button>+</button> <span>0</span> <button>-</button> <button>Reset</button> </div>
خب برای اینکه این کامپوننت توی صفحه نمایش داده بشه کافیه اون رو به صورت زیر توی blade خودمون استفاده کنیم.
<livewire:counter/>
کل کدهای welcome.blade.php که صفحه اصلی من هستش به این صورته:
<!doctype html> <html lang="en"> <head> <title>TALL Stack</title> @livewireStyles </head> <body> <div> <livewire:counter/> </div> @livewireScripts </body> </html>
خب حالا بریم سراغ کنترلر این کامپوننت لایووایر توی پوشه app/Http/Livewire. طبیعتا یه متغیر برای ذخیره مقدار شمارنده نیاز داریم با سه تا تابع برای افزایش، کاهش و ریست.
اول از همه یه property روی کلاس Counter ایجاد میکنیم و مقدار اولیه اون رو برابر با صفر قرار میدیم.
public int $counter = 0;
حواستون باشه که این property حتما باید public باشه تا بتونیم به صورت اتوماتیک از اون توی ویو خودمون استفاده کنیم.
بعد دوتا تابع تعریف میکنیم برای کاهش و افزایش مقدار این متغیر:
public function increment() { $this->counter++; } public function decrement() { $this->counter--; }
توی لایووایر به همین راحتی میتونیم دوتا action ایجاد کنیم که متغیرهای ما رو به دلخواهمون تغییر میدن و این مقدار به صورت خودکار توی ویو آپدیت میشه! بدون هیچ کار اضافه ای.
در مرحله سوم هم تابع ریست کردن شمارنده رو مینویسیم
public function resetCounter() { $this->reset('counter'); // OR $this->counter = 0; }
این کار رو به دو روش میتونیم انجام بدیم؛ راه اول اینه که مثل متد increment مقدار متغیر رو به صورت دستی برابر با صفر قرار بدیم (که به صورت کامنت نوشتم). راه دوم و بهتر اینه که از تابع reset خود لایووایر استفاده کنیم تا به صورت اتوماتیک اون رو به مقدار اولیه برگردونه. شاید اینجا زیاد تفاوتی نداشته باشه، ولی توی کامپوننت های پیچیده تر خیلی به کارمون میاد این تابع reset.
خب حالا که کارمون با کنترلر این کامپوننت تموم شد بریم و این توابع رو توی ویو خودمون استفاده کنیم.
<div> <button wire:click="decrement">-</button> <span>{{ $counter }}</span> <button wire:click="increment">+</button> <button wire:click="resetCounter">Reset</button> </div>
برای اینکه یه تابعی که توی کنترلر لایووایر نوشتیم رو بتونیم از توی ویو کال کنیم، کافیه از wire:click استفاده کنیم و اسم اون تابع رو بهش پاس بدیم! بقیه کارها رو خود لایووایر هندل میکنه. برای سه تا دکمه ای که داشتیم من همینکار کردم.
حالا که دکمه های خودمون رو به توابع (یا به اصطلاح همون action) های لایووایر وصل کردیم، باید مقدار شمارنده رو هم توی سایت نمایش بدیم. برای اینکار خیلی راحت میتونیم مثل یه متغیر ساده که قبلا توی کنترلر ها پاس میدادیم و توی ویو ازش استفاده میکردیم؛ کافیه که از {{ $counter }} استفاده کنیم تا این مقدار هم به درستی نمایش داده بشه.
نکته جالب کار هم همینجاست، متغیرهایی که توی لایووایر داریم مثل متغیرهایی که از توی کنترلر ها پاس میدادیم نیست که مرده باشن! این متغیرها وقتی مقدارشون تغییر کنه به صورت خودکار توسط لایووایر آپدیت میشن و ویو ما هم به صورت خودکار آپدیت میشه!
خب حالا نتیجه کار رو میتونیم توی مرورگر با اجرای دستور محبوب
php artisan serve
روی پورت 8000 ببینیم. (سورس کامل رو هم در انتها براتون قرار میدم)
یه نکته ای رو هم همینجا بهتون بگم راجع به لایووایر. احتمال زیاد وقتی که با این شمارنده کار کردین متوجه شدین که Real-Time نیست داستان، یجورایی لگ داره. این داستان برمیگرده به ماهیت لایووایر که اصلا برای همچین کارهایی مثل یک شمارنده ساخته نشده!
وقتی که شما یک اکشن لایووایر رو کال میکنین یک درخواست به سرور ارسال میشه، توی سرور مقدار این متغیر تغییر میکنه، مقدار جدید برمیگرده به لایووایر و خودش ویو ما رو آپدیت میکنه. یعنی عملا این داستان سمت فرانت هندل نمیشه که بخوایم یه شمارنده Real-Time داشته باشیم.
با این اوصاف یعنی لایووایر به درد نمیخوره؟ ? به هیچ وجه اینطور نیست. هر تکنولوژی ای وقتی در جای خودش استفاده بشه خیلی هم میتونه کمک کننده باشه. به عنوان مثال صفحه بندی و سرچ اطلاعات؛ بدون لایووایر شما برای اینکه به عنوان مثال 2000 داده رو صفحه بندی کنی و بخوای قابلیت سرچ هم به کاربر بدی بدون اینکه کاربر مجبور باشه صفحه رو ریفرش کنه؛ باید برید سراغ فریمورک های جاوااسکریپی و نوشتن API و... که نیازی به توضیح نداره حجم کار. اما توی لایووایر این کار 1 دقیقهست! چجوریش دیگه از حوصله این مقاله خارجه، یه لینک میزارم اگه دوست داشتین بررسی کنین: لینک
برای داشتن یه چارچوب کاری مدرن طبیعتا نیاز به یه راه جدید برای نوشتن CSS قدیمی و وقت گیر داشته باشیم. اینجاست که Tailwind به کارمون میاد و سرعت کارمون رو خیلی بالا میبره.
برای نصب Tailwind طبق مستندات خود کتابخونه اول از همه باید خود tailwind و postcss و autoprefixer رو از طریق npm نصب کنیم
npm install -D tailwindcss postcss autoprefixer
بعد از اون با دستور زیر کانفیگ پیشفرض tailwind رو ایجاد میکنیم
npx tailwindcss init -p
حالا توی فایل کانفیگ مشخص میکنیم که فایل های ورودی ما کجان. یعنی توی چه فایلهایی قراره از کلاس های تیلویند استفاده کنیم تا بانلدر ما بتونه اونها رو به کدهای css خام تبدیل کنه و در اختیار ما قرار بده.
توی فایل tailwind.config.js قسمت کانتنت میتونیم نوع فایلهامون رو مشخص کنیم
content: [ "./resources/**/*.blade.php" ],
بهش گفتم که برو توی پوشه resources، بعد ** به معنای "هر پوشه ای" هست؛ یعنی برو توی تک تک پوشه های اونجا (هم خود پوشه ها هم پوشه های داخل پوشه ها تا اخر) و هرچی فایل که با پسوند .blade.php هست رو پیدا کن و برای من بیلد بگیر.
طبیعتا اگه از فایل های vue یا js یا jsx استفاده میکنین هم میتونین به همین صورت اونها رو مشخص کنین. حتی اگه فایل های blade تون توی پوشه متفاوتی هست میتونین اینجا براش مشخص کنین (مثلن توی پوشه مخصوص module ها)
خب حالا باید یه فایل CSS خام داشته باشیم برای چی؟ اول اینکه که بتونیم اون رو به فایل blade خودمون لینک کنیم. دوم اینکه tailwind استایل هایی که بیلد میگیره رو اونجا اعمال کنه. سوم اینکه استایل های پایه tailwind رو هم اونجا اعمال کنیم تا تیلویند بتونه درست کار کنه. برای اینکار توی resources/css/app.css من ایمپورت های زیر رو اضافه میکنم
@tailwind base; @tailwind components; @tailwind utilities;
حالا باید این فایل css رو به صفحه خودمون اضافه کنیم. من از Vite استفاده میکنم که کار رو خیلی برامون راحت کرده. قبل از بسته شدن تگ Head:
@vite('resources/css/app.css')
دیگه خودش تشخیص میده که فایل ورودی ما توی resources هستش و توی پروداکشن قراره از فایلی که توی پوشه پابلیک بیلد گرفته میشه استفاده کنه! این هم از زیبایی های Vite.
خب بریم یه سری استایل به اون Counter خودمون بدیم تا مطمعن شیم درست کار میکنه. (لیست کامل استایل ها رو میتونین توی مستندات Tailwind چک کنین طبیعتا)
کل کار tailwind با استفاده از کلاس ها انجام میشه. به کلاس هایی که دادم دقت کنین، مطمعنم که میتونین معنی هر کلاسی که اعمال شده رو بفهمید.
فایل counter.blade.php:
<div class="flex flex-col items-center justify-center p-4 gap-4"> <div class="flex items-center gap-12"> <button wire:click="decrement" class="bg-amber-400 text-4xl px-2 text-white rounded-md hover:bg-amber-500 transition-all hover:shadow-md" >-</button> <span class="bg-gray-300 p-5 rounded">{{ $counter }}</span> <button wire:click="increment" class="bg-amber-400 text-4xl px-2 text-white rounded-md hover:bg-amber-500 transition-all hover:shadow-md" >+</button> </div> <button wire:click="resetCounter" class="bg-red-500 text-2xl px-2 text-white rounded-md hover:bg-red-600 transition-all hover:shadow-md" >Reset</button> </div>
برای اینکه این کلاس ها اعمال بشن کافیه دستور npm run dev روی توی ترمینال اجرا کنین تا توی حالت watch قرار بگیره. البته اگه از vite استفاده میکنین خودش به صورت اتوماتیک وقتی تغییری اعمال میکنین ریلود میکنه صفحه رو بعد از اجرای این دستور :)
خب حالا صفحه رو چک کنین و استایل ها رو ببینید که بدون حتی نوشتن یک خط css پیاده شده.
خب حالا که نمیخوایم از فریمورک های بزرگ (و صد البته سنگین) جاوا اسکریپی استفاده کنیم، لاراول به ما پیشنهاد میده که از یه فریمورک خیلی مینیمال و سبک به اسم AlpineJS استفاده کنیم. بنظرم ایده کار رو از تیلویند گرفته این دوستمون. کارش اینه که مث تیلونید که استایل میدادی بدون css، خب، اسکریپت مینویسی بدون اینکه مستقیما جاوا اسکریپت بنویسی ?
بریم همین counter ساده ای که با لایووایر نوشتیم رو با آلپاین بازنویسی کنیم و اون رو بزاریم برای کارهای بزرگتر و سنگین تر. (این رو هم بگم که Alpine با لایووایر خیلی خوب مچ میشه و میتونن یه سری کارهای باحال رو با هم انجام بدن که توی این لینک میتونین بخونین راجع بهش)
خب اول از همه بریم آلپاین رو با استفاده از npm نصب کنیم:
npm install alpinejs
بعد آلپاین رو به فایل JS خودمون اضافه میکنیم و اون رو به فایل blade خودمون لینک میکنیم:
توی فایل app.js:
import Alpine from 'alpinejs' window.Alpine = Alpine Alpine.start()
با اینکار موتور Alpine شروع به کار میکنه. یادتون باشه که این فایل app.js رو به فایل blade خودتون هم اضافه کنین. قبل از بسته شدن تگ body:
@vite('resources/js/app.js')
خب حالا میتونیم از قابلیت های alpine عزیز استفاده کنیم.
آلپاین کلا بر اساس دایرکتیو ها کار میکنه. مهمترین دایرکتیوی که توی آلپاین داریم x-data هستش. آلپاین فقط توی تگ هایی کار میکنه که داخل یه x-data قرار گرفته باشن و کاری به بقیه نداره.
توی فایل counter.blade.php که قبلا ساخته بودیم توی بالاترین تگ div من x-data رو اضافه میکنم و متغیر count رو تعریف میکنم و مقدار اون رو برابر با 0 قرار میدم:
<div x-data="{ count: 0 }" ... > ... </div>
به همین راحتی یه متغیر تعریف کردیم. حالا چجوری مقدارش رو نمایش بدیم؟ با دایرکتیو x-text! این دایرکتیو رو به span خودمون اضافه میکنیم و داخلش چیزی نمینویسیم:
<span x-text="count" ></span>
حالا باید به جای تمام wire:click هایی که داشتیم از دایرکتیو x-on:click استفاده کنیم.
// for decrement x-on:click="count--" // for increment x-on:click="count++" // for reset x-on:click="count = 0"
این دایرکتیو ها رو به جای ایونت های کلیک لایووایر قرار بدین و خیلی راحت از alpine لذت ببرین. امیدوارم alpine نظرتون رو جلب کرده باشه تا یه سر به داکیومنتش بزنین تا ببینین دیگه چه کارهایی از دستش بر میاد.
خب این هم از مقاله TALL Stack که خودم به شخصه خیلی این ستاپ اولیه رو دوست دارم.
سورس این کدهایی که نوشتیم رو میتونین توی این لینک گیتهاب ببینین.
امیدوارم این مقاله به کارتون اومده باشه. خوشحال میشم نظرتون رو برام بنویسین ❤️