تكرار السؤال: …
الإجابة المختصرة
في CJS يعاد كائن exports غير مكتمل أثناء التحميل المتزامن، بينما في ESM تُربط المراجع الحية ولكن قراءة متغيرات غير مهيأة قد ترمي ReferenceError.
الشرح
تحدث عندما يعتمد الملف A على B وفي نفس الوقت يعتمد B على A. يفضل دائماً إعادة هيكلة الكود وفصل الجزء المشترك في ملف ثالث مستقل.
مثال بالكود
// a.js (CommonJS) — b.js requires a.js back, so b receives a PARTIAL exports object
exports.loaded = false;
const b = require("./b"); // while b runs, require("./a") returns { loaded: false }
exports.loaded = true;
// Fix: move the shared code into a third module that neither a nor b imports back
// shared.js
module.exports = { formatPrice: (n) => n.toFixed(2) };
// a.js and b.js: const { formatPrice } = require("./shared");
// ESM: bindings are live, but reading one before its module has evaluated throws a ReferenceError (TDZ)أخطاء شائعة
- الاعتماد على ترتيب الاستيراد العشوائي لإخفاء أخطاء التبعية الدائرية.
أسئلة متابعة
- قارن بين نظامي CommonJS (CJS) و ES Modules (ESM) في Node.js وكيف يتعامل المحرك معهما؟
- ما هو خطر الـ Dual Package Hazard عند نشر مكتبة تدعم CJS و ESM معاً في Node.js؟