لمعرفة ما الذي يجعل حجم تثبيت مشروع Node كبيراً على macOS، قم بقياس الحزم المثبتة، ثم تتبع أكبر الحزم المحتملة عبر شجرة تبعيات npm. في Terminal، ابدأ من دليل المشروع: يعرض du استهلاك القرص، ويسرد npm ls الشجرة المثبتة، ويوضح npm explain سبب وجود الحزمة. تجيب هذه الأوامر عن أسئلة مختلفة: يشير الحجم إلى ما يشغل المساحة؛ وتشير سلسلة التبعيات إلى ما تسبب في جلبها.
قياس الحزم المثبتة على macOS
افتح Terminal، وانتقل إلى مجلد المشروع، وتأكد من أنه يحتوي على node_modules قبل إجراء القياس. تعمل الأوامر التالية في غلاف zsh الافتراضي لنظام macOS وتتجنب الاعتماد على سلوك الأحرف البديلة (wildcards) في الغلاف:
cd "/path/to/your/project"
ls -ld node_modules
find node_modules -mindepth 1 -maxdepth 1 -type d -prune -exec du -sh {} + | sort -h
يقدم du -sh إجمالياً قابلاً للقراءة البشرية لكل دليل مباشر، ويرتب sort -h تلك الإجماليات من الأصغر إلى الأكبر. اقرأ المخرجات من الأسفل لرؤية العناصر الأكبر حجماً. يقيس الأمر find كل دليل من المستوى الأعلى مرة واحدة: على سبيل المثال، يبلغ عن node_modules/@example كدليل نطاق (scope) مجمع واحد، وليس كل حزمة ذات نطاق على حدة. هذه خطوة أولى مفيدة، وليست تقريراً بالتكلفة الفردية المنسوبة لكل تبعية.
إذا أفاد الأمر بأن node_modules غير موجود، فقد لا يحتوي المشروع على شجرة تبعيات مثبتة بعد، أو قد تكون في الدليل غير الصحيح. تحقق من مدير حزم المشروع وملف القفل (lockfile) قبل تثبيت أي شيء لمجرد قياسه. يصف ملف قفل npm شجرة تبعيات تم حلها، في حين أن الملفات المثبتة هي ما يقيسه du. وثائق package-lock الخاصة بـ npm
تتبع الدليل الكبير وصولاً إلى سلسلة تبعياته
استخدم npm ls لفحص شجرة التبعيات المنطقية لـ npm. يركز ناتجه الافتراضي على حزم المستوى الأعلى؛ بينما يقوم الخيار --all بتوسيع القائمة لتشمل التبعيات المتعدية (transitive dependencies). وثائق npm ls
npm ls --all
بالنسبة للمشاريع الكبيرة، قد يكون سرد القائمة الكاملة أمراً يصعب التعامل معه. بمجرد حصولك على اسم حزمة مرشحة من الشجرة، اسأل npm عن سبب تثبيتها:
npm explain package-name
استبدل package-name بالاسم الفعلي، مثل some-library. يتتبع الناتج سلسلة التبعيات وصولاً إلى جذر المشروع. إذا أبلغ npm عن وجود نُسخ أو إصدارات متعددة، فحدد موقع التثبيت المعني في القائمة ومرر ذلك المسار إلى npm explain، على سبيل المثال:
npm explain node_modules/parent-package/node_modules/package-name
يوثق npm استخدام npm explain لتتبع السلسلة التي تؤدي إلى تثبيت حزمة ما، بما في ذلك مجلد معين عندما تكون التبعية متداخلة. وثائق npm explain
فحص الحزم ذات النطاق والمجلدات المتداخلة
يقوم القياس الأول بتجميع النطاق مثل @example في دليل واحد. لفحص أدلة الحزم المباشرة داخله، شغّل:
find node_modules/@example -mindepth 1 -maxdepth 1 -type d -prune -exec du -sh {} + | sort -h
استبدل @example بالنطاق الذي رأيته في القياس الأول. ضع مسار النطاق بين علامتي اقتباس إذا كنت تستخدم متغيراً أو مساراً يحتوي على مسافات. بالنسبة لحزمة لا تتبع نطاقاً، قِس مجلدها مباشرة، على سبيل المثال du -sh "node_modules/some-library". قد يحتوي مجلد الحزمة على تبعياتها المتداخلة الخاصة؛ لذا فإن قياس كل من الدليل الأصلي والدليل المتداخل سيؤدي إلى حساب بعض الملفات مرتين إذا جمعت الإجماليات معاً. استخدم هذه الأرقام لتحديد الحزم المرشحة، وليس لحساب المساهمة الدقيقة لكل فرع.
بعد ذلك، شغّل npm explain على حزمة كبيرة أو على مسار حزمة متداخلة يظهر داخل الدليل الذي قمت بقياسه. إذا أشار التوضيح إلى المرور عبر تبعية مباشرة، فإن تلك الحزمة ذات المستوى الأعلى هي الفرع الذي يجب فحصه. يمكن أيضاً مشاركة حزمة متعدية كبيرة بين عدة فروع، لذا فإن وجودها تحت مسار واحد لا يعني بالضرورة أن تلك التبعية المباشرة هي وحدها التي تستخدمها. يصف npm الأمر npm ls بأنه شجرة منطقية، والتي قد تختلف عن التخطيط الفعلي لـ node_modules؛ استخدم ناتج التوضيح لفهم العلاقة بدلاً من التعامل مع تداخل المجلدات على أنه الرسم البياني الكامل.
فصل تبعيات التطوير عن تبعيات الإنتاج
قد تكون أداة التطوير الكبيرة غير ضرورية في بيئة الإنتاج، في حين أن تبعية التشغيل الكبيرة قد تكون مطلوبة بواسطة التطبيق. افحص السلسلة وما إذا كانت ناتجة عن تبعية تطوير أو تبعية إنتاج في مخرجات npm. إذا كنت ترغب في مقارنة تثبيت npm مخصص للإنتاج فقط، فإن npm ls --omit=dev يستبعد تبعيات التطوير من عرض التثبيت على القرص؛ لكنه لا يزيلها من package.json أو ملف القفل. تأكد من سلوك npm وإصداره قبل استخدام خيارات الاستبعاد في عمليات التشغيل الآلي. وثائق npm install
تعامل مع الحجم الكبير كخيط إرشادي، وليس كدليل على أن الحزمة غير ضرورية. تحقق مما تستورده تطبيقاتك، وما تتطلبه نصوص البناء البرمجية، وعملية النشر قبل إزالة أي تبعية أو استبدالها. إذا كان ملف القفل موجوداً، فاحرص على مراعاته عند مقارنة عمليات التثبيت: فهو يسجل الشجرة المحلولة ويساعد في شرح سبب اختلاف تثبيت آخر عن المجلد الحالي.
نقطة توقف عملية
ستحصل على إجابة مفيدة عندما تتمكن من تحديد أكبر دليل تم قياسه، والتعرف على الحزمة أو الحزم بداخله، واستخدام npm explain لتتبعها حتى التبعية الجذرية التي جلبتها. يمنحك ذلك فرعاً ملموساً لمراجعته. لا يمكن لاستخدام القرص وحده تحديد ما إذا كان حذف الفرع آمناً، ولا تحسب أوامر تبعيات npm الحصة الحصرية لحزمة ما عندما تكون الملفات أو التبعيات مشتركة.
المصادر
package-lock.json — npm
Terminal User Guide for Mac — Apple