4 دقیقه مطالعه
SemVer توی npm به زبان ساده
توی این پست یاد میگیریم علامتهای ^ و ~ توی نسخهگذاری npm دقیقاً چه کاری انجام میدن و npm install چطور باهاشون رفتار میکنه.
مقدمه: نسخهبندی معنایی (Semantic Versioning) چیه؟
ما موقع ریلیز کردن یا زدن hotfix، از یه ساختار مشخص برای نسخهها استفاده میکنیم. مثلا 1.0.0 یا 1.0.1. این ساختار بر پایه یه روش استاندارد به اسم Semantic Versioning یا همون نسخهبندی معنایی ساخته شده.
این عددها نشون میدن که نسخه فعلی محصول ما چیه و چه تغییری توش اتفاق افتاده. وقتی از نسخهبندی معنایی استفاده میکنیم، بقیه توسعهدهندهها راحتتر میفهمن که با آپدیت کردن برنامه قراره چیزی خراب بشه یا نه.
درک نسخهبندی معنایی
فرمت کلی نسخهبندی به صورت MAJOR.MINOR.PATCH هست. یعنی سهتا عدد که با نقطه جدا شدن:
- نسخه Patch (عدد سمت راست): وقتی فقط یه باگ رو فیکس کردی، بدون اینکه تغییری توی قابلیتها یا ساختار اصلی برنامه بدی. مثلا از
1.0.0میرسیم به1.0.1. - نسخه Minor (عدد وسط): وقتی یه قابلیت جدید اضافه میکنی ولی تغییری که دادی باعث نمیشه چیزی بترکه. مثلاً از
1.0.1میره به1.1.0. - نسخه Major (عدد سمت چپ): وقتی یه تغییری میدی که نسخه قبلی باهاش سازگار نیست. مثلاً از
1.2.3میره به2.0.0.
نسخه Pre-release
اگه بخوای نسخه آزمایشی منتشر کنی (مثل alpha یا beta)، میتونی یه خط تیره بذاری:
1.0.0-alpha
1.0.0-beta
1.2.0-rc.1
شروع یه پروژه
خیلیها پروژههاشون رو با نسخه 0.1.0 شروع میکنن. وقتی پروژه آماده بشه برای انتشار رسمی، نسخه رو میزارن 1.0.0.
SemVer توی npm یعنی چی؟
خب، توی npm هم همین ساختار نسخهبندی معنایی استفاده میشه. ولی یه چیز مهمتر اینه که توی فایل package.json میتونی تعیین کنی چه نسخههایی از یه پکیج رو قبول داری. مثلاً اینو دیدی؟
"axios": "^1.2.3"
یا
"react": "~18.2.0"
اینا نشون میدن که چه نسخههایی مجازن نصب بشن. حالا بریم ببینیم این علامتها (^, ~, یا بدون علامت) دقیقاً چیکار میکنن.
^ (Caret) یعنی چی؟
علامت ^ میگه که نسخههایی از پکیج رو میخوای که تغییرات Major نداشته باشن ولی Minor و Patch میتونن آپدیت بشن.
مثلاً:
"axios": "^1.2.3"
یعنی:
- 1.2.4 ✅
- 1.3.0 ✅
- 1.9.9 ✅
- 2.0.0 ❌
نکته: اگه نسخه از 1.0.0 پایینتر باشه (مثلاً ^0.2.3) اونوقت فقط Patch اجازه داره تغییر کنه چون تا قبل از نسخه 1، تغییرات Minor هم ممکنه ناسازگار باشن.
~ (Tilde) یعنی چی؟
علامت ~ یعنی فقط اجازه بده Patch آپدیت بشه، نه Minor و نه Major.
مثلاً:
"react": "~18.2.0"
یعنی:
- 18.2.1 ✅
- 18.2.5 ✅
- 18.3.0 ❌
- 19.0.0 ❌
بدون علامت (Exact Version)
وقتی مینویسی:
"lodash": "4.17.21"
یعنی فقط همین نسخه نصب شه. هیچ نسخه دیگهای، حتی Patch جدیدتر، نصب نمیشه.
حالا وقتی npm install میزنی چی میشه؟
وقتی npm install رو میزنی، npm میره بر اساس نسخههایی که توی package.json نوشتی، بررسی میکنه آخرین نسخهای که با اون محدودیتها سازگاره چیه و همونو نصب میکنه.
مثلاً اگه نوشتی:
"vue": "^3.2.0"
و الان نسخهی 3.3.1 منتشر شده، ولی هنوز 4.0.0 نیومده، npm نسخهی 3.3.1 رو نصب میکنه چون با ^3.2.0 سازگاره.
فرق بین npm install و npm install package@version
وقتی npm install ساده میزنی، npm به package.json نگاه میکنه و نسخهها رو طبق قوانین بالا انتخاب میکنه.
ولی وقتی بزنی:
npm install react@18.2.0
یعنی دقیقاً همون نسخه رو نصب کن و نسخه رو هم توی package.json مینویسه.
فایل package-lock.json چیکار میکنه؟
این فایل دقیقاً مشخص میکنه کدوم نسخهها نصب شدن. حتی اگه محدودیتت باز باشه (^)، ولی وقتی یه بار نصب کردی، نسخه دقیقش توی package-lock.json میمونه که توی نصبهای بعدی (روی دستگاه دیگه یا CI/CD) همون نسخه بیاد بالا و همه چیز قابل پیشبینی باشه.
پس اگه یه روز دیدی با اینکه پکیجت "^1.0.0" بود ولی نسخهی 1.9.9 نصب شد، تعجب نکن! همهچی طبق برنامهست 😄
📖 اگر با مشکل Memory Leak در Webpack هنگام استفاده از hash مواجه شدهاید، پست مشکل Memory Leak هنگام استفاده از hash در Webpack رو بخونید.
نوشتههای مرتبط
شاید این نوشتهها هم برات مفید باشن
مشکل Memory Leak هنگام استفاده از hash در Webpack
در این مقاله یک مشکل رایج Memory Leak در Webpack هنگام استفاده از contenthash در محیط توسعه بررسی میشود و راهحل عملی ارائه میدهیم.
خواندن نوشته ←Semantic Versioning
مقدمهای سریع بر نسخهبندی معنایی چیه و چرا ازش استفاده میکنیم.
خواندن نوشته ←