أدوات تطوير الواجهة الأمامية الأساسية التي يجب على كل مطور معرفتها

دقائق القراءة: 10

مقدمة: تبسيط عالم أدوات تطوير الواجهة الأمامية

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

في هذا المقال، سنسلط الضوء على مجموعة من الأدوات الأكثر شيوعًا في تطوير الواجهة الأمامية: NPM، Babel، Webpack، ESLint، وCircleCI. سنقوم بتوضيح المشكلات التي تعالجها هذه الأدوات وكيف تقدم حلولًا فعالة لتحسين سير عملك.

NPM: مدير الحزم الافتراضي لـ JavaScript

شعار NPM، مدير الحزم الأساسي لتطوير JavaScript

يُعد NPM (Node Package Manager) مدير الحزم الافتراضي لتطوير JavaScript. إنه أداة لا غنى عنها تساعدك في العثور على الحزم (البرامج) وتثبيتها واستخدامها داخل مشاريعك. يمكنك إضافة NPM إلى أي مشروع ببساطة عن طريق تشغيل الأمر npm init. عند تنفيذ هذا الأمر، يتم إنشاء ملف package.json في الدليل الحالي للمشروع. هذا الملف هو بمثابة بطاقة هوية لمشروعك، حيث يسرد جميع التبعيات (dependencies) الخاصة به.

لإضافة تبعية جديدة، يمكنك استخدام الأمر npm install (package_name). يقوم NPM بالبحث في السجل البعيد (remote registry) عن الحزمة المحددة بالاسم. إذا تم العثور عليها، يتم إضافة إدخال جديد للتبعية في ملف package.json، ويتم تنزيل الحزمة مع تبعياتها الداخلية إلى مشروعك. ستجد الحزم والتبعيات التي تم تنزيلها ضمن المجلد node_modules. تذكر أن هذا المجلد غالبًا ما يصبح كبيرًا جدًا، لذا تأكد من إضافته إلى ملف .gitignore لتجنب رفعه إلى مستودع Git الخاص بك.

صورة ميم تظهر حجم مجلد node_modules الكبير

لا يقتصر دور NPM على تسهيل عملية البحث عن الحزم وتنزيلها فحسب، بل يساهم أيضًا في تبسيط العمل التعاوني على المشاريع. بدون NPM، سيكون من الصعب إدارة التبعيات الخارجية؛ ستحتاج إلى تنزيل الإصدارات الصحيحة لكل تبعية يدويًا عند الانضمام إلى مشروع قائم، وهو ما يمثل تحديًا كبيرًا. بفضل NPM، يمكنك ببساطة تشغيل الأمر npm install، وسيقوم بتثبيت جميع التبعيات الخارجية لك. ويمكنك تشغيله مرة أخرى في أي وقت يضيف فيه عضو جديد في فريقك تبعية جديدة.

Babel: مترجم JavaScript للمستقبل

شعار Babel، مترجم JavaScript لتحويل الكود الحديث إلى إصدارات أقدم

Babel هو مترجم (compiler) أو محوّل (transpiler) للغة JavaScript، وظيفته ترجمة كود ECMAScript 2015+ الحديث إلى كود يمكن فهمه بواسطة محركات JavaScript القديمة. يُعد Babel المترجم الأكثر شعبية لـ JavaScript، وتستخدمه أطر عمل مثل Vue وReact بشكل افتراضي. المفاهيم التي سنتناولها هنا لا تتعلق بـ Babel وحده، بل تنطبق على أي مترجم JavaScript آخر.

لماذا نحتاج إلى مترجم؟

قد تتساءل: «لماذا نحتاج إلى مترجم، أليست JavaScript لغة مفسرة؟» إذا كنت على دراية بمفاهيم اللغات المترجمة والمفسرة. صحيح أننا عادةً ما نطلق على الشيء اسم «مترجم» إذا كان يترجم الكود الذي يقرأه الإنسان إلى ملف تنفيذي ثنائي يمكن فهمه بواسطة وحدة المعالجة المركزية (CPU). لكن هذا ليس هو الحال هنا.

قد يكون مصطلح «محوّل» (transpiler) أكثر ملاءمة، لأنه يعتبر مجموعة فرعية من المترجم: المحوّلات هي مترجمات تقوم بتحويل الكود من لغة برمجة إلى لغة أخرى (في هذا المثال، من JavaScript الحديث إلى إصدار أقدم).

JavaScript هي لغة المتصفحات، ولكن هناك مشكلة تواجه المتصفحات: التوافقية عبر المتصفحات (Cross-compatibility). تتطور أدوات JavaScript واللغة نفسها بسرعة، وتفشل العديد من المتصفحات في مواكبة هذا التطور. هذا يؤدي إلى مشكلات في التوافق. أنت ترغب في كتابة الكود بأحدث إصدارات JavaScript للاستفادة من ميزاته الجديدة، ولكن إذا لم يقم المتصفح الذي يعمل عليه الكود بتطبيق بعض الميزات الجديدة في محرك JavaScript الخاص به، فلن يتم تنفيذ الكود بشكل صحيح على هذا المتصفح.

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

قبل Babel، كنا نستخدم polyfills لتشغيل إصدارات أقدم من كود معين إذا كان المتصفح لا يدعم الميزات الحديثة. وعند استخدام Babel، فإنه يستخدم polyfills في الخلفية ولا يتطلب منك القيام بأي شيء.

كيف تعمل المحوّلات/المترجمات؟

يعمل Babel بشكل مشابه للمترجمات الأخرى، حيث يمر بمراحل التحليل (parsing)، والتحويل (transformation)، وتوليد الكود (code generation). لن نتعمق هنا في كيفية عمله، لأن المترجمات أنظمة معقدة. ولكن لفهم أساسيات كيفية عمل المترجمات، يمكنك الاطلاع على مشروع the-super-tiny-compiler. تم ذكره أيضًا في وثائق Babel الرسمية كمرجع مفيد لفهم كيفية عمل Babel.

عادةً ما يمكننا الاكتفاء بمعرفة مكونات Babel الإضافية (plugins) والإعدادات المسبقة (presets).

  • المكونات الإضافية (Plugins): هي أجزاء صغيرة من الكود يستخدمها Babel في الخلفية لترجمة الكود الخاص بك إلى إصدارات أقدم من JavaScript. يمكنك التفكير في كل ميزة حديثة كمكون إضافي.

قائمة بمكونات Babel الإضافية لـ ES5

قائمة المكونات الإضافية لـ ES5

  • الإعدادات المسبقة (Presets): هي مجموعات من المكونات الإضافية. إذا كنت ترغب في استخدام Babel لمشروع React، يمكنك استخدام الإعداد المسبق الجاهز @babel/preset-react الذي يحتوي على المكونات الإضافية الضرورية.

مثال على مكونات React Preset الإضافية

مكونات React Preset الإضافية

يمكنك إضافة المكونات الإضافية عن طريق تعديل ملف إعدادات Babel.

هل تحتاج إلى Babel لتطبيق React الخاص بك؟

بالنسبة لـ React، تحتاج إلى مترجم لأن كود React يستخدم عادةً JSX، وJSX يحتاج إلى ترجمة. كما أن المكتبة مبنية على مفهوم استخدام صيغة ES6. لحسن الحظ، عند إنشاء مشروع باستخدام create-react-app، يأتي Babel مُهيأً مسبقًا، وعادةً لا تحتاج إلى تعديل الإعدادات.

أمثلة على عمل المترجم

يحتوي موقع Babel الإلكتروني على مترجم عبر الإنترنت وهو مفيد جدًا لفهم كيفية عمله. ما عليك سوى إدخال بعض الكود وتحليل المخرجات.

واجهة مترجم Babel عبر الإنترنت تعرض كود JavaScript حديث
مخرجات مترجم Babel بعد تحويل الكود الحديث إلى إصدار متوافق

Webpack: مجمّع الوحدات الثابتة

شعار Webpack، أداة تجميع الوحدات الثابتة

Webpack هو مجمّع وحدات ثابت (static module bundler). عند إنشاء مشروع جديد، تستخدمه معظم أطر عمل/مكتبات JavaScript بشكل مباشر هذه الأيام. إذا كانت عبارة «مجمّع وحدات ثابت» تبدو مربكة، فتابع القراءة لأن لدينا أمثلة رائعة لمساعدتك على الفهم.

لماذا تحتاج إلى مجمّع؟

في تطبيقات الويب، سيكون لديك الكثير من الملفات. ينطبق هذا بشكل خاص على تطبيقات الصفحة الواحدة (Single Page Applications) مثل React، Vue، وAngular، حيث يمتلك كل منها تبعياته الخاصة. ما نعنيه بالتبعية هو عبارة import – إذا كان الملف A يحتاج إلى استيراد الملف B ليعمل بشكل صحيح، فإننا نقول إن A يعتمد على B.

في المشاريع الصغيرة، يمكنك التعامل مع تبعيات الوحدات باستخدام علامات <script>. ولكن عندما يكبر المشروع، تصبح التبعيات صعبة الإدارة بسرعة. والأهم من ذلك، أن تقسيم الكود إلى ملفات متعددة يجعل موقع الويب الخاص بك يحمل ببطء أكبر. هذا لأن المتصفح يحتاج إلى إرسال المزيد من الطلبات مقارنة بملف واحد كبير، ويبدأ موقع الويب الخاص بك في استهلاك قدر كبير من عرض النطاق الترددي بسبب رؤوس HTTP.

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

كيف يعمل Webpack؟

عندما تحدثنا عن Babel، ذكرنا أن كود JavaScript يحتاج إلى تحويل قبل النشر. لكن الترجمة باستخدام Babel ليست العملية الوحيدة التي تحتاجها قبل نشر مشروعك. عادةً ما تحتاج إلى تقليص حجمه (uglify)، وتحويله، وترجمة SASS أو SCSS إلى CSS إذا كنت تستخدم أي معالجات مسبقة، وترجمة TypeScript إذا كنت تستخدمه… وكما ترى، يمكن أن تطول هذه القائمة بسهولة.

لا تريد التعامل مع كل هذه الأوامر والعمليات قبل كل عملية نشر. سيكون رائعًا لو كانت هناك أداة تقوم بكل ذلك نيابة عنك بالترتيب الصحيح والطريقة الصحيحة. والخبر السار هو أنها موجودة: Webpack.

يوفر Webpack أيضًا ميزات مثل خادم محلي مع إعادة تحميل فوري (يسمونها hot module replacement) لجعل تجربة التطوير الخاصة بك أفضل. فما هو إعادة التحميل الفوري (hot reloading)؟ يعني ذلك أنه كلما قمت بحفظ الكود الخاص بك، يتم تجميعه ونشره على خادم HTTP المحلي الذي يعمل على جهازك. وكلما تغير ملف، يرسل رسالة إلى متصفحك حتى لا تحتاج حتى إلى تحديث الصفحة. إذا كنت قد استخدمت يومًا npm run serve أو npm start أو npm run dev، فإن هذه الأوامر تبدأ أيضًا خادم تطوير Webpack في الخلفية.

يبدأ Webpack من نقطة الدخول (entry point) لمشروعك (index) ويولد شجرة بناء مجردة (Abstract Syntax Tree) للملف. يمكنك التفكير في الأمر على أنه تحليل الكود. تتم هذه العملية أيضًا في المترجمات، والتي تبحث بعد ذلك عن عبارات import بشكل متكرر لإنشاء رسم بياني للتبعيات. ثم يقوم بتحويل الملفات إلى IIFEs (دوال يتم استدعاؤها فورًا بعد تعريفها) لوحداتها (تذكر، وضع الكود داخل دالة يحد من نطاقها). من خلال القيام بذلك، يقوم Webpack بتقسيم الملفات إلى وحدات والتأكد من أن المتغيرات والدوال غير قابلة للوصول للملفات الأخرى. بدون هذه العملية، سيكون الأمر أشبه بنسخ ولصق كود الملف المستورد، وسيكون لهذا الملف نفس النطاق. يقوم Webpack بالعديد من الأشياء المتقدمة الأخرى في الخلفية، ولكن هذا يكفي لفهم الأساسيات.

ESLint: ضمان جودة الكود

شعار ESLint، أداة تحليل الكود الثابت لضمان الجودة

تُعد جودة الكود أمرًا بالغ الأهمية وتساعد في الحفاظ على مشاريعك قابلة للصيانة والتوسيع بسهولة. بينما يدرك معظم المطورين أهمية الكود النظيف، فإننا أحيانًا نميل إلى تجاهل العواقب طويلة المدى تحت ضغط المواعيد النهائية. تقرر العديد من الشركات معايير الكود وتشجع المطورين على الالتزام بها. ولكن كيف يمكنك التأكد من أن الكود الخاص بك يفي بالمعايير؟

حسنًا، يمكنك استخدام أداة مثل ESLint لفرض القواعد في الكود. على سبيل المثال، يمكنك إنشاء قاعدة لفرض أو منع استخدام الفواصل المنقوطة (semicolons) في كود JavaScript الخاص بك. إذا خالفت قاعدة، يظهر ESLint خطأ ولا يتم تجميع الكود حتى – لذا لا يمكن تجاهل ذلك إلا إذا قمت بتعطيل القاعدة.

يمكن استخدام أدوات التدقيق اللغوي (Linters) لفرض المعايير عن طريق كتابة قواعد مخصصة. ولكن يمكنك أيضًا استخدام إعدادات ESLint المسبقة التي أنشأتها شركات التكنولوجيا الكبرى لمساعدة المطورين على التعود على كتابة كود نظيف. يمكنك إلقاء نظرة على إعدادات ESLint الخاصة بـ Google هنا – وهي التي أُفضلها. يساعدك ESLint على التعود على أفضل الممارسات، ولكن هذه ليست فائدته الوحيدة. يحذرك ESLint أيضًا من الأخطاء/العلل المحتملة في الكود الخاص بك حتى تتمكن من تجنب الأخطاء الشائعة.

مثال على تحذيرات ESLint في محرر الأكواد

CI/CD (CircleCI): التكامل والنشر المستمر

شعار CircleCI، منصة التكامل المستمر والنشر المستمر

اكتسب التكامل/النشر المستمر (Continuous Integration/Continuous Development - CI/CD) شعبية كبيرة في السنوات الأخيرة، حيث تبنت العديد من الشركات مبادئ Agile. تتيح لك أدوات مثل Jenkins وCircleCI أتمتة نشر واختبار برامجك حتى تتمكن من النشر بشكل متكرر وموثوق دون المرور بعمليات بناء صعبة وعرضة للأخطاء بنفسك. أذكر CircleCI كمنتج هنا لأنه مجاني ويستخدم بشكل متكرر في مشاريع JavaScript. كما أنه سهل الاستخدام للغاية.

دعنا نمر بمثال: لنفترض أن لديك خادم نشر/ضمان جودة (deployment/QA server) ومستودع Git الخاص بك. تريد نشر تغييراتك على خادم النشر/ضمان الجودة، لذا إليك عملية مثال:

  1. دفع التغييرات إلى Git.
  2. الاتصال بالخادم.
  3. إنشاء حاوية Docker وتشغيلها.
  4. سحب التغييرات إلى الخادم، وتنزيل جميع التبعيات (npm install).
  5. تشغيل الاختبارات للتأكد من عدم وجود أي أعطال.
  6. استخدام أداة مثل ESLint/Sonar لضمان جودة الكود.
  7. دمج الكود إذا كان كل شيء على ما يرام.

بمساعدة CircleCI، يمكنك القيام بكل هذه العمليات تلقائيًا. يمكنك إعداده وتكوينه للقيام بجميع العمليات المذكورة أعلاه كلما دفعت تغييرًا إلى Git. سيرفض الدفع إذا حدث خطأ ما، على سبيل المثال فشل اختبار. لن أخوض في تفاصيل كيفية تكوين CircleCI لأن هذا المقال يدور حول «لماذا؟» كل أداة. ولكن إذا كنت مهتمًا بمعرفة المزيد ورؤيته عمليًا، يمكنك الاطلاع على هذه السلسلة التعليمية.

الخلاصة التقنية

يتطور عالم JavaScript بسرعة فائقة، وتكتسب أدوات جديدة شعبية كل عام. من السهل أن تتفاعل مع هذا التغيير بمجرد تعلم كيفية استخدام الأداة – فنحن غالبًا ما نكون مشغولين جدًا بحيث لا نأخذ وقتنا للتفكير في سبب شعبية تلك الأداة أو المشكلة التي تحلها. في هذا المقال، اخترت الأدوات التي أعتقد أنها الأكثر شعبية وشاركت أفكاري حول أهميتها. أردت أيضًا أن أجعلك تفكر في المشكلات التي تحلها بدلاً من مجرد تفاصيل كيفية استخدامها. إن فهم الغرض الأساسي لكل أداة هو ما يمكّن المطور من اتخاذ قرارات مستنيرة وبناء أنظمة قوية وفعالة، مما يعزز من جودة الكود وسلاسة سير العمل في أي مشروع.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *