ماذا يحدث عندما تقوم بتشغيل أوامر npm؟
تضغط على مفتاح Enter لتنفيذ أمر npm. يتم بناء مشروعك. يبدو الأمر وكأنه سحر.
ليس سحراً. بل هو سلسلة من طلبات الشبكة، وتحليل الكود، وتحسين الملفات.
توقف عن تشغيل الأوامر بشكل أعمى. افهم المحرك بدلاً من ذلك.
إليك ما يحدث خلف الكواليس في الأوامر الستة الأساسية التي تستخدمها كل يوم.
- npm install
يقرأ هذا الأمر ملف package.json الخاص بك. ويتصل بسجل سحابي (cloud registry) للعثور على الإصدارات المناسبة لأدواتك.
- يقوم بتنزيل الحزم من السجل.
- ينشئ مجلد
node_modules. - يبني شجرة التبعيات (dependency tree).
- يقوم بتحديث
package-lock.jsonلتسجيل الإصدارات الدقيقة.
- npm run format:check
هذه خطوة تحقق. فهي تتحقق مما إذا كان الكود الخاص بك يتبع قواعد التنسيق (style rules) الخاصة بك دون تغيير أي شيء.
- يقوم ببناء تخطيط افتراضي لملفاتك.
- يقارن ملفاتك بالقواعد مثل Prettier.
- يحدد الأخطاء إذا كانت المسافات أو الصيغة (syntax) خاطئة.
لإصلاح هذه الأخطاء، قم بتشغيل npm run format. يستخدم هذا الأمر Prettier لإعادة كتابة ملفاتك بالتنسيق الصحيح.
- npm run lint
فكر في هذا الأمر كمدقق إملائي للكود الخاص بك. يبحث ESLint عن الأخطاء التي تكسر المنطق البرمجي الخاص بك.
- يجد أخطاء الصيغة (syntax errors).
- يحدد المتغيرات غير المستخدمة.
- يكتشف عمليات الاستيراد (imports) المفقودة.
- يحدد الاستخدام غير الصحيح لـ React Hook.
- npm run build
يجهز هذا الأمر تطبيقك للعالم الحقيقي. حيث يقوم بإنشاء مجلد dist.
- يستخدم أداة تجميع (bundler) لإجراء عملية tree shaking، والتي تقوم بحذف الكود الذي قمت باستيراده ولكنك لم تستخدمه أبداً.
- يقوم بعملية التصغير (minification)، والتي تزيل المسافات البيضاء وتعيد تسمية المتغيرات لتوفير المساحة (bytes).
- يعالج ملفات CSS والأصول (assets).
- يُنتج ملفات ثابتة (static files) محسنة وجاهزة للخادم.
- npm run dev
يبدأ هذا الأمر خادم التطوير المحلي الخاص بك. إذا كنت تستخدم Vite، فإنه يستخدم Native ES Modules.
- يقوم بتجميع الملفات فقط عندما يطلبها المتصفح.
- يستخدم WebSockets لخاصية Hot Module Replacement (HMR).
- يستبدل الكود المعدل في متصفحك فوراً دون الحاجة إلى إعادة تحميل الصفحة بالكامل.
- npm run preview
استخدم هذا الأمر للتحقق من عملك قبل النشر (deploy). يتجاهل هذا الأمر الكود المصدري الخاص بك، بل ينظر فقط إلى مجلد dist.
- يحاكي كيفية سلوك تطبيقك على Vercel أو AWS.
- يقوم بتشغيل نسخة الإنتاج (production build) الخاصة بك على خادم محلي.
الطرفية (terminal) ليست صندوقاً أسود. عندما تفهم أدواتك، ستتمكن من تصحيح الأخطاء (debug) بشكل أسرع.
ما هو الأمر الذي غير سير عملك بمجرد أن تعلمت كيفية عمله؟ أخبرني في التعليقات أدناه.
السحر الكامن تحت الطرفية: ماذا يحدث فعلياً عند تشغيل أوامر npm
هل تساءلت يوماً عما يحدث خلف الكواليس عندما تكتب npm install في الطرفية (terminal) الخاصة بك؟ يبدو الأمر وكأنه سحر، ولكن هناك عملية معقدة تحدث في الخفاء. في هذا المقال، سنغوص في أعماق هذه العملية لنفهم ما يحدث فعلياً.
1. واجهة سطر الأوامر (CLI)
عندما تقوم بتشغيل أمر npm، فإن أول شيء يحدث هو أن واجهة سطر أوامر npm (CLI) تقوم بتحليل الأمر الخاص بك. تقوم الـ CLI بالتحقق من صحة الأمر وتحديد الإجراء الذي يجب اتخاذه، سواء كان ذلك تثبيت حزم جديدة، أو حذف حزم موجودة، أو تشغيل سكربتات محددة.
2. سجل npm (npm Registry)
سجل npm هو قاعدة بيانات ضخمة تحتوي على آلاف الحزم العامة. بمجرد تحليل الأمر، تتواصل الـ CLI مع السجل لطلب معلومات حول الحزم التي طلبتها. يقوم السجل بإرسال "البيانات الوصفية" (metadata) التي تتضمن معلومات حول الإصدارات المتاحة، والتبعيات (dependencies)، وغيرها من التفاصيل الضرورية.
3. ملف package.json
يعتبر ملف package.json هو حجر الزاوية في أي مشروع Node.js. فهو يعمل كـ "مانيفست" (manifest) يحدد التبعيات التي يحتاجها مشروعك، والإصدارات المطلوبة، والسكربتات المتاحة، ومعلومات المشروع الأخرى. عندما تطلب تثبيت حزمة، ينظر npm إلى هذا الملف ليعرف ما إذا كانت الحزمة موجودة بالفعل أو إذا كانت هناك تعارضات.
4. ملف package-lock.json
بينما يحدد ملف package.json نطاقات الإصدارات (مثل ^1.2.0)، فإن ملف package-lock.json يقوم بتسجيل الإصدار الدقيق الذي تم تثبيته. هذا يضمن أن جميع المطورين في الفريق، وكذلك بيئات الإنتاج، يستخدمون نفس الإصدارات تماماً، مما يمنع مشكلة "إنه يعمل على جهازي!" الناتجة عن اختلاف إصدارات الحزم.
5. مجلد node_modules
هذا هو المكان الذي يتم فيه تخزين الكود الفعلي للحزم التي قمت بتثبيتها. بمجرد تحميل الحزم من السجل، يتم فك ضغطها ووضعها في هذا المجلد. قد يكون هذا المجلد ضخماً جداً، لأنه يحتوي ليس فقط على الحزم التي طلبتها، بل وأيضاً على جميع التبعيات التي تحتاجها تلك الحزم.
6. عملية حل التبعيات (Dependency Resolution)
هذا هو الجزء الأكثر تعقيداً. عندما تطلب حزمة معينة، فإن تلك الحزمة قد تعتمد بدورها على حزم أخرى، وتلك الحزم قد تعتمد على حزم أخرى أيضاً. يقوم npm ببناء "شجرة تبعيات" (dependency tree) معقدة لضمان الحصول على جميع الحزم المطلوبة وتجنب التعارضات بين الإصدارات المختلفة.
الخاتمة
فهم ما يحدث تحت غطاء أوامر npm لا يجعلك مطوراً أفضل فحسب، بل يساعدك أيضاً على استكشاف الأخطاء وإصلاحها (debugging) وفهم كيفية إدارة مشروعك بشكل أكثر احترافية. في المرة القادمة التي تكتب فيها npm install ، تذكر أن هناك عملية هندسية دقيقة تحدث في تلك اللحظة!