Webpack: دليل المبتدئين





يوم جيد ، أيها الأصدقاء!



أقدم لكم ترجمة لمقال "Webpack: مقدمة لطيفة" بقلم تايلر ماكجينيس.



قبل استكشاف تقنية جديدة ، اسأل نفسك سؤالين:



  1. لماذا هذه الأداة مطلوبة؟
  2. ما المهام التي تؤديها؟


إذا لم تتمكن من الإجابة على هذه الأسئلة ، فقد لا تحتاج إلى التكنولوجيا التي تدرسها. دعنا نحاول الإجابة على هذه الأسئلة فيما يتعلق بـ Webpack.



لماذا تحتاج حزمة ويب؟



Webpack هو منشئ الوحدات. يقوم بتوزيع الوحدات النمطية للتطبيق ، وإنشاء رسم بياني تبعية ، ثم تجميع الوحدات بالترتيب الصحيح في حزمة واحدة أو أكثر ، والتي يمكن الرجوع إليها بواسطة ملف "index.html".



App.js ->       |
Dashboard.js -> | Bundler | -> bundle.js
About.js ->     |


ما هي المشاكل التي يحلها webpack؟



عادةً ، عند إنشاء تطبيق JavaScript ، يتم تقسيم الكود إلى عدة أجزاء (وحدات). بعد ذلك ، في ملف "index.html" ، يجب تحديد ارتباط لكل برنامج نصي.



<body>

    ...
    
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="libs/react.min.js"></script>
    <script src='src/admin.js'></script>
    <script src='src/dashboard.js'></script>
    <script src='src/api.js'></script>
    <script src='src/auth.js'></script>
    <script src='src/rickastley.js'></script>
</body>


هذا ليس فقط مملا ولكن أيضا عرضة للخطأ. من المهم ألا تنسى أي نص برمجي فحسب ، بل من المهم أيضًا ترتيبها بالترتيب الصحيح. إذا قمت بتحميل برنامج نصي يعتمد على React قبل تحميل React نفسها ، فسيتوقف تطبيقك. Webpack يحل هذه المشاكل. لا داعي للقلق بشأن تضمين جميع البرامج النصية في تسلسل.



<body>

    ...
    
    <script src='dist/bundle.js'></script>
</body>


كما سنكتشف قريبًا ، يعد تجميع الوحدات جانبًا واحدًا فقط من كيفية عمل حزمة الويب. إذا لزم الأمر ، يمكنك إجبار حزمة الويب على إجراء بعض تحويلات الوحدة قبل إضافتها إلى الحزمة. على سبيل المثال ، تحويل SASS / LESS إلى CSS عادي ، أو تحويل JavaScript إلى ES5 للمتصفحات القديمة.



تثبيت حزمة الويب



بعد تهيئة المشروع باستخدام npm ، لكي تعمل حزمة الويب ، تحتاج إلى تثبيت حزمتين - webpackو webpack-cli.



npm i webpack webpack-cli -D


webpack.config.js



بعد تثبيت هذه الحزم ، يجب تكوين حزمة الويب. لهذا ، يتم إنشاء ملف يقوم webpack.config.jsبتصدير الكائن. يحتوي هذا الكائن على إعدادات حزمة الويب.



module.exports = {}


تتمثل المهمة الرئيسية لحزمة الويب في تحليل الوحدات وتحويلها الاختياري وتركيبتها الذكية في حزمة واحدة أو أكثر ، لذلك تحتاج حزمة الويب إلى معرفة ثلاثة أشياء:



  1. نقطة دخول التطبيق
  2. التحويلات التي يتعين القيام بها
  3. مكان وضع الحزمة المُنشأة


نقطة الدخول



بغض النظر عن عدد الوحدات النمطية التي يحتوي عليها التطبيق ، هناك دائمًا نقطة دخول واحدة. هذه الوحدة تشمل الباقي. عادةً ما يكون هذا الملف هو index.js. قد يبدو مثل هذا:



index.js
  imports about.js
  imports dashboard.js
    imports graph.js
    imports auth.js
      imports api.js


إذا أخبرنا حزمة الويب بمسار هذا الملف ، فسيستخدمها لإنشاء الرسم البياني للتبعية للتطبيق. للقيام بذلك ، تحتاج إلى إضافة خاصية entryإلى إعدادات حزمة الويب بقيمة المسار إلى الملف الرئيسي:



module.exports = {
    entry: './app/index.js'
}


التحويل مع لوادر



بعد إضافة نقطة الإدخال ، تحتاج إلى إعلام حزمة الويب بالتحولات التي يجب إجراؤها قبل إنشاء الحزمة. لهذا ، يتم استخدام لوادر.



بشكل افتراضي ، عند إنشاء رسوم بيانية تبعية قائمة على عامل التشغيل ، فإن import / require()حزمة الويب تكون قادرة فقط على معالجة ملفات JavaScript و JSON.



import auth from './api/auth' // 
import config from './utils/config.json' // 
import './styles.css' // ️
import logo from './assets/logo.svg' // ️


لن تجرؤ على تقييد نفسك بملفات JS و JSON في تطبيقك ، وعلى الأرجح ستحتاج أيضًا إلى أنماط و SVGs وصور وما إلى ذلك. وهنا يأتي دور اللوادر. تتمثل المهمة الرئيسية لبرامج التحميل ، كما يوحي اسمها ، في تمكين حزمة الويب من العمل مع أكثر من ملفات JS و JSON فقط.



الخطوة الأولى هي تثبيت اللودر. نظرًا لأننا نريد تحميل SVG ، استخدم npm لتثبيت svg-loader.



npm i svg-inline-loader -D 


بعد ذلك ، قم بإضافته إلى إعدادات حزمة الويب. يتم تضمين جميع أدوات التحميل في مجموعة من الكائنات module.rules:



module.exports = {
    entry: './app/index.js',
    module: {
        rules: []
    }
}


تتكون معلومات اللودر من جزأين. الأول هو نوع الملفات التي تتم معالجتها ( .svgفي حالتنا). والثاني هو أداة التحميل المستخدمة لمعالجة هذا النوع من الملفات ( svg-inline-loaderفي حالتنا).



module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' }
    ]
  }
}


يمكننا الآن استيراد ملفات SVG. ولكن ماذا عن ملفات CSS الخاصة بنا؟ للأنماط المستخدمة css-loader.



npm i css-loader -D 


module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: 'css-loader' }
    ]
  }
}


يمكننا الآن استيراد ملفات SVG و CSS. ومع ذلك ، لكي تعمل أنماطنا بشكل صحيح ، نحتاج إلى إضافة محمل آخر. بفضلنا css-loader، يمكننا استيراد ملفات CSS. لكن هذا لا يعني أنه سيتم تضمينهم في DOM. لا نريد استيراد هذه الملفات فحسب ، بل نرغب أيضًا في وضعها في علامة <style>بحيث تنطبق على عناصر DOM. لهذا تحتاج style-loader.



npm i style-loader -D 


module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }
    ]
  }
}


لاحظ أنه نظرًا لاستخدام محملَين لمعالجة ملفات CSS ، فإن قيمة الخاصية useهي مصفوفة. انتبه أيضًا إلى ترتيب اللوادر أولاً style-loader، ثم css-loader. انه مهم. ستقوم حزمة الويب بتطبيقها بترتيب عكسي. يتم استخدامه أولاً css-loaderللواردات './styles.css'، ثم style-loaderلحقن الأنماط في DOM.



يمكن استخدام أدوات التحميل ليس فقط لاستيراد الملفات ، ولكن أيضًا لتحويلها. الأكثر شيوعًا هو تحويل الجيل التالي من JavaScript إلى JavaScript حديث باستخدام Babel. يتم استخدامه لهذا الغرض babel-loader.



npm i babel-loader -D 


module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  }
}


توجد برامج تحميل لأي نوع من الملفات تقريبًا.



نقطة الخروج



تعرف حزمة الويب الآن عن نقطة الدخول وأدوات التحميل. الخطوة التالية هي تحديد دليل الحزمة. للقيام بذلك ، أضف خاصية outputإلى إعدادات حزمة الويب.



const path = require('path')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  }
}


تبدو العملية برمتها كما يلي:



  1. تتلقى حزمة الويب نقطة دخول تقع في ./app/index.js
  2. يقوم بتوزيع البيانات import / requireوإنشاء رسم بياني للتبعية
  3. تبدأ حزمة الويب في إنشاء الحزمة عن طريق تحويل الكود باستخدام أدوات التحميل المناسبة
  4. يجمع حزمة ويضعها فيها dist/index_bundle.js


الإضافات



لقد رأينا كيفية استخدام برامج التحميل لمعالجة الملفات الفردية قبل أو أثناء إنشاء الحزمة. بخلاف برامج التحميل ، تسمح لك المكونات الإضافية بأداء المهام بعد إنشاء حزمة. يمكن أن تتعلق هذه المهام بكل من الحزمة نفسها والتعليمات البرمجية الأخرى. يمكنك التفكير في المكونات الإضافية على أنها برامج تحميل أكثر قوة وأقل محدودية.



لنأخذ مثالا.



HtmlWebpackPlugin



تتمثل المهمة الرئيسية لحزمة الويب في إنشاء حزمة يمكن الرجوع إليها index.html.



HtmlWebpackPluginيُنشئ index.htmlفي الدليل مع الحزمة ويضيف تلقائيًا رابطًا إلى الحزمة الموجودة فيه.



قمنا بتسمية الحزمة ووضعناها index_bundle.jsفي dist. HtmlWebpackPluginسيُنشئ ملفًا جديدًا index.htmlفي الدليل distويضيف ارتباطًا إلى الحزمة - <script src='index_bundle.js'></script>. عظيم ، أليس كذلك؟ نظرًا لأنه تم index.htmlإنشاؤه HtmlWebpackPlugin، حتى إذا قمنا بتغيير نقطة الخروج أو اسم الحزمة ، HtmlWebpackPluginفسوف تتلقى هذه المعلومات وتغير المحتوى index.html.



كيف نستخدم هذا البرنامج المساعد؟ كالعادة ، تحتاج إلى تثبيته أولاً.



npm i html-webpack-plugin -D 


بعد ذلك ، أضف الخاصية إلى إعدادات حزمة الويب plugins.



const path = require('path')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: []
}


نقوم بإنشاء مثيل HtmlWebpackPluginفي مصفوفة plugins.




const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin()
  ]
}


البيئة



إذا كنت تستخدم React ، فستحتاج إلى ضبط هذا process.env.NODE_ENVعلى قيمة productionقبل نشر التطبيق. سيسمح هذا لـ React بالبناء في الإنتاج عن طريق إزالة أدوات التطوير مثل التحذيرات. يتيح لك Webpack القيام بذلك من خلال مكون إضافي EnvironmentPlugin. إنه جزء من حزمة الويب ، لذلك لا تحتاج إلى تثبيته.



const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin(),
    new webpack.EnvironmentPlugin({
      'NODE_ENV': 'production'
    })
  ]
}


الآن ، في أي مكان في تطبيقنا ، يمكننا ضبط وضع الإنتاج باستخدام process.env.NODE_ENV.



HtmlWebpackPluginو EnvironmentPluginهو مجرد جزء صغير من نظام webpack المساعد.



الوضع (الوضع)



في عملية إعداد طلب للإنتاج ، هناك عدة خطوات يجب اتخاذها. لقد غطينا واحدًا منهم للتو - تحديد process.env.NODE_ENVالقيمة production. إجراء آخر هو تصغير الكود وإزالة التعليقات لتقليل حجم الحزمة.



هناك مكونات إضافية خاصة لحل هذه المهام ، ولكن هناك طريقة أسهل. في إعدادات webpack، فإنه يمكن تعيين modeل developmentأو productionاعتمادا على بيئة التطوير.



const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin()
  ],
  mode: 'production'
}


يرجى ملاحظة أننا قد أزلنا EnvironmentPlugin. الحقيقة هي أنه بعد تعيين modeالقيمة ، تقوم productionحزمة الويب تلقائيًا بتعيين process.env.NODE_ENVالقيمة production. كما أنه يصغر الرمز ويزيل التحذيرات.



إطلاق حزمة الويب



في الوقت الحالي ، نعرف كيف تعمل حزمة الويب وكيفية تكوينها ، ويبقى تشغيلها.



لدينا ملف package.jsonيمكننا إنشاؤه scriptللتشغيل webpack.



"scripts": {
  "build": "webpack"
}


الآن ، عند تشغيل الأمر npm run buildفي الجهاز ، سيتم تشغيل حزمة ويب ، والتي ستنشئ حزمة محسّنة وتضعها index_bundle.jsفيها dist.



طرق التطوير والإنتاج



الكل في الكل ، لقد انتهينا من webpack. أخيرًا ، دعنا نلقي نظرة على كيفية التبديل بين الأوضاع.



عند البناء من أجل الإنتاج ، نريد تحسين كل شيء قدر الإمكان. في حالة وضع التطوير ، فإن العكس هو الصحيح.



للتبديل بين الأوضاع ، تحتاج إلى إنشاء نصين package.json.



npm run buildسيبني حزمة الإنتاج.



npm run startسيبدأ خادم التطوير ومراقبة تغييرات الملف.



إذا كنت تتذكر ، فقد قمنا بتعيين هذا modeعلى قيمة productionفي إعدادات حزمة الويب. ومع ذلك ، لسنا بحاجة إليها الآن. نريد أن يكون لمتغير البيئة قيمة مناسبة اعتمادًا على الأمر الذي يتم تنفيذه. دعنا نغير البرنامج النصي buildفي package.json.



"scripts": {
  "build": "NODE_ENV='production' webpack",
}


إذا كان لديك ويندوز، فإن الأمر على النحو التالي: "SET NODE_ENV='production' && webpack".



الآن في إعدادات حزمة الويب يمكننا تغيير القيمة modeبناءً على process.env.NODE_ENV.



...

  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}


لبناء حزمة جاهزة لتطبيقنا ، نقوم ببساطة بتشغيلها npm run buildفي المحطة. distيتم إنشاء ملفات الدليل index.htmlو index_bunlde.js.



خادم التطوير



عندما يتعلق الأمر بتطوير تطبيق ، فإن السرعة هي الجوهر. لا نريد إعادة تشغيل حزمة الويب وانتظار إنشاء جديد مع كل تغيير. هذا هو المكان الذي تأتي فيه الحزمة في متناول اليد webpack-dev-server.



كما يوحي الاسم ، هذا خادم webpack للتطوير. بدلاً من إنشاء دليل dist، يقوم بتخزين البيانات في الذاكرة ومعالجتها على خادم محلي. علاوة على ذلك ، فهو يدعم إعادة التشغيل المباشر. هذا يعني أن أي تغيير سيعيد webpack-dev-serverبناء الملفات ويعيد تشغيل المتصفح.



قم بتثبيت الحزمة.



npm i webpack-dev-server -D 


كل ما تبقى هو إضافة البرنامج النصي startإلى package.json.



"scripts": {
  "build": "NODE_ENV='production' webpack",
  "start": "webpack-dev-server"
}


لدينا الآن أمرين: أحدهما لبدء خادم التطوير ، والآخر لإنشاء الحزمة النهائية.



آمل أن يكون المقال مفيدًا لك. شكرآ لك على أهتمامك.



All Articles