المدير التاني يقع لوحده
بعد corepack use والتفعيل، من جوه المشروع:
yarn installالرسالة بالإنجليزي، وفيها مسار الملف اللي اتقرأ:
This project is configured to use pnpm because /path/to/package.json has a "packageManager" fieldالأمر يطلع بغير صفر. ملف yarn.lock مش هيتعمل. نفس الكلام لو الحقل Yarn وكتبت pnpm. المسار في الرسالة هو الملف الحاكم، حتى لو أنت واقف في فولدر تحته.
ده إجبار الاسم. النسخة متجبرة لأن الوسيط مش هيشغّل غير الرقم اللي بعد @. بس ده workflow guard مش سور أمان: مطور متعمد يقدر يتخطى الـ shim أو يطفي strict mode.
devEngines شرط زيادة
الحقل ده مش بدل packageManager. هو فحص توافق. onFail يقول يحصل إيه لو الاسم أو النسخة مش ماشيين مع المطلوب.
{ "packageManager": "pnpm@10.15.0", "devEngines": { "packageManager": { "name": "pnpm", "version": "10.15.0", "onFail": "error" } }}onFail قيمته error أو فاضي: اختلاف يوقف الأمر. warn يطبع ويكمل. ignore يسكت. الاتنين لازم يتفقوا: لو packageManager يقول yarn و devEngines يقول pnpm، Corepack يرفض. ولو النسخة المكتوبة مش جوّه المطلوب في devEngines، يرفض برضه.
متستخدمش مدى في devEngines وأنت عايز نسخة واحدة للأبد. المدى بيتسأل للريجستري. حط نفس الرقم في المكانين.
npm لسه الباب الخلفي
طالما corepack enable npm ما حصلش، npm install بيستخدم npm بتاع Node ومش بيسأل Corepack. قفل Yarn مش قفل للباب ده.
corepack enable npmnpm installبعد التفعيل، npm الوسيط يشوف الحقل. مشروع pnpm يرفض npm install زي ما رفض yarn.
حزام تاني، لو جهاز في الفريق مش مفعّل shim لـ npm: سكربت preinstall بحزمة only-allow. npm و pnpm بيشغّلوا preinstall قبل التثبيت. الحزمة تخرج بغير صفر لو اسم المدير الحالي مش pnpm.
{ "scripts": { "preinstall": "npx only-allow pnpm" }}الحزام ده مش بديل عن الحقل. هو يمسك اللي عدّى من غير shim. الحقل هو اللي يختار النسخة.
في متغير COREPACK_ENABLE_STRICT=0 يطفي رفض المدير الغلط. متتحطش في CI. دي للتجربة المحلية، وبتخلّي المدير التاني يشتغل بنسخته العامة. عكس الإجبار.
أقرب package.json هو اللي بيحكم
Corepack يطلع من الفولدر الحالي لفوق. لو لقى package.json في الهوم فيه packageManager، ممكن يعتبر كل فولدر تحته جزءًا من المشروع ده.