آموزش جامع Webpack (بخش اول) – از صفر تا صد
این نخستین بخش از سری مقالات آموزش جامع Webpack است که اقدام به معرفی کتابخانه Webpack و هر آن چه به آن مربوط است میکند. هدف این مقاله آن است که خواننده را به سادهترین روش ممکن با این ابزار آشنا کند. اما پیش از آن که وارد جزییات مباحث فنی بشویم میخواهیم اندکی از تاریخچه این ابزار را با هم مرور کنیم تا شما به عنوان یک توسعهدهنده فرانتاند با روند شکلگیری آن آشنا شوید و بدانید که چگونه به این نقطه رسیدهایم. این ابزارها موجب استقلال شما میشوند و همچنین باعث میشوند به عنوان مهندسان واقعی حرفی برای گفتن داشته باشید.
تاریخچه
جاوا اسکریپت همواره به عنوان یک زبان «پشتیبان» مطرح بوده و هرگز جدی شمرده نشده است. در سال 2007 اغلب توسعهدهندگان وب از PHP و جاوا اسکریپت استفاده میکردند و هنوز چیزی به نام اصطلاحهای فرانتاند و بکاند اختراع نشده بودند. دلیل این مسئله آن بود که در آن زمان شغلهای فنی تا این حد تفکیک نشده بود و همه چیز در یک وب اپلیکیشن واحد تجمیع میشد.
در آن زمان مثلث نرمافزارهای HTML/CSS/JS در این حوزه غلبه داشتند. سپس عصر «بی جدول» (table less) فرا رسید که عصر طلایی جیکوئری و ایجکس بود که یک انقلاب محسوب میشدند.
ظهور REST برای حل مشکل رفرش صفحه
چند سال گذشت و وباپلیکیشنها بزرگتر شدند و توسعهدهندگان بکاند همه چیز را به سرویس تبدیل کردند. این نیز یک روند جدید بود که در فرانتاند صرفاً ایجکس اجرا میشود و از REST API استفاده میشد و دیگر نیازی به ارسال فرمها یا UI به بکاند وجود نداشت. اگر تا این زمان اغلب توسعه دهنگان 40 درصد بکاندکار و 60 درصد فرانتاندکار بودند، از این زمان به بعد باید مسیر خود را انتخاب میکردند تا یا با جاوا اسکریپت و یا با فریمورکهای بکاند مانند CodeIgniter ،Symfony ،Django یا Flask کار کنند.
نخستین فریمورک جاوا اسکریپت که ظاهر شد از الگوی SPA یعنی وب اپلیکیشنهای منفرد و MVC بهره میگرفت و چیزی که تا آن زمان صرفاً در فرانتاند دیده میشد، اینک به بکاند نیز راه یافته بود. در این زمان Backbone JS و KnockoutJS محبوبیت یافته بودند و همراه با jQuery UI و Twitter Bootstrap چند وب اپلیکیشن ایجاد کرده بودند که اینک بسیار غنیتر و قدرتمندتر از قبل بودند.
سپس به صورت طبیعی شروع به استفاده از اصطلاحهای فرانتاند و بکاند کردیم، زیرا در این روش جدید ساخت وباپلیکیشن، نیاز بود که افراد مجزایی روی این بخشهای جداگانه کار کنند.
بدین ترتیب اپلیکیشنها بسیار رشد یافتند و با وجود استایلها و اسکریپتهای فراوان که خارج از کنترل شده بودند، نیاز به روشی بود که اپلیکیشنها را به روشی هوشمندانه به کاربران ارسال کنیم. بنابراین باید آنها را صرفاً زمانی که ضروری بود require میکردیم و از چیزی که برای توسعهدهندگان بکاند متداول بود، یعنی «یکپارچهسازی پیوسته» (Continuous Integration) استفاده میکردیم.
در یک چنین موقعیتی، یکی از روشهای مناسب استفاده از RequireJS بود که اپلیکیشنهای جاوا اسکریپت را به روشی ناهمگام در سمت کلاینت بارگذاری میکرد و بدین ترتیب صفحه هرگز در نتیجه وجود تعداد بیشماری تگهای <script> مسدود نمیشد. در این حالت تنها یک اسکریپت نقطه مدخل منفرد وجود داشت که همه اسکریپتهای دیگر را require میکرد و آنها را از طریق ایجکس دانلود کرده و به صورت داخلی بر مبنای قالب زیر تجزیه میکرد:
در این موقعیت نیازمند روشی برای ارسال کردن اپلیکیشن نیز بودیم و باید همه این موارد را طوری minify میکردیم که به هم اتصال مییافتند، اما به طور جداگانه نگهداری میشدند، بنابراین روش قدیمی concat and minify دیگر جوابگو نبود. در این زمان بود GruntJS تولد یافت.
در این زمان شروع به ایجاد برخی اسکریپتها با استفاده از این نوع بلوکهای جدید به نام Node.js کردیم که از LESS درون Bootstrap بهره میگرفتند و تغییرات این فایلها را تحت نظارت قرار میدادند.
بدین ترتیب ما قادر شدیم هر کاری که نیاز داریم را با آنها انجام دهیم، اما پروژهها همچنان در حال بزرگ شدن بودند و کم کم اجرای build-ها در حالت watch دشوار میشد و دوباره به عصر تک اجرایی بازگشتیم و منتظر ماندیم بکاند همه چیز را از قبل پردازش کند تا بتوانیم صفحهها را رندر کنیم.
فراخوانی فریمورک بهتر برای فناوریهای بهتر
در این زمان Grunt به تدریج کُند شد، ساختار RequireJS به نوعی آلوده شد و Backbone نیز دیگر کافی نبود. بنابراین باید کاری میکردیم.
در این زمان به صورت طبیعی به Gulp روی آوردیم که امکان اجرای چند وظیفه را به روشی ناهمگام داشت و بسیار سریعتر از Grunt عمل میکرد. این نوع جدید از بلوک به نام AngularJS شناخته شد که نوید روشی بسیار سریع برای بهروزرسانی رابط کاربری میداد، مدلها (داده) را کپی میکرد و دادههای فرم (یا هر نوعی ورودی) به صورت خودکار روی آن مدلها اعمال میشد. این همان الگوی MVVM بود.
ضمناً ابزاری به نام Browserify با نوید تجزیه ماژول وارد بازار شد که کاری مانند Node.js انجام میداد، اما در مرورگرها نبود و ساختار پیچیده AMD را نیز نداشت. ساختار آن ساده بود و صرفاً از ()require از CommonJS استفاده میکرد.
اینک نوبت به بررسی عملکرد رسیده بود
مدت زمان زیادی طول نکشید تا کسانی که از AngularJS استفاده میکردند با مشکلاتی در زمینه عملکرد مواجه شدند. البته دلیل این مسئله آن بود که این ابزار از روی پروتوتایپ برخی طراحان ساخته شده بود، اما در عمل به یک فریمورک تبدیل شده بود. AngularJS برای همگامسازی مدلها با نما و برعکس از یک الگوریتم سنگین برای بررسی بهروزرسانیها در هر دو سمت استفاده میکرد. این فرایند «بررسی کثیف» (Dirty Checking) بدنام اقدام به ثبت watch-هایی برای بخشهای داده/نما میکرد که در معرض رشد سریع و اقامت در حافظه بودند و موجب بروز نشت حافظه شدید میشدند. بدین ترتیب یک قهرمان دیگر وارد عرصه شد:
ReactJS به همراه ایده گردش داده یکطرفه (برخلاف مسیر دوطرفه انگولار) و الگوریتم Virtual DOM متولد شد و عملکردی بسیار بهتر از انگولار ارائه کرد. بدین ترتیب ساختار جدیدی به نام JSX ارائه شد.
بدین ترتیب ما به جای افزودن دستی polyfill-ها، از BabelJS برای انجام این کار استفاده کردیم و از آنجا که Babel یک «مترجم» (transpiler) بود میتوانست ورودی JSX را نیز گرفته و به JS تبدیل کند.
در نهایت با استفاده از همه این ابزارها به عصر «ابزارهای بستهبندی» (bundlers) رسیدیم:
منظور از ابزار بستهبندی ماژول چیست؟
ابزار بستهبندی شبیه به یک ابزار تجربه ماژول و ابزار مدیریت وظیفه است. این ابزار به صورت پیشفرض مسئولیتهای آنچه RequireJS یا Browserify اجرا میکرد را بر عهده دارد و وظیفه تجزیه ماژول را انجام میدهد، اما برخی مسئولیتهای ابزارهای مدیریت وظیفه مانند Grunt یا Gulp را نیز اجرا میکند و فایلها را مورد نظارت قرار داده و انواع متفاوت فایلها را نیز به جز جاوا اسکریپت تجزیه میکند.
Webpack چه کار میکند؟
Webpack یک ابزار بستهبندی ماژول است و در حال حاضر یکی از مشهورترین آنها محسوب میشود. برخی موارد مشابه شامل Parcel و Rollup هستند. این ابزار نه تنها مسئولیت تجزیه ماژول را بر عهده دارد بلکه به loader-ها کمک میکند که انواع متفاوتی از فایلها را تحلیل کرده و با آنها به صورت برابری مانند ماژولهای جاوا اسکریپت رفتار کنند. ما به طور معمول از آن به همراه ایمپورت اسکریپت ECMA استفاده میکنیم، اما همچنین از require کردن موارد CommonJS و require/define موارد AMD نیز پشتیبانی میکند. این ابزار ظرفیت اکسپورت کردن همه آنها را با استفاده از قالب UMD دارد.
آیا Webpack میتواند همه این موارد را اجرا کند؟
پاسخ منفی است، زیرا Webpack صد درصد کارهای مدیریت وظیفه را که ابزارهایی مانند Gulp یا Grunt انجام میدهند اجرا نمیکند. اما اکنون میتوانیم از این ابزارهای ساده برای انجام آن کارها استفاده کنیم. در این سری مقالات قصد داریم از اسکریپتهای npm استفاده کنیم، چون راهحلی ساده هستند و همه مواردی را که Webpack پوشش نمیدهد انجام میدهند. برای مطالعه بخش بعدی به لینک زیر بروید:
آموزش جامع Webpack (بخش دوم: آشنایی مقدماتی) — از صفر تا صد
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- ساخت اپلیکیشنهای مدرن با Webpack — به زبان ساده
- توسعه وب اپلیکیشن با جاوا اسکریپت و Webpack — راهنمای کاربردی
- راهنمای جامع React (بخش هفتم) — از صفر تا صد
==