شروع کار با گالپ (Gulp)

تلاش برای تسلط بر یک ابزار، بدون آنکه بدانیم واقعاً به چه دردی خواهد خورد یا چه مشکلی را دقیقاً از ما حل می‌کند، کاری بیهوده است. خیلی از ما در طول توسعه نرم‌افزار مجبور به انجام کارهای تکراری بوده‌ایم. کارهایی که ربطی به خلاقیت در توسعه نداشته و اغلب کسل‌کننده و ملالت‌بار هستند. به لیست زیر توجه کنید، احتمالاً برای شما هم آشنا هستند:

  • ساختن و کوچک کاری فایل‌های حجیم کتابخانه‌های جاوا اسکریپت
  • ادغام فایل‌های استایل (css) و ساخت یک فایل از آن‌ها
  • اجرای تک‌تک آزمون‌هایی که برای کد نوشته‌شده‌اند
  • کامپایل فایل‌های دستوری Less/Sass و تولید خروجی مناسب
  • کوچک کاری و درهم‌ریزی کدها
  • تغییر در ابعاد و مشخصات تصاویر
  • نسخه‌برداری از فایل‌های نهایی در یک پوشه دیگر برای ترخیص نهایی
  • به‌روزرسانی شاخص نسخه نرم‌افزار
  • و صدها کار ریز و درشت دیگر

در انتهای هر چرخۀ توسعه و در هر بار ترخیص بستۀ جدید از نرم‌افزار، همۀ کارهای فوق باید تک‌تک انجام شوند! کار تکراری و خسته‌کننده‌ای است! نه؟

اگر کاری هست که از انجام دادنش متنفری [ولی مجبور هستی که انجامش بدی]، خودکارش کن!

سپردن کارهای کسل‌کننده ولی ضروری به یک ابزار قدرتمند، نشانۀ هوش یک برنامه‌نویس است. هوشی که نتایجی مانند، بالا رفتن سرعت توسعه، کاهش ریسک خطای انسانی، کاهش احتمال فراموشی فرآیندهای مهم، تمرکز بیشتر بر خلاقیت، ارتقاء کیفیت محصول نهایی و بسیاری دیگر را برای توسعه‌دهندگان و مالکان محصول به ارمغان خواهد آورد.

یکی از این ابزارهای قدرتمند در این زمینه، که امروزه با اقبال توسعه‌دهندگان و برنامه نویسان همراه شده، ابزار Gulp.js است. تفاوت عمدۀ این ابزار با ابزارهای مشابه مانند Grunt ،Broccoli یا Brunch، وابستگی به Node.js و استفاده از فرآیند زنجیره‌ای pipe آن است. به این مفهوم که ابزار گالپ، امکان زنجیر کردن تکالیف مختلف و نگهداری آن‌ها در حافظۀ موقت رایانه را فراهم کرده است. دیگر نیاز نیست نگران تعداد وظایفی که تعریف می‌شوند و یا حجم خواندن و نوشتن بر روی دیسک سخت در هر بار اجرا باشید. این مزیت باعث افزایش سرعت و چابکی پردازش خواهد شد زیرا همۀ وظایفِ تعریف‌شده، به‌یک‌باره بر روی حافظه اجرا و در پایان، خروجی بر روی دیسک سخت منتقل می‌شود.

از طرفی همان‌طور که توسعه‌دهندگان این ابزار بیان می کنند، گالپ صرفاً یک task runner نیست بلکه یک build system helper است، که به‌خودی‌خود یک مزیت به‌حساب می‌آید.

مبانی و ملزومات ابزار Gulp

به‌منظور بهره‌برداری از ابزار گالپ، به دو فایل package.json و gulpfile.js نیاز خواهیم داشت. قبل از هر چیز نیاز به Node.js دارید، چون Gulp به‌عنوان ماژولی از آن اجرا می‌شود. نصب Node.js بسیار ساده است کافی است به وب‌سایت آن مراجعه کرده و دستورات را دنبال کنید. پس از نصب Node.js و ابزار مدیریت بسته آن (npm)، ترمینال خود را اجرا کرده و دستور زیر را صادر کنید:

نصب gulp

دستور فوق به npm می‌گوید که ابزار دستوری گالپ را به‌صورت عمومی (سوئیچ g–) نصب کند.

نکته: بستۀ gulp-cli تنها شامل دستوران خط فرمان Gulp است.

مرحلۀ بعدی ایجاد فایل package.json در ریشۀ پوشۀ پروژه است. به پوشۀ پروژه رفته و دستور زیر را اجرا کنید:

$ npm init -f

این دستور یک فایل با عنوان package.json و با پیکربندی پیش‌فرض و بدون سؤال (سوئیچ f–)، ایجاد می‌کند:

package.json gulp

اگر دستور init را بدون سوئیچ f– اجرا کنید، سؤالاتی مربوط به پروژه برای پر کردن فایل package.json از شما پرسیده خواهد شد که می‌توانید آن‌ها را مطابق میل تغییر دهید تا درنهایت درون فایل نوشته شوند.

فایل package.json قابلیت پیکربندیِ وابستگی‌ها و تنظیم عمومی پروژه را در اختیار شما قرار می‌دهد که درنهایت برای اجرا صحیح پروژه، توسط npm مورداستفاده قرار خواهد گرفت. این فایل تضمین خواهد کرد که پروژۀ شما همواره شامل ابزارها و فایل‌های لازم برای اجرای صحیحش باشد.

پس‌ازآن لازم است که گالپ را به‌عنوان یک وابستگی جدید در پروژۀ خود نصب و پیکربندی کنید. شاید سؤال کنید که مگر قبل‌تر این کار را انجام نداده‌ایم؟ بله، قبل از این ابزار gulp-cli را نصب‌کرده‌اید تا بتوانید از دستورات خط فرمان آن به صورت عمومی استفاده کنید. ولی اگر بخواهید تکالیفی را در سطح پروژه بر عهدۀ این ابزار قرار دهید باید آن را به‌عنوان یک ابزار وابسته به پروژه معرفی و پیکربندی کنید تا در تمام مراحل همراه پروژۀ شما باشد. به‌عبارت‌دیگر با این کار پروژۀ خود را برای اجرای موفق به این ابزارها وابسته می‌کنید که بدون آن‌ها پروژه یا به‌طورکلی کار نمی‌کند یا به‌صورت ناقص عملیاتی خواهد شد.

بستۀ گالپ دارای دو بخش است. بخشِ دستورات خط فرمان برای اجرای فرمان‌های داخلی و بخشِ توابع جاوا اسکریپت که درون پروژه و برای اجرای تکالیف و پیکربندی‌های ویژه از آن‌ها استفاده می‌کنید. توسعه‌دهندگان گالپ برای تفکیک این دو بخش و افزایش بهره‌وری بخش اول یعنی دستوراتِ عمومیِ خط فرمان گالپ را در بسته‌ای مجزا به نام gulp-cli که به آن Gulp Command Line Interface می‌گویند، فراهم آورده‌اند.

برای این منظور، درحالی‌که همچنان در پوشۀ اصلی پروژه هستید، دستور زیر را صادر کنید:

npm install gulp --save-dev

این دستور، ابزار گالپ را در بخش وابستگی‌های فنی فایل package.json ثبت کرده (سوئیچ save-dev––) و فایل‌های موردنیاز را در پوشه‌ای با عنوان node_modules، دانلود و ذخیره می‌کند. این کار سطح توزیع‌پذیری پروژه‌ را بالا خواهد برد به این شکل که کافی است پوشۀ اصلی را به ماشین دیگری منتقل کنید، تمام ملزوماتِ کار، همراه پروژه خواهند بود.

خب، هر آنچه برای شروع بازی لازم داشتید، در اختیارتان است. برای ادامه، به یک سناریوی فرضی نیاز داریم که درنهایت ما را به تعدادی تکلیف تکراری که باید انجام شوند برساند. فرض کنید که در پروژۀ خود چندین فایل جاوا اسکریپت ایجاد کرده‌ایم. حال می‌خواهیم پس از پایان هر حلقۀ توسعه، کارهای زیر به‌صورت خودکار انجام شوند:

  1. تمام فایل‌های جاوا اسکریپتِ ایجادشده باهم یکی شوند.
  2. فایل نهایی کوچک‌سازی شود.
  3. فایل خروجی در پوشۀ دیگری و با عنوان جدید ذخیره شود.
  4. با هر بار تغییر در هر یک از فایل‌ها، تکالیف فوق دوباره و به‌صورت خودکار انجام شوند.

مرحلۀ بعدی نصب افزونه‌هایی است که انتظارات فوق را تأمین کنند. به‌منظور اجرای تکالیف ۱و ۲ به دو افزونۀ gulp-concat، gulp-minify نیاز داریم. دستور زیر هر دو افزونهرا برایتان یکجا نصب خواهد کرد:

npm install gulp

فایل package.json چیزی شبیه این خواهد بود:

package.json

همان‌طور که مشاهده می‌کنید، در فایل package.json به تمام ابزارهایی که لازم داریم اشاره ‌شده است. نکته جالب این است که اگر پروژۀ خود را در اختیار کس دیگری قرار دهید یا بر روی ماشین دیگری منتقل کنید، با اجرای دستور npm install تمامی ملزومات پیکربندی‌شده در این فایل مجدداً نصب‌شده و قابل‌استفاده خواهند بود. قابلیتی که در مواقع دست‌به‌دست شدن پروژه بین توسعه‌دهندگان مختلف بسیار حائز اهمیت و طلایی است.

تعریف تکالیف در فایل gulpfile.js

این فایل، قلب تپندۀ فرآیند ساخت پروژه با گالپ است. جایی که تکالیف مورد انتظار را تعریف و پیکربندی می‌کنیم. ابزار گالپ درنهایت این فایل را فراخوانی و دستورات موجود در آن را اجرا خواهد کرد. فایل gulpfile.js را در ریشۀ پوشۀ پروژه ایجاد کرده و خطوط زیر را به آن اضافه کنید:

gulpfile

کدهای فوق (که به زبان جاوا اسکریپت نوشته‌شده‌اند) ، دستورات پایه برای تعریف تکالیف بعدی است. خط اول، ماژول گالپ را برای کارهای عمومی در اختیارمان قرار می‌دهد. خطوط بعدی نمایانگر یک تکلیف پیش‌فرض است که شروع فرآیند ساخت را کلید می‌زند. تکلیف default تکلیفی است که به‌صورت نقطۀ آغاز توسط Gulp شناسایی و اجرا خواهد شد. به آن به چشم یک تابع main که در هنگام فراخوانی یک برنامه اجرا می‌شود بنگرید.

قبل از اینکه تکالیف موردنظرمان را ایجاد کنیم، دستور gulp را در پوشۀ ریشۀ پروژه اجرا کنید. باید با پیامی مبنی بر موفقیت در اجرای دستورات مواجه شوید:

gulp exec

کدهای زیر را  با کدهای قبلی در فایل gulpfile.js جایگزین کنید:

gulpfile

اگر به نظرتان کمی پیچیده می‌آید، نگران نباشید به خواندن ادامه دهید. به‌زودی همۀ آن‌ها را درک خواهید کرد.

ساختار تکلیف‌ها

هر تکلیف با فراخوانی متد task از شیء gulp ایجاد می‌شود. این متد سه ورودی می‌گیرد.

  • عنوان منحصربه‌فرد برای تکلیف.
  • آرایه‌ای از تکالیف که باید قبل از اجرای آن اجرا شوند.
  • یک تابع اجرایی

نکته: اگر تکلیفی که تعریف می‌کنید نیازمند یا وابسته به تکالیف دیگر نیست، می‌توانید از آرایه صرف‌نظر کرده و تابع خود را مستقیم به پارامتر دوم ارسال کنید.

تعریف و اختصاص توابع از قواعد شیرین جاوا اسکریپت پیروی می‌کند. هر سه حالت زیر معتبر هستند:

tasks

دست‌کم در هنگام کار با گالپ، ترجیح می‌دهم از حالت سوم استفاده کنم! زیرا اجازه می‌دهد که فایلِ تر و تمیزتری داشته باشم و ترتیب تعریف توابع را آزادانه تغییر دهم. علاوه بر این، تعریف تکالیف پیچیده و توابع اشتراکی در این حالت راحت‌تر خواهد بود.

درصورتی‌که تکلیف موردنظر به تکالیف دیگر وابسته باشد، عنوان آن تکالیف را درون یک آرایه قرار داده و در پارامتر دوم به تابع task ارسال می‌کنیم. به تکلیف default در خط ۱۲ دقت کنید. یک تکلیف پیش‌فرضِ صامت (بدون تابع اجرایی) که تکالیف js و watch ،که قبل‌تر ایجادشده‌اند را اجرا می‌کند. باید توجه داشت که ترتیب قرارگیری تکالیف در آرایه تأثیری در تقدم و تأخر اجرای آن‌ها ندارد. همۀ تکالیف موجود در آرایه یکباره و به صورت موازی اجرا خواهند شد. اگر عنصر دوم یک تابع باشد، در هنگام فراخوانیِ تکلیف، اجرا خواهد شد. درون تابع هر چیزی را می‌توانید تعریف کنید. هر منطقی که مایلید درون تابع قابل پیاده‌سازی است. اجازه دهید به کد قبل بازگشته و درون این توابع را دقیق‌تر بررسی کنیم. سه خط اول ماژول‌هایی که نصب‌کرده بودیم را برای استفاده‌های بعدی، مهیا می‌کنید.

در بخش بعدی، تکلیفی با عنوان js ساخته شد و تابع jsTask را به آن متصل کردیم. درون تابع مذکور، متد src ، هرچه فایل با پسوند js در پوشۀ /js/ و همۀ زیرشاخه‌های آن پیدا کند را به‌عنوان منبع در خود حفظ می‌کند. خط بعدی تابع concat را به‌عنوان حلقۀ بعدی به زنجیر متصل می‌کند. این تابع نام فایلی که باید پس از چسباندن فایل‌ها بسازد را (all.js) در ورودی اخذ می‌کند. خط بعدی دستور minify که فایل یکپارچه‌شده را کوچک‌سازی می‌کند را صادر می‌کند و درنهایت خط بعدی به Gulp می‌گوید که فایل‌های ایجادشدۀ نهایی را به کجا (/dest/js) منتقل کند. دقت کنید تا زمانی که دستور gulp.dest را اجرا نکرده‌ایم هیچ خروجی بر روی دیسک نخواهیم داشت. انتظارات شمارۀ ۱، ۲ و ۳ در این تکلیف مرتفع شدند.

اجرا به محض تغییر

یک مورد دیگر باقی‌مانده است. اینکه تمام فرآیندهای فوق در هر بار تغییر در فایل‌های مبدأ به‌صورت خودکار تکرار شوند. تکلیف بعدی با عنوان watch همین کار را انجام می‌دهد. درون تابع این تکلیف از متد gulp.watch استفاده‌شده که دو پارامتر می‌گیرد.

  • مسیر فایل‌هایی که قرار است رصد شوند.
  • آرایه‌ای از تکالیف که باید به‌محض تغییر در هر یک فایل‌های مبدأ اجرا شوند.

پارامتر اول را بر روی src/**/*.js تنظیم کردیم چون قرار است تمام فایل‌های جاوا اسکریپت موجود در شاخۀ src و زیرشاخه‌های آن را در بربگیرد. پارامتر دوم هم یک آرایۀ تک عنصری است که عنوان تکلیف از پیش تعریف‌شدۀ js در آن قرار دارد. به این مفهوم که هر وقت تغییری در هر یک از فایل‌های جاوا اسکریپت موجود در آن پوشه صورت گرفت، تکلیف مربوط به چسباندن، کوچک کردن و انتقال را به‌صورت خودکار اجرا کن!

در انتها باید تکلیف default را از وجود تکالیفی که ایجاد کرده‌ایم آگاه کنیم. خط ۱۲ این کار را برای ما انجام می‌دهد. وقتی دستور gulp را در ترمینال اجرا کنید، تکلیف default، تکلیف js و تکلیف watch را اجرا خواهد کرد به این مفهوم که تمام فایل‌های جاوا اسکریپت موجود در پوشه src فشرده‌ و کوچک‌سازی شده و در قالب دو فایل all.js و all-min.js به پوشۀ dest/js کپی می‌شوند و ابزار گالپ در یک وضعیت انتظار به‌منظور رصد تغییرات در فایل‌ها، باقی خواهد ماند تا با هر بار تغییر، مجدداً تکالیف خود را انجام دهد. امتحان کنید:

Terminal

می‌توانید هریک از تکالیف تعریف‌شده را به‌صورت مستقل هم اجرا کنید:

gulp taskname

اطلاعات بیشتر

مواردی که در بالا به آن‌ها اشاره کردم تنها بخش کوچکی از قابلیت‌هایی است که ابزار گالپ در اختیار شما قرار می‌دهد. برای اطلاعات تکمیلی و مبانی بیشتر می‌توانید به مستندات رسمی گالپ در گیت هاب مراجعه کنید. مجموعه‌ای کامل و آموزنده از دستور‌عمل‌های آماده و مقالات مفید برای آشنایی بیشتر با افزونه‌های مختلف و ترفندهای این ابزار قدرتمند نیز در دسترس هستند.

👋

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *