01-04-2019, 06:21 PM | #1 |
تاريخ التسجيل: Feb 2019
العمر: 38
المشاركات: 1,149
التقييم: 10
|
تاريخ التسجيل: Feb 2019
العمر: 38
المشاركات: 1,149
التقييم: 10
ما هو محزم الوحدات webpack
تحدثنا في مقال سابق عن Webpack من الناحية النظرية، وشرحنا دوره وأهميته في حياة مطوري الويب هذه الأيام.
وكنت قد وعدتكم بأن أقوم بإعداد درس جديد من أجل شرح webpack واكتشافه بطريقة عملية حتى تترسخ في أذهاننا المفاهيم التي رأيناها في الدرس السابق، وها أنا اليوم أفي بوعدي لكم سنسير في هذا الدرس خطوغ بخطوة لنرى كيفية إعداد ويب باك من الصفر من أجل تكييفه مع احتياجات مشروعنا، وقد يكون هذا الدرس طويلا لأنني لا أريد أن أحرق أي مرحلة مهما كانت بسيطة حتى يكون الشرح في متناول المبتدئين والمتقدمين على السواء. البداية لننشئ مجلدا اسمه wepback-project ونقوم بالدخول إليه : mkdir wepback-project cd wepback-project 1 2 mkdir wepback-project cd wepback-project ثم لنقم بتهيئة ملف packages.json عن طريق هذا الأمر : npm init 1 npm init بعد إنشاء الملف packages.json سنقوم بتحميل Webpack 4، وهي آخر نسحة من webpack لحدود كتابة هذه الأسطر، مع تحميل حزمة Webpack-cli لتنفيذ بعض أوامر webpack انطلاقا من Terminal. npm install webpack webpack-cli --save-dev 1 npm install webpack webpack-cli --save-dev الآن، عند تنفيذ الأمر webpack من نافذة Terminal فإنه ستظهر لنا رسالة الخطأ هذه : الرسالة باللون الأصفر هي فقط رسالة تحذيرية تعلمنا بأن webpack يفترض مسبقا بأننا في وضع الإنتاج (Production) إذا لم نقل له العكس، وبالتالي فإنه قد يقوم بتنفيذ بعض المهام الخاصة بهذا الوضع مثل ضغط ملفات CSS و JS إلخ… أما الرسالة الثانية باللون الأحمر فهي رسالة خطأ تقول لنا بأن webpack يبحث عن مجلد اسمه src في مشروعنا ولكن لم يجده. فانطلاقا من النسخة الرابعة، أصبح webpack يعتمد مقاربة zero configuration التي تمكننا من القيام بعدد من المهام الأساسية من دون إنشاء ملف الإعدادات webpack.config.js. لهذا يفترض هذا المحزم بأن هناك مجلد اسمه src وبداخله ملف index.js، ويمكننا طبعا تغيير هذه الإعدادات الإفتراضية عبر ملف webpack.config.js كما سنرى لاحقا، أو حتى من دونه إنطلاقا من الأوامر السطرية فقط : webpack ./src/index.js --output ./dist/main.js 1 webpack ./src/index.js --output ./dist/main.js وضع التطوير لنقم بإنشاء المجلد src وملف index.js بداخله. وبما أننا في مرحلة التطوير، فسنطلب من webpack أن يقوم بعمله بناء على هذا الوضع، والطريقة هي عبر إضافة العلم mode– لأوامر ويب باك : webpack --mode development 1 webpack --mode development بعد تنفيذ هذا الأمر، ستتم عملية التحزيم بنجاح لأن ويب باك وجد كل الظروف التي افترضها مسبقا. وستلاحظون بأنه قام بإنشاء مجلد جديد اسمه dist بداخله ملف جافاسكريبت main.js وبداخله كود الجافاسكريبت المحزم، غير مضغوط لأننا طلبنا من webpack أن يعمل وفق إعدادات وضع التطوير Development. ولجعل بيئة عملنا أكثر احترافية وعملية، سنقوم بتنفيذ أوامر webpack من داخل سكريبتات npm التي نقوم بإضافتها داخل الملف package.json في منطقة scripts. إليكم الطريقة : "scripts": { "dev": "webpack --mode development" } 1 2 3 "scripts": { "dev": "webpack --mode development" } لإعادة تنفيذ الأمر السابق webpack --mode development ، يكفي تنفيذ هذا الأمر : npm run dev 1 npm run dev بهذه الطريقة يمكننا تنفيذ أوامر npm مهما كانت معقدة، ومهما أظفنا أعلاما وخصائص جديدة لأوامر webpack فإن أمر npm الذي نقوم بتنفيذه في نافذة Terminal يبقى كما هو. وحتى إذا قدر لمطور آخر أن يعمل على مشروعنا، فسيمكنه معرفة الأوامر التي يجب تنفيذها على المشروع فقط بفتح الملف package.json ومعاينة الأوامر داخل الخاصية {} scripts . لإضافة وضع بناء جديد خاص بمرحلة الإنتاج، فيمكننا إنشاء سكريبت جديد اسمه مثلا build بنفس الكيفية التي أضفنا بها السكريبت dev. "scripts": { "dev": "webpack --mode development", "build": "webpack --mode production" } 1 2 3 4 "scripts": { "dev": "webpack --mode development", "build": "webpack --mode production" } npm run build 1 npm run build لكي لا نضطر لإعادة تنفيذ هذه الأوامر بعد كل عملية تعديل على الملف index.js، سنقوم بإضافة علم جديد (flag) اسمه watch– لأوامر webpack بهذه الكيفية : "scripts": { "dev": "webpack --mode development --watch", "build": "webpack --mode production --watch" } 1 2 3 4 "scripts": { "dev": "webpack --mode development --watch", "build": "webpack --mode production --watch" } لنبدأ العمل في الأمور الجادة أحدث طريقة لكتابة أكواد الجافاسكريبت معروفة باسم ES6، ولكن مع الأسف لا تدعمها حتى الآن بشكل كامل كل المتصفحات الكبيرة، لذلك علينا تحويل أكواد جافاسكريبت ES6 إلى أكواد جافاسكريبت ES5 مدعومة من كافة المتصفحات. هذه العملية معروفة باسم Transpiling، ويعتبر Babel هو أشهر Transpiler لأكواد الجافاسكريبت في الوقت الحالي. لنكتشف معا كيفية استخدام Babel مع webpack تحميل وإعداد بابل Babel أولا علينا تحميل بابل من مستودع npm مع ملحقاته التي سوف نحتاجها. npm install babel-core babel-loader babel-preset-env --save-dev 1 npm install babel-core babel-loader babel-preset-env --save-dev قمنا هنا بتحميل 3 حزم :
الآن بعد أن قمنا بتحميل الحزم الثلاث، سنقوم بإنشاء ملف اسمه babelrc. لكي نطلب من بابل أن يستخدم الإضافة babel-preset-env ( تعرف هذه الإضافات في بيئة “بابل” ب Presets ) أثناء عملية Transpiling. ونكتب بداخله ما يلي : { "presets": [ "env" ] } 1 2 3 4 5 { "presets": [ "env" ] } جاء الوقت الآن لنطلب من “ويب باك” أن يستعين ب Babel، سنفعل ذلك عن طريق ملف webpack.config.js الذي ذكرناه أكثر من مرة. إعداد “ويب باك” نحن الآن مطالبين بالإستعانة بالملف webpack.config.js من أجل إضافة عدد من الإعدادات المتقدمة ل Webpack. لنشئ هذا الملف الآن، ولنضع فيه المحتوى التالي : const path = require('path'); module.exports = { entry: { main: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js' } }; 1 2 3 4 5 6 7 8 9 const path = require('path'); module.exports = { entry: { main: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js' } }; هذا هو أبسط صورة يمكن أن يكون عليها الملف webpack.config.js، وهذا الكود بسيط حيث يطلب من ويب باك فقط أن يبدأ التحزيم من ملف index.js (يسمى Entry point) على أن يجمع الكود النهائي في ملف main.js (يسمى Output file) وهي كما رأينا سابقا الإعدادات الإفتراضية التي يمكن تغييرها كما شئنا. لنطلب الآن من webpack أن يستخدم الحزمة babel-loader لكي نتمكن من كتابة أكواد جافاسكريبت ES6 : const path = require('path'); module.exports = { entry: { main: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] } }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const path = require('path'); module.exports = { entry: { main: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] } }; لاحظوا بأننا أضفنا المنطقة {} module، هناك سيتم إضافة وإعداد جميع ال Loaders التي نحتاجها مع webpack في مشروعنا. بداخل المصفوفة rules نضع هذه ال loaders على شكل كائنات من نوع JSON، وكل كائن يضم مجموعة من الخصائص أهمها :
// src/index.js const fn = () => "Arrow functions're Working!"; alert(fn()); 1 2 3 4 5 // src/index.js const fn = () => "Arrow functions're Working!"; alert(fn()); بعد تنفيذ الأمر npm run dev سنلاحظ بأن webpack قام بعملية التجميع في الملف main.js مع تحويل الدالة السهمية (Arrow function) أعلاه إلى دالة تقليدية بطريقة جافاسكريبت ES5. // dist/main.js "use strict"; var fn = function fn() { return "Arrow functions're Working!"; }; alert(fn()); 1 2 3 4 5 6 7 8 9 // dist/main.js "use strict"; var fn = function fn() { return "Arrow functions're Working!"; }; alert(fn()); إذن أصبح بإمكاننا الآن كتابة أكواد جافاسكريبت الحديثة في مشروعنا، و webpack بفضل ال babel-loader سيتولى مهمة تجميعها وتحويلها لأكواد جافاسكريبت ES5 المدعومة من معظم المتصفحات. ماذا عن ملفات HTML ؟ نحن الآن لدينا ملف dist/main.js المحزم والجاهز للإستدعاء في صفحة الويب، ولكن أين هي هذه الصفحة ؟ لا تقلق، صديقي، سنقوم بإضافتها حالا. لنقم بإنشاء ملف اسمه index.html داخل المجلد src ونضع فيه المحتوى التالي : // dist/index.html <html> <head> </head> <body> <h1>مرحبا بكم في توتومينا :)</h1> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 // dist/index.html <html> <head> </head> <body> <h1>مرحبا بكم في توتومينا :)</h1> </body> </html> هناك مشكلة صغيرة تواجهنا الآن عندما نقوم بتنفيذ الأمر npm run dev فإنه لا يتم إنشاء أي ملف HTML داخل المجلد dist، رغم أننا قمنا بإنشاء الملف index.html في المجلد src. من الواضح إذن بأن webpack لا يستطيع لوحده القيام بهذه المهمة. سنقوم بمساعدته بواسطة إضافة جديدة ( Plugin ) اسمها HTML webpack Plugin. تلاحظون كذلك أننا لم نقم باستدعاء أي ملف جافاسكريبت في الصفحة src/index.html سنترك هذه المهمة أيضا للإضافة HTML webpack Plugin التي سنقوم بتثبيها في مشروعنا حالا ؛) npm i --save-dev html-webpack-plugin 1 npm i --save-dev html-webpack-plugin بعد تثبيت إضافتنا الجديدة، سنقوم بإعداد webpack لكي يقوم باستخدامها. هيا بنا إلى الملف webpack.config.js ... const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { ... }, output: { ... }, module: { rules: [ ... ] }, plugins: [ new HtmlWebpackPlugin({ hash: true, template: './src/index.html', filename: 'index.html' }) ] }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { ... }, output: { ... }, module: { rules: [ ... ] }, plugins: [ new HtmlWebpackPlugin({ hash: true, template: './src/index.html', filename: 'index.html' }) ] }; في البداية قمنا بإنشاء متغير (كلاس) جديد HtmlWebpackPlugin انطلاقا من الحزمة html-webpack-plugin، ثم قمنا بإنشاء نموذج (Instance) من هذا الكلاس داخل المصفوفة plugins، وبعد ذلك قمنا بتمرير 3 معاملات :
الآن، بعض تنفيذ npm run dev مرة أخرى سنرى بأن webpack قام بإنشاء ملف index.html داخل المجلد dist مع استدعاء الملف main.js المحزم (Bundled). // dist/index.html <html> <head> </head> <body> <h1>مرحبا بكم في توتومينا :)</h1> <script type="text/javascript" src="main.js?3cbc8ec659d08ad396e1"></script></body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // dist/index.html <html> <head> </head> <body> <h1>مرحبا بكم في توتومينا :)</h1> <script type="text/javascript" src="main.js?3cbc8ec659d08ad396e1"></script></body> </html> لم ننتهي بعد! أين هو CSS ؟ لا يوجد تطبيق ويب من دون CSS، لنقم بإنشاء ملف style.css في المجلد src. ثم لنقم باستدعائه من ملف index.js، نعم من الجافاسكريبت // src/index.js import './style.css'; const fn = () => "Arrow functions're Working!"; alert(fn()); 1 2 3 4 5 6 // src/index.js import './style.css'; const fn = () => "Arrow functions're Working!"; alert(fn()); webpack لا يستطيع التعامل مع ملفات CSS، فهو دائما ينتظر ملفات JavaScript. لهذا عند تشغيله سيظهر لنا هذا الخطأ الجميل والذي يخبرنا بأنه علينا مساعدة webpack في إيجاد حل للتعامل مع ملفات CSS وذلك بتثبيت ال Loader المناسب لهذه الحالة. ال Loader الذي نحتاجه هنا موجود واسمه css-loader، لنقم بتثبيته الآن : npm install --save-dev css-loader 1 npm install --save-dev css-loader هذا loader يمكن webpack من استيراد أكواد CSS باستخدام import أو require، وهذه حدود دور css-loader، هذا الدور ضروري ولكنه غير كافي. نحن الآن لدينا ال CSS المستورد بفضل css-loader، ولكن كيف نقوم باستدعاء هذا CSS في الصفحة ؟ لحسن الحظ هناك إضافة (Plugin) أخرى اسمها mini-css-extract-plugin وتمكن من استخلاص ال CSS المستورد ووضعه في ملف (أو ملفات) CSS منفصل. لنقم بتثبيت هذه الإضافة : npm install --save-dev mini-css-extract-plugin 1 npm install --save-dev mini-css-extract-plugin بعد التثبيت، سنقوم بإعداد webpack لكي يستعين بهذه الإضافة الجديدة : // webpack.config.js ... const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: { ... }, output: { ... }, module: { rules: [ ... ,{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader" ] } ] }, plugins: [ ..., new MiniCssExtractPlugin({ filename: "bundle.css" }) ] }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 // webpack.config.js ... const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: { ... }, output: { ... }, module: { rules: [ ... ,{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader" ] } ] }, plugins: [ ..., new MiniCssExtractPlugin({ filename: "bundle.css" }) ] }; مثلما فعلنا مع إضافة HtmlWebpackPlugin، قمنا بإنشاء نموذج من الكلاس MiniCssExtractPlugin وأضفناه في المصفوعة plugins، ثم طلبنا منه أن يكون اسم ملف ال CSS المخرج bundle.css. ولا ننسى كذلك أننا أعطينا تعليمات لِ webpack من داخل المصفوفة rules لكي يقوم بإجراء css-loader و MiniCssExtractPlugin.loader (هذا الأخير يمكن تعويضه ب style-loader بعد تثبيته) على جميع الملفات من نوع css. ومن الآن، بعد تشغيل webpack سيتم استخلاص ال css المستورد من داخل الجافاسكريبت ويضاف إلى ملف جديد اسمه bundle.css في المجلد dist، ثم يتم استدعائه تلقائيا في الملف dist/index.html إليكم الحالة النهائية لهذا الملف : // dist/index.html <html> <head> <link href="bundle.css?a583e8290b8c96b0a276" rel="stylesheet"> </head> <body> <h1>مرحبا بكم في توتومينا :)</h1> <script type="text/javascript" src="main.js?a583e8290b8c96b0a276"></script> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 // dist/index.html <html> <head> <link href="bundle.css?a583e8290b8c96b0a276" rel="stylesheet"> </head> <body> <h1>مرحبا بكم في توتومينا :)</h1> <script type="text/javascript" src="main.js?a583e8290b8c96b0a276"></script> </body> </html> وفي الصورة التالية، تجدون البنية النهائية لمشروعنا : النهاية هكذا تعلمنا اليوم كيفية إضافة Webpack إلى مشاريعنا والإستعانة بالمزايا العديدة التي يوفرها بفضل العدد الكبير من Loaders و Plugins التي تزخر بها هذه البيئة. المهام التي أنجزناها في هذا الدرس تعتبر بسيطة مقارنة بكل ما يمكن القيام به، حتى الإضافات و Loaders التي تطرقنا إليها اليوم لم نرى من إمكانياتها سوى القليل، فأدعوكم لزيارة صفحات كل واحدة منها على Github لإكتشاف جميع المزايا التي تقدمها. المصدر: منتديات رحيل لكل العرب - من قسم: قسم تطوير المواقع ومحركات البحث والسيو Seo والووردبريس WordPress |
اقتباس |
أضف رد جديد |
الذين يشاهدون محتوى الموضوع الآن : 1 ( الأعضاء 0 والزوار 1) | |
|
|
المواضيع المتشابهه | ||||
الموضوع | كاتب الموضوع | المنتدى | مشاركات | آخر مشاركة |
إدارة القسائم (Coupons)، الودجات (Widgets)، والشيفرات المختصرة (Shortcodes) في متجرك | مهرة النجدية | قسم تطوير المواقع ومحركات البحث والسيو Seo والووردبريس WordPress | 1 | 22-07-2019 06:51 PM |
دليلك الشامل حول النظام البيئي لِ “جافاسكريبت” | raheel | قسم تطوير المواقع ومحركات البحث والسيو Seo والووردبريس WordPress | 0 | 01-04-2019 06:50 PM |
كيفية استيراد وتصدير الوحدات على طريقة es5 | raheel | قسم تطوير المواقع ومحركات البحث والسيو Seo والووردبريس WordPress | 0 | 01-04-2019 06:37 PM |
مميزات Webpack التي تفوق بها على المنافسين | raheel | قسم تطوير المواقع ومحركات البحث والسيو Seo والووردبريس WordPress | 0 | 01-04-2019 06:24 PM |
كيفية إعداد مشروع React.js باستخدام Webpack 4 و Babel | raheel | قسم تطوير المواقع ومحركات البحث والسيو Seo والووردبريس WordPress | 0 | 01-04-2019 06:04 PM |