مخرجات الحزم المزدوجة ESM وCJS
أنشئ إصدارات ES module وCommonJS مع الضبط الصحيح للحقل exports في package.json
مخرجات الحزم المزدوجة ESM وCJS درس مجاني في React Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في React Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة React Academy 4 دروس في المجموع.
ما ESM؟
إن ESM (وحدات ECMAScript) هو معيار وحدات JavaScript الرسمي الذي يستخدم الصياغتين import وexport. ويمكن تحليل ESM تحليلاً ثابتًا، إذ تستطيع أدوات التجميع تحديد الصادرات المستخدمة بدقة وقت البناء، مما يتيح tree-shaking. وتدعم المتصفحات الحديثة وNode.js لغة ESM دعمًا أصليًا.
ما CJS؟
يستخدم CJS (CommonJS) الصياغتين require() وmodule.exports. وكان نظام الوحدات الأصلي في Node.js، ولا يزال مطلوبًا للتوافق مع بيئات Node.js الأقدم، وJest (الذي كان يستخدم CJS تاريخيًا)، والشيفرة التي تستخدم require(). ويُقيَّم CJS ديناميكيًا، مما يجعل tree-shaking أصعب.
حزمة بصيغتين: شحن الصيغتين
ينبغي لحزمة npm الحديثة أن تشحن بصيغتي ESM وCJS لزيادة التوافق إلى أقصى حد. يحصل مستخدمو ESM (مثل Vite وNext.js وأدوات التجميع الحديثة) على استيرادات تدعم tree-shaking. ويحصل مستخدمو CJS (مثل سكربتات Node.js الأقدم وJest دون إعدادات) على توافق مع require(). ويحدد حقل exports في package.json لـ Node وأدوات التجميع الصيغة التي ينبغي استخدامها.
حقل exports
يُعد حقل exports في package.json الطريقة الحديثة لتعريف نقاط الدخول الشرطية. مثال: { '.': { 'import': './dist/esm/index.js', 'require': './dist/cjs/index.js', 'types': './dist/esm/index.d.ts' } }. تقرأ أدوات التجميع وNode.js 12+ حقل exports لاختيار الصيغة الصحيحة تلقائيًا.
حقلا main وmodule القديمان
لا تفهم الأدوات الأقدم حقل exports. ولتحقيق التوافق، عيّن أيضًا: main ليشير إلى مخرجات CJS (كخيار احتياطي لـ require في Node القديم)، وmodule ليشير إلى مخرجات ESM (كتلميح لـ webpack وrollup، وهو غير قياسي لكنه مدعوم على نطاق واسع). تفضّل الأدوات الحديثة exports، بينما تعود الأدوات القديمة إلى main وmodule.
آثار type: module
يؤدي ضبط "type": "module" في package.json إلى التعامل مع جميع ملفات .js في الحزمة على أنها ESM. وإذا كنت تشحن بصيغتين، فستحتاج بعد ذلك إلى امتدادات صريحة: استخدم .mjs لملفات ESM و.cjs لملفات CJS عند ضبط type على module، أو العكس. يتولى tsup ذلك تلقائيًا.
امتدادا .mjs و.cjs
يحدد استخدام امتدادي الملفين .mjs (ESM) و.cjs (CJS) الصيغة صراحةً بغض النظر عن حقل type. وهذا يزيل أي التباس. يستطيع tsup إخراج: index.js (ESM) وindex.cjs (CJS) عند ضبط format على ['esm', 'cjs'] وعدم تعيين حقل type، بما يطابق الاصطلاح الأكثر شيوعًا.
مشكلة الحزمة مزدوجة الصيغة
عندما توفر حزمة ما صيغتي ESM وCJS، قد تُحمّل أداة تجميع المستخدم كلا الإصدارين في العملية نفسها — مثلًا، إصدار ESM للتطبيق الرئيسي وإصدار CJS لاختبار Jest. وإذا كانت الحزمة تحتوي على حالة على مستوى الوحدة (مثل سياق React)، فستملك كلتا المثيلتين حالة مستقلة. وهذه هي مشكلة الحزمة مزدوجة الصيغة.
الحد من مشكلة الحزمة مزدوجة الصيغة
للحد من هذه المشكلة: أبقِ الحالة على مستوى الوحدة خارج مكتبتك (من دون أنماط singleton)، واستخدم شروط exports بدقة لضمان تحميل صيغة واحدة فقط، ووثّق ضرورة إعداد المستخدمين لأداة التجميع لديهم لاستخدام ESM في الاختبارات. وتمثل هذه المشكلة مصدر قلق رئيسيًا للمكتبات التي تحتوي على singleton مشتركة.
اختبار الإخراج بصيغتين
تحقق من عمل الصيغتين بعد البناء. اختبر CJS باستخدام: node -e "const lib = require('./dist/cjs/index.js'); console.log(lib)". واختبر ESM باستخدام: node --input-type=module --eval "import { Component } from './dist/esm/index.js'; console.log(Component)". ينبغي أن تُحل الصيغة الصحيحة في كلتا الحالتين دون أخطاء قبل النشر.
exports لنقاط الدخول المتعددة
يدعم حقل exports نقاط دخول متعددة: { '.': { import: './dist/esm/index.js', require: './dist/cjs/index.js' }, './utils': { import: './dist/esm/utils.js', require: './dist/cjs/utils.js' } }. ويمكن للمستخدمين عندئذٍ الاستيراد من 'your-lib' أو 'your-lib/utils' والحصول على الصيغة الصحيحة.
حقل exports في package.json
ما الغرض الأساسي من حقل exports في package.json الخاص بالمكتبة؟
مراجعة الدرس: إخراج الحزمة بصيغتين
يستخدم ESM الصيغتين import وexport ويتيح tree-shaking. ويستخدم CJS الصيغة require() للتوافق مع Node.js. اشحن الصيغتين عبر حقل exports في package.json باستخدام شرطي import وrequire. أما البدائل القديمة فهي: main (لـ CJS) وmodule (لـ ESM). استخدم الامتدادين .mjs و.cjs أو type: module لتحديد الصيغة صراحةً. اختبر الصيغتين باستخدام واجهة سطر أوامر node بعد البناء. وانتبه إلى مشكلة الحزمة مزدوجة الصيغة عند استخدام حالة singleton.
الأسئلة الشائعة
هل درس «مخرجات الحزم المزدوجة ESM وCJS» مجاني؟
نعم — نص درس «مخرجات الحزم المزدوجة ESM وCJS» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة React Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Academy 4 دروس في المجموع.
ماذا ستتعلم في «مخرجات الحزم المزدوجة ESM وCJS»؟
أنشئ إصدارات ES module وCommonJS مع الضبط الصحيح للحقل exports في package.json تتمرن على React Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ React Academy؟
لا تُشترط خبرة سابقة. React Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «مخرجات الحزم المزدوجة ESM وCJS»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس React Academy هذا؟
نعم. كل درس في React Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- التجميع باستخدام Rollup وtsup للمكتبات
- مخرجات الحزم المزدوجة ESM وCJS
- التبعيات النظيرة وTree Shaking
- النشر إلى npm والإصدارات الدلالية