Appearance
معرفی ابزارهای Build
نسخهی ویدئویی همین متن
نسخهی ویدئویی این آموزش را میتوانید از طریق لینک زیر دریافت کنید. البته توصیهی ما مطالعهی نسخهی متنی آن است.
https://cdn.gaplication.com/o/c26ecc673eb14b9d986c50750d75a5a3
در این مطلب میخواهیم بدانیم ابزارهای Build چیستند و چرا از آنها استفاده میکنیم و اینکه آیا میتوان امروزه پروژهای را بدون استفاده از ابزارهای Build پیش برد؟
نکته
واژهی «Build» به معنای ساختن است. کار ابزار Build این است که کدهای ما را (js و html و css و حتی فایلهایی مثل jpg) به عنوان ورودی بگیرد و روی آنها پردازش انجام دهد و خروجی تولید کند.
در زبان های کامپایلی مثل C این ابزارها از دیرباز وجود داشتهاند و کاربردشان هم روشن بوده است، یعنی یک ابزار Build کدی که کاربر نوشته است را میگیرد و بعد تبدیل به چیزی می کند که ماشین بتواند آن را بخواند و اجرا کند. ولی برای جاوااسکریپت میتوانیم کدهای js را مستقیما روی سرور قرار دهیم. کاربران با مرورگر سایت را بازکرده و همان کدها برای مرورگرشان فرستاده میشود و مرورگر کدها را اجرا می کند. پس در حالت عادی نیازی به سیستم build نیست، زیرا خود مرورگر کد های جاواسکریپت و html و css را می فهمد.
اما برخی نیازمندیها باعث میشود ما از ابزارهای Build در جاوااسکریپت استفاده کنیم که به مهمترین موارد آن اشاره میکنیم:
باندلکردن
ابزارهایی هستند که فایلها را با یکدیگر ترکیب میکنند و تبدیل به یک فایل میکنند، مثلا تمام فایلهای جاوااسکریپت برنامه را با هم ادغام میکند و تنها در یک فایل نهایی میریزد.
نمونه ابزار باندلکننده: Webpack, Rollup, Parcel, ESBuild
مینیفای (Minify)
مینیفای به معنای کمحجم کردن کد از طریق خلاصهکردن نام متغیرها، حذف تابعها و متغیرها و کدهای بلااستفاده، حذف فاصلههای اضافی و... که به صورت خودکار و بدون تغییر در عملکرد برنامه انجام میشود.
نمونه ابزار مینیفای جاوااسکریپت: terser، esbuild
نمونه ابزار مینیفای CSS: cssnano, LightningCSS
مثال: کدی که به Terser تحویل میدهیم (ورودی):
js
let myCounter = 0
const interval = () => {
myCounter++
alert(myCounter)
}
const intervalTime = 2 * 1000 /* 2s */
let intervalId = setInterval(interval, intervalTime)
کدی که از Terser دریافت میکنیم (خروجی):
js
let e=0;setInterval(()=>{e++,alert(e)},2e3)
پشتیبانی از مرورگرهای قدیمی
ابزارهایی هستند که به ما اجازه میدهند از جدیدترین Syntaxها و قابلیتهای وب استفاده کنیم، و نگران مرورگرهای قدیمی که از این قابلیتها پشتیبانی نمیکنند نباشیم. این ابزارها به صورت خودکار طوری کد ما را تغییر میدهند که در مرورگرهای قدیمیتر نیز به درستی اجرا شود. برخی از این ابزارها (مثل ابزار Babel) قادرند قابلیتهایی را که قرار است در آینده به جاوااسکریپت اضافه شود و هماکنون هیچ مرورگری از آنها پشتیبانی نمیکند نیز در اختیار ما بگذارند.
نمونه ابزار برای جاوااسکریپت: babel (preset-env)
نمونه ابزار برای CSS: postcss (preset-env)
تایپاسکریپت (TypeScript)
امروزه تایپاسکریپت جزئی ناگسستنی از دنیای جاوااسکریپت شده است. همهی کتابخانهها و فریمورکهای درست و حسابی جاوااسکریپتی یا با تایپاسکریپت نوشته شده اند (مثل Vue یا Angular و Solid.js) و یا پشتیبانی کاملی از آن دارند (مثل React). تایپاسکریپت یک سیستم Type روی جاوااسکریپت اضافه میکند که تأثیر بهسزایی در پیشنهاددهی بهتر نرمافزار کدنویسی و پیشگیری از خطاها در برنامه دارد.
سینتکس تایپاسکریپت به صورت عادی در مرورگرها پشتیبانی نمیشود. از این رو نیاز به ابزاری داریم که این تبدیل را انجام دهد. ابزار رسمی این کار TypeScript Compiler است. ولی ابزارهای دیگری همانند Babel و ESBuild نیز میتوانند سینتکس تایپاسکریپت را به جاوااسکریپت تبدیل کنند.
پیشپردازندهها
برای راحتی کار با CSS زبانهایی ساخته شده اند که نهایتا به CSS تبدیل میشوند، مثل SCSS یا Stylus. مشابه این زبانها برای جاوااسکریپت یا HTML هم وجود دارد. مثلا زبان CoffeeScript که به جاوااسکریپت تبدیل میشود، یا Pug که به HTML تبدیل میشود.
مرورگر به خودی خود از این زبانها پشتیبانی نمیکند و برای کار با آنها باید از ابزارهای Build مربوطه استفاده کرد تا اینها را به همان HTML و CSS و JS تبدیل کند. این زبانها اصطلاحا preprocessor (پیشپردازنده) نامیده میشوند.
مبهمسازی
ابزارهایی هستند که هدفشان مبهمسازی کد نوشته شده است، تا هکرها نتوانند به راحتی از ساز و کار کد جاوااسکریپت نوشتهشده سر در بیاورند. البته با مینیفای کردن کد تا حد نسبتا خوبی مبهم میشود، ولی هدف از مینیفای مبهمسازی نیست و فقط کمحجم کردن است. ابزارهایی داریم که هدفشان مبهم کردن کد است.
بهینهسازی
یکی از مهمترین استفادههای ابزارهای Build در بهینهسازی است. ابزارهایی هستند که با مینیفای کردن و حذف کدهای اضافی حجم برنامه را کاهش میدهند. ابزارهایی تصاویر موجود را فشرده و کمحجم میکنند. ابزارهایی فایلها خروجی پروژه را با فرمتهایی مثل gzip فشرده میکنند. ابزارهایی با روشهای حرفهای مثل تولید خودکار CSSهای ضروری پروژه را بهینهسازی میکنند و...
چندزبانگی
در چندزبانگی دو موضوع مطرح است. موضوع اول متنهای بهکار رفته در صفحات مختلف است که در یک پروژهی چند زبانه باید نسبت به زبان انتخابشده متن متفاوتی نمایش داده شود. برای این موضوع ابزارهای Build مناسبی ساخته شده است. البته در این زمینه کتابخانههای خوبی که در زمان اجرا این موضوع را مدیریت میکنند نیز وجود دارد.
علاوه بر این در زبانهای راستبهچپ (مثل فارسی) جهت چیدمان صفحه برعکس زبانهای چپبهراست است. یعنی اگر جایی margin-right دادهایم در زبانی که جهتش فرق میکند باید تبدیل به margin-left شود. برای این موضوع نیز ابزارهای Build فوقالعاده خوبی ساخته شده اند.
نمونهابزارهای دوجهتهسازی CSS: postcss-rtlcss, rtlcss
Atomic CSS
در این روش برنامهنویس از یک فریمورک AtomicCSS مثل TailwindCSS استفاده میکند. سپس طبق ساختارهای مشخصی که آن فریمورک تعیین کرده است کلاسهای CSS خود را مینویسد. فریمورک مورد نظر در زمان Build کد نوشتهشده را پردازش میکند و کلاسهای CSS استفاده شده را در همان لحظه تولید میکند و در فایل CSS خروجی میریزد. بنابراین در این فریمورکها کلاس بلااستفادهای در CSS خروجی نخواهیم داشت و معمولا حجم CSS خروجی بسیار کم است، و تجربهی کاربری آن برای برنامهنویس این قدر دلنشین است که معمولا بعد از استفاده از یکی از این فریمورکها و پیادهسازی یک پروژه با این روش ترجیح خواهد داد که همیشه از این روش استفاده کند!
نمونهها: TailwindCSS، UnoCSS، Atomizer
CSS in JS
روشی است که در آن کدهای CSS را در لابلای کدهای JS مینویسند، نه در یک فایل CSS جداگانه. این کار در فریمورکهایی مانند React که کد HTML هم به نوعی در همان فایلهای جاوااسکریپت نوشته میشود مرسوم است، زیرا برای نوشتن یک کامپوننت همزمان کد HTML و CSS و JS را به صورت یکجا میبینیم و کنترل بهتری روی تغییراتشان داریم و نیازی به جابجایی بین فایلهای مختلف نیست. همچنین این کار از تداخل انتخابگرهای CSS نیز جلوگیری میکند.
برخی کتابخانههای CSS in JS در زمان اجرا کار میکنند، ولی برخی دیگر در زمان Build کدهای CSS نوشته شده در فایلهای جاوااسکریپت را بیرون میکشند و در فایل CSS جداگانهای میریزند به طوری که گاهی هیچ سربار اضافهای در زمان اجرا ایجاد نمیکنند.
نکته
ساختار فریمورکهایی مثل Vue و Svelte به شکلی است که داخل فایلهای مربوط به کامپوننتها میشود کدهای CSS همان کامپوننت را هم نوشت. یعنی میتوان گفت در این فریمورکها از ابتدا CSS in JS تعبیه شده است و نیازی به نصب و استفاده از یک کتابخانه CSS in JS نیست.
نمونههای ابزارهای CSS in JS در زمان بیلد:
- https://vanilla-extract.style
- https://panda-css.com
- https://seek-oss.github.io/treat
- https://linaria.dev
- https://4catalyzer.github.io/astroturf
- https://github.com/johanholmerin/style9
CSS Modules
روشی دیگر برای رفع چالش تداخل انتخابگرهای CSS استفاده از CSS Module است. در این روش کدهای CSS مثل حالت عادی در فایلهای CSS مجزا نوشته میشود. ابزار Build مربوطه نام کلاسهای CSS به کار رفته در فایلها را تغییر میدهد و در قالب یک شیء در جاوااسکریپت در اختیار فایلهایی که آن CSS را import کرده باشند قرار میدهد. به این روش حتی اگر در دو فایل متفاوت اسم یک کلاس CSS مشترک باشد، در زمان Build تغییر میکند و به دو اسم مجزا تبدیل میشود و از این جهت مشکل تداخل انتخابگرها حل میشود.
نکته
بهشخصه استفاده از CSS Module را به عنوان راهی برای جلوگیری از تداخل CSS توصیه نمیکنم. حتی استفاده از ابزارهای Build دیگر را نیز توصیه نمیکنم، چون خیلی بهینه نیستند! بهترین روش برای عدم تداخل CSS استفاده از متدلوژیهای نامگذاری در CSS مثل متدلوژی BEM یا استفاده از فریمورکهای AtomicCSS است.
فریمورکها و متافریمورکها
امروزه برای سادهسازی کدنویسی ساختارها و Syntaxهای جدیدی توسط فریمورکها ارائه میشود که برای استفاده از آنها نیاز به ابزاری است که آنها را به جاوااسکریپت خام تبدیل کند. برای مثال در فریمورک React سینتکس JSX برای راحتی کار به جاوااسکریپت اضافه شده است که مرورگر به خودی خود از آن پشتیبانی نمیکند و این سینتکس باید توسط یک ابزار Build به js عادی تبدیل شود. فریمورکهای دیگر نیز به طریق مشابه ابزارهای Build مخصوص به خود را ایجاد کرده اند.
امروزه این حرکت تا جایی پیش رفته است که فریمورکهایی بر روی فریمورکهای موجود ساخته شده اند که در هستهی خود شامل ابزارهای Build هستند. به این فریمورکها اصطلاحا متافریمورک گفته میشود. از نمونههای ساده مثل Create React App گرفته تا نمونههای پیشرفته مثل Next.js یا Nuxt.js.
حتی کار به اینجا ختم نمیشود. امروزه فریمورکهایی به وجود آمده اند که در اصل مشابه Compilerهای سایر زبانهای برنامهنویسی عمل میکنند و در اصل فقط یک ابزار Build هستند. این فریمورکها ساختار و چارچوب خاصی را برای کدنویسی ما تعیین میکنند و بعد کدهای نوشته شده در آن ساختار را به جاوااسکریپت عادی تبدیل میکنند. از این رو از نظر سرعت اجرایی و حجم برنامه بسیار بهینهتر از فریمورکهای سنتی مثل React عمل میکنند. از معروفترین نمونههای این فریمورکها میتوان به فریمورک Svelte اشاره کرد.
خیلی کارهای دیگر 😎
مواردی که گفتیم برخی از کاربردهای اصلی ابزارهای Build بود، اما بسته به پروژهی خود ممکن است صدها کاربرد دیگر از این ابزارها پیدا کنید که اشارهای به آنها نکردیم. شما میتوانید با استفاده از کامپایلرهایی مثل Babel هرگونه تغییرات دلخواه ساختارمند روی کدهای جاوااسکریپت بدهید، یا مشابه آن را با PostCSS برای CSS انجام دهید. میتوانید سینتکسها و روال بیلد دلخواه خود را برای پروژهتان ایجاد کنید و...
این سلسله آموزشها تازه شروع کار است. ابزارهای Build دنیای بزرگی دارند که ما در اوّل راه آن هستیم.