وقتی داریم از NodeJs برای توسعه اپلیکیشنهامون استفاده میکنیم، معمولا باید کلی وابستگی (Dependency) رو توسط NPM، نصب و یا (حذف و دوباره نصب) کنیم. حالا بسته به اینکه تعداد وابستگیهای پروژمون چقدره، این فرآیند میتونه کند و انتظار براش خسته کننده باشه.
توی این یادداشت نگاهی به npm ci و مزایای اون نسبت به npm install میندازیم و کمی هم در مورد اهمیت وجودی فایل package-lock.json صحبت میکنیم.
وقتی میخوایم یک پکیج خاص رو نصب کنیم معمولا این دستور رو استفاده میکنیم:
npm install highcharts --save
وقتی این دستور رو اجرا میکنیم، NPM میاد highcharts رو به فایل package.json اضافه میکنه (اگه از قبل موجود نباشه) و بعد پکیجش رو توی دایرکتوری node_modules نصب میکنه.
وقتی از npm استفاده میکنیم، یه فایل به نام package-lock.json هم توی پروژه به صورت اتوماتیک ایجاد میشه. که این فایل تمام وابستگیهایی که نصب کردیم و وابستگیهای غیر مستقیم رو ردیابی (Track) میکنه.در واقع این فایل تضمین میکنه که هر وقت npm install بزنیم، نسخه پکیجها دقیق همونی خواهند بود که ما قبلا نصب کرده بودیم و تغییری نمیکنن.
قبل از اینکه بخوام وارد بحث اصلی بشم، اول بیاید اهمیت فایل pakcage-lock.json رو بررسی کنیم.
اهمیت فایل pakcage-lock.json
واسه اینکه بهتر متوجه بشید فرض کنید این فایل package.json رو ایجاد کردیم:
{ "name": "test", "version": "1.0.0", ... "devDependencies": { "highcharts": "9.0.0" } }
و هنوز فایل package-lock.json وجود نداره. وقتی دستور npm install رو بزنیم فایل package-lock.json هم اتوماتیک ایجاد میشه و محتوای زیر هم داخلش قرار میگیره:
"highcharts": { "version": "9.0.0"
حالا فرض کنید این دوتا فایل رو کپی کردیم و توی یک دایرکتوری دیگه قرار دادیم، و یک تغییر کوچک هم تو نسخه پکیج ایجاد کردیم و اولش از ( ^ ) استفاده کردیم: یعنی "9.0.0^".
( اگه معنی ^ یا ~ رو توی نسخه پکیجها نمیدونید این لینک رو مطالعه کنید.)
اصل داستان اینجاست :)
الان اگه فایل pakcage-lock.json وجود نداشته باشه وقتی دستور npm install رو بزنیم، فایل package.json تغییر میکنه و نسخه 9.1.0 رو به جای 9.0.0 نصب میکنه
{ "name": "test", "version": "1.0.0", ... "devDependencies": { "highcharts": "^9.1.0" } }
اما اگه pakcage-lock.json وجود داشت، NPM لیست پکیجهارو از اون میخوند و دقیقا همون نسخه 9.0.0 رو نصب میکرد. اینجاست که اهمیت این فایل مشخص میشه :)
خب حالا بریم سراغ بحث اصلیمون.
خیلی وقتا پیش میاد که ما مجبور میشیم به دلایلی node_modules رو حذف و تمام پکیج هارو مجددا نصب کنیم. که معمولا دستور زیر رو استفاده میکنیم:
rm -rf node_modules && npm install
این دستور کار میکنه اما دستور زیر خیلی بهتره.
npm ci
چرا ؟ دستور npm ci میاد به صورت خودکار node_modules رو حذف میکنه و تمام نیازمندیهای پروژه رو دوباره نصب میکنه.
این دستور معمولا سریعتر از npm install عمل میکنه. چون مستقیم میره فایل package-lock.json رو میخونه و از روی اون تمام پکیجهارو نصب میکنه که باعث میشه سرعت نصب بالاتر بره.
مثالی از تفاوت سرعت نصب دو دستور npm ci و npm install:
// example repo: https://github.com/vmware/clarity/tree/master/packages/core npm install - 42.116s npm ci - 24.629s
اگه دستور npm ci تفاوتی توی لیست نیازمندیهای موجود توی فایل package-lock.json و package.json پیدا کنه، خطا میده. که این خوبه. باز چرا؟
وقتی دستور npm install رو میزنیم فایل package-lock.json هم بروزرسانی میشه حتی اگه تفاوتی تو نسخه پکیجها وجود داشته باشه :(
اما وقتی دستور npm ci رو بزنیم دیگه خیالمون راحته که همیشه دقیقا همون نسخههایی نصب میشن که قبلا نصب کرده بودیم.
امیدوارم این یادداشت هم براتون مفید بوده باشه.
خیلی خوشحال میشم اگه ابهام یا اشکالی وجود داره برام کامنت کنید که اصلاح کنم.