سیستمهای مدیریت ماژول یا باندل کنندههای جاوااسکریپتی، چندی است که دچار تنوع زیادی شدهاند و هر از گاهی، چهرههای جدیدی خود نمایی میکنند. اگر با انگولار 2 آشنا باشید قطعا با SystemJs که یکی دیگر از این گونه باندل کننده هاست آشنایید. در این سری قصد داریم که با یک باندل کنندهی تقریبا همه کاره با نام webpack آشنا شویم.
مقدمه و توضیحی بر اینکه چه لزومی بر باندل کنندههای جاوااسکریپتی هست؟
زمانیکه جاوا اسکریپت پا به عرصهی وجود گذاشت، در توسعهی برنامههای کلاینت، از سیستمهای بیلد استفادهای نمیشد و شاید بتوان سادهترین دلیل آن را عدم احتیاج جاوااسکریپت به کامپایل دانست. ولی با گذشت زمان و عوض شدن چهرهی برنامههای سمت کلاینت و بزرگتر شدن آنها، برنامه نویسان با مشکلاتی از قبیل نگه داری و امنیت، در برنامههای بزرگ رو به رو بودند.
در پاسخ به بزرگ شدن پروژهها قطعا شما این پیشنهاد را خواهید داد که بایستی برنامه را به قسمتها و یا ماژولهای کوچکتری بشکنیم، تا هم نگه داری از آن سادهتر شود و هم احتمال بروز خطا در حین انجام پروژه کاهش یابد. اما باید به یاد داشت که این قسمتهای کوچک شده به معنای یک تگ اسکریپت جدا در صفحات وب برنامه میباشند و این مساله به این معنا خواهد بود که برای هر یک از آنها، مرورگر بایستی به میزبان، درخواستی را ارسال کرده و فایلها را جداگانه دریافت کند. قطعا پاسخ به این مشکل دوباره چسباندن این ماژولها به یکدیگر است تا مرورگر فقط یک درخواست را برای این فایلها ارسال کند. این مسئله همچنین برای فایلهای css و تصاویر نیز صادق میباشد.
دومین مشکلی که با ماژول سازی برنامه با آن روبه رو میشویم، بالا رفتن حجم کد و درنتیجه بالا رفتن ترافیک مصرفی خواهد بود که این مسئله نیز بایستی توسط یک Minifier حل شود. مشکل بعدی، وابستگی ماژولها به یکدیگر است .در صورتی که در اضافه کردن یک ماژول به وابستگیهای آن دقت نداشته باشیم، باعث بروز خطا در برنامه میشویم. با استفاده از یک باندلر میتوانیم وابستگیهای هر ماژول را تعریف کنیم تا این مسئله نیز حل شود.
آخرین مسالهای که به ذهن میآید نیز میتوان قابلیتهای جدید ES6 را نام برد که به صورت سراسری در تمامی مرورگرها ممکن است هنوز قابل استفاده نباشند و شما به عنوان برنامه نویس قصد بهره بردن از آنها را داشته باشید. درنتیجه راهکار، استفاده از یک ترانسپایلر است که میتوان از معروفترین آنها تایپ اسکریپت و babel را نام برد .
راهکارهای مختلف برای حل مشکلات ذکر شده
در صورتی که با فریمورکهای سمت سرور آشنایی داشته باشید، حتما با سیستمهای باندل کننده و Minify کنندهی آنها برخورد داشته اید. به طور مثال فریمورک Asp.Net Mvc دارای یک باندل کنندهی توکار است که مشکل بسته بندی کردن کل ماژولها و همچنین Minify کردن آنها را حل میکند. ولی تا آخرین اطلاعی که دارم، مشکل وابستگی ماژولها به جز اینکه برنامه نویس به صورت دستی ترتیب اضافه شدن را رعایت نماید، قابل حل نیست. همچنین در اینجا استفاده از یک ترانسپایلر نیز مقدور نمیباشد.
راه حل دیگر استفاده از Task Runnerهای جاوا اسکریپتی مانند گرانت و گالپ میباشد که تمامی مسائلی که پیشتر ذکر شد، به وسیلهی آنها قابل حل است؛ به جز مسئلهی وابستگی ماژولها به یکدیگر که بایستی به صورت دستی توسط برنامه نویس ترتیب آنها رعایت شود یا از فریمورک هایی مانند browserify و ... استفاده شود.
راه حل webpack
تفاوت وب پک با TaskRunnerهای جاوا اسکریپتی را میتوان در اینجا بیان کرد که وب پک در انجام یک وظیفه تخصص وافری دارد و آن وظیفه نیز پردازش فایلهای ورودی و خروجی داده شده به آن است که با استفاده از کامپوننتهایی که با نام loader از آن نام میبرد، این وظیفه را انجام میدهد. با استفاده از این لودرها شما نتیجهای را که از یک TaskRunner انتظار دارید، خواهید گرفت؛ مانند ترنسپایل کردن ماژولها، بسته بندی ماژولها، Minify کردن آنها و در نهایت قابلیتی که معمولا در Task Runnerها موجود نیست و وب پک امکان انجام آن را دارد، ترکیب فایلهای Css با فایلهای جاوا اسکریپت برنامه است. این کار برای تصاویر و فونتهای برنامه نیز قابل انجام است.
پیش فرضهای کار با webpack
دو پیش فرض مهم در شروع به کار با وب پک از این قرارند:
1. وب پک برای نصب Assetهای سمت کلاینت شما از NPM استفاده میکند و انتظار دارد که شما نیز این پکیج منیجر بهره ببرید و به طور مثال از bower استفاده نکنید.
2.استفاده از یک سیستم ماژولار ( اینکه از کدام یک استفاده میکنید مهم نیست Commonjs ، amd ، es6 و...)
نصب webpack و شروع کار
webpack یکی از صدها ماژولهای نوشته شدهی با استفاده از پلتفرم nodejs میباشد. پس اول از همه چیز در صورتیکه nodejs بر روی سیستم شما نصب نیست، آن را دریافت و نصب کنید.
قبل از شروع به کار بهتر است که یک محیط کار تمیز ( یک فولدر خالی) را آماده کنید و سپس با اجرای دستور npm init، یک بستر برای کار با npm را داشته باشیم. میتوانید به صورت دستی نیز یک فایل package.json را اضافه کنید و گزینههای مدنظرتان را به آن اضافه کنید.
من با اجرای این دستور و جواب دادن به سوالاتش یک خروجی فایل package.json با این محتوا را ایجاد کردم :
{
"name": "dntwebpack",
"version": "1.0.0",
"description": "a webpack tutorial",
"main": "main.js",
"scripts": {
},
"author": "mehdi",
"license": "MIT"
}
قدم دوم نصب webpack میباشد. برای نصب وب پک دو راه وجود دارد:
1. نصب وب پک به صورت گلوبال ( سراسری ) با استفاده از دستور :npm install -g webpack ، با اجرای این دستور قابلیت استفاده از وب پک را در همه جا با استفاده از خط فرمان، خواهید داشت.
2. ایراد روش اول این است که ممکن است در آینده بخواهید در پروژههای گوناگون از دو نسخهی متفاوت وب پک استفاده کنید و به خاطر نسخهای که به طور سراسری نصب شده است به مشکل بر بخورید. پس با استفاده از دستور npm install -D webpack یا npm install --save-dev webpack وب پک را به صورت محلی برای پروژه نصب میکنیم ( کاربرد پرچم D- یا --save-dev این است که وب پک در قسمت وابستگیهایی که فقط جهت توسعهی پروژه هستند، در فایل package.json اضافه میشود).
در ادامه در محیط کاری که ایجاد کردیم، دو فایل دیگر را ایجاد میکنیم. اولی یک فایل سادهی html جهت اینکه اسکریپتهای پروژه را به آن اضافه کنیم و دیگری یک فایل اسکریپت جهت اینکه آن را به وب پک بدهیم.
فایل html را index.html نام گذاری کردم و اسکریپت سمپل را نیز main.js. محتوای هر دوفایل به این صورت میباشد:
<html>
<!-- index.html -->
<head>
first part of webpack tut!
</head>
<body>
<h1>webpack is awesome !</h1>
<script src="bundle.js"></script>
</body>
</html>
//main.js
//start of the journey with webpack
console.log(`i'm bundled by webpack`);
اگر دقت کنید اسکریپتی با نام bundle.js در فایل html رجوع داده شده است که در پروژه وجود خارجی ندارد و قصد این است که این فایل را با استفاده از وب پک تولید کنیم.
حالا نوبت به این میرسد که تک فایل main.js را به وب پک بدهیم.
در صورتی که وب پک را به صورت سراسری نصب کرده باشید، این کار ساده است. در خط فرمان با فراخوانی وب پک با دستور webpack ./main.js bundle.js
فایل bundle.js را تولید میکنیم.
در صورتی که وب پک به صورت محلی در پروژه نصب شده باشد، فایل package.json را باز کرده و در قسمت scripts، یک ورودی جدید را به اسم webpack به همراه فرمان مورد نظر، به آن میدهیم. محتوای فایل package.json پس از این کار به صورت زیر خواهد بود:
{
"name": "dntwebpack",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
,"webpack":"webpack"
},
"author": "mehdi",
"license": "ISC",
"devDependencies": {
"webpack": "^1.13.1"
}
}
حال با استفاده از دستور
npm run webpack ./main.js bundle.js ، وب پک فراخوانی شده و تک فایل main.js را باندل میکند.
در صورتی که اجرای دستور بالا موفقیت آمیز باشد، پاسخی مشابه به زیر را باید دریافت کنید:
در قسمت بعدی با تنظیمات پیشرفتهتر و loaderهای وب پک آشنا میشویم .
فایلهای پروژه
dntwebpack.zip (جهت اجرای آنی احتیاج به نصب وبپک را دارید که این کار با استفاده از دستور npm install در فولدر پروژه قابل انجام است).