Bugsy يشرح
الترقيم الدلالي للإصدارات
ماذا يَعِد به الرقم 2.4.1 فعلًا، ولماذا تسمح ^ و~ بتحديثات مختلفة، وما وظيفة المفاتيح التي ستقابلها كثيرًا في package.json.
6 دقائق 3 ألعاب
- الحزم
- JavaScript
- الأدوات
افتح أي ملف package.json وسترى إصدارات مثل 2.4.1. إصدار الحزمة نفسها يتكوّن دائمًا من ثلاثة أرقام، لا من رقم واحد مثل «الإصدار 7». لماذا ثلاثة؟
لأن رقم الإصدار ليس عدّادًا، بل وعد لكل من يستخدم شيفرتك: يخبرهم بما تغيّر وهل الترقية آمنة. هذه الفكرة اسمها الترقيم الدلالي للإصدارات (semantic versioning)، واختصارها semver.
ثلاثة أرقام، ثلاثة وعود
يرتفع MAJOR (الرقم الرئيسي) عندما تكسر شيئًا: تغيّر اسم دالة، أو تحذف خيارًا، أو تغيّر ما يُرجعه استدعاء. وعلى المستخدمين أن يعدّلوا شيفرتهم قبل الترقية.
يرتفع MINOR (الرقم الثانوي) عندما تضيف ميزة دون أن تكسر شيئًا. الشيفرة القديمة تبقى تعمل.
يرتفع PATCH (رقم الإصلاح) عندما تُصلح خطأً (bug) دون أن يتغيّر شيء آخر على المستخدمين.
رفع أي رقم يُعيد الأرقام التي تليه إلى 0. ميزة جديدة على 2.4.1 تعطي 2.5.0 لا 2.5.1.
جرّب
النطاقات: أي التحديثات تقبل؟
نادرًا ما تحدّد إصدارًا واحدًا بعينه في package.json، بل تكتب نطاقًا (range)، أي قاعدة تحدّد الإصدارات المقبولة. عندما تشغّل npm install some-package يحفظ npm آخر إصدار منشور وأمامه ^، مثل ^1.4.2.
1.4.2 بلا علامة (إصدار محدّد) يعني هذا الإصدار ولا شيء غيره.
^1.4.2 بعلامة القبعة (caret) يعني أي إصدار من 1.4.2 حتى 2.0.0 من دون 2.0.0 نفسه. تصلك الميزات والإصلاحات الجديدة، أما MAJOR الجديد فلا يصلك أبدًا.
~1.4.2 بعلامة التيلدا (tilde) يعني من 1.4.2 حتى 1.5.0 من دون 1.5.0 نفسه. إصلاحات الأخطاء فقط.
القبعة تصبح حذرة تحت 1.0.0. فمعيار semver نفسه لا يَعِد بشيء هناك، لذلك يتبع npm عُرفًا متّفقًا عليه: في 0.x يتصرّف MINOR كأنه MAJOR وقد يكسر الشيفرة، بينما يحمل PATCH الميزات والإصلاحات. والقبعة تتبع هذا العُرف: النطاق ^0.2.3 يعني >=0.2.3 <0.3.0، والنطاق ^0.0.3 لا يسمح إلا بالإصدار 0.0.3.
جرّب
اختبار سريع
لماذا يوجد ملف القفل؟
لكن في النطاقات فخًّا. لنقل إنك تثبّت الحزمة اليوم بالنطاق ^1.4.2 فتحصل على 1.4.2، وبعد شهر يصدر 1.5.0. من دون ملف قفل، سيحصل زميلك الذي يثبّت المشروع بعدها على 1.5.0. ملف package.json واحد، وشيفرة مختلفة.
ملف القفل (lock file)، أي package-lock.json، يحلّ هذه المشكلة. يسجّل الإصدار الدقيق لكل حزمة في الشجرة، بما فيها تبعيات (dependencies) تبعياتك، فيثبّت كل جهاز الشيء نفسه.
لذلك احفظه في المستودع (commit). وعلى الخوادم وفي التكامل المستمر (CI)، أي الجهاز الذي يختبر كل دفعة (push) من الشيفرة، ثبّت بالأمر npm ci: يثبّت بالضبط ما في ملف القفل، وإن اختلف ملف القفل عن package.json يتوقف برسالة خطأ بدل أن يحدّث شيئًا بصمت.
لكن ملف القفل يحدّد الإصدارات لمشروعك أنت فقط. أما من يثبّت حزمتك فيحصل على إصدارات تُختار من نطاقاتك ومن ملف القفل الخاص به، لأن npm يتجاهل ملف package-lock.json الموجود داخل أي تبعية.
git add package.json package-lock.jsonnpm ci
على جهازك: احفظ الملفين معًا في المستودع. وفي CI: ثبّت بالأمر npm ci.
جولة في package.json
كل مفتاح في package.json يجيب عن سؤال واحد عن مشروعك. هذه مكتبة مكوّنات React صغيرة. اختر مفتاحًا لترى وظيفته.
جرّب
اختبار سريع
سؤال الزعيم
حان وقت جمع كل ما تعلّمته.
اختبار سريع
انتهيت من القراءة؟
حلّ 3 اختبارات سريعة بعد لتنهي.