پیش از این گفتیم که پکیج های نیازمندی در npm، می توانند پنج نوع مختلف داشته باشند. این پنج نوع عبارتند از:
• dependencies (normal dependencies)
• devDependencies
• optionalDependencies
• peerDependencies
• bundledDependencies
قبلاً در مورد نیازمندی های معمولی و نیازمندی های زمان توسعه در مقاله ی پکیج npm را بصورت dependency نصب کنیم یا devDependency؟ از سری مقالات آموزش npm صحبت کردیم و گفتیم که این دو نوع، نیازمندی هایی هستند که بیش از سایرین مورد استفاده قرار می گیرند. اما سه نوع دیگر چه زمانی کاربرد دارند؟ در مقاله پیش رو در این باره بیشتر توضیح داده ایم.
optionalDependency
همانطور که از نامش پیداست، این نوع نیازمندیها دلخواه هستند. به این معنی که اگر npm موفق به نصب آنها نشد، اروری نخواهد داد، صرفاً از نصب آن صرف نظر می کند (skip میکند) و در ترمینال اخطار(warning) میدهد. با اضافه کردن گزینه save-optional--
به npm install
، پکیج مورد نظر به لیست optionalDependencies فایل package.json اضافه خواهد شد. معمولاً پکیجهایی را بعنوان optionalDependency نصب میکنیم که الزاماً روی همه سیستمعاملها کار نمیکنند، یا برای حالتی که این پکیجها روی پروژه نصب نیستند برنامه خاصی داریم(مثلاً در کد پروژه، صراحتاً مشخص کردهایم که اگر آن پکیج نبود، راه حل جایگزینی بعنوان fallback اجرا شود)
فرض کنیم فایل package.json
پروژهای به صورت زیر است. دو پکیج غیرواقعی که در npm وجود ندارند، با نامهای fake-package1 و fake-package2، به ترتیب بعنوان optionalDependency و dependency مشخص شدهاند:
در این حالت اگر دستور npm install
را اجرا کنیم، خواهیم دید که مرحله نصب fake-package1 بدون مشکل skip میشود و npm در این مورد به یک اخطار بسنده میکند، ولی به ازای fake-package2 ارور خواهیم داشت:
peerDependency
با استفاده از این نوع نیازمندیها، مشخص میکنیم که پکیج ما به نسخه خاصی از یک پکیج نیاز دارد. در این مقاله به این نوع نیازمندی، «نیازمندیِ همتا» گفتهایم. برای اضافه کردن نسخهای از یک پکیج بعنوان نیازمندی همتا، لازم است که بصورت دستی فایل package.json
را تغییر دهیم و نسخه پکیجمان را به لیست peerDependencies اضافه کنیم.
با استفاده از نیازمندی همتا، نشان میدهیم که پروژه به نسخه خاصی از یک پکیج وابسته است، ولی هیچ الزامی برای نصب آن ایجاد نمیکنیم.
بطور دقیقتر، وقتی در فایل package.json
پروژهای، یک پکیج بعنوان نیازمندیِ همتا در نظر گرفته میشود، در واقع داریم به npm میگوییم:
1. کد پروژه ما سازگار با نسخه مشخص شده از این پکیج است.
2. وقتی کاربر دستور npm install
را اجرا میکند، اگر در حال حاضر نسخه مشخص شده از پکیج در فولدر node_modules
وجود دارد، در رابطه با این پکیج هیچ کاری انجام نده.
3. وقتی کاربر دستور npm install
را اجرا میکند، اگر این پکیج در node_modules
وجود ندارد، و همچنین اگر این پکیج در node_modules
وجود دارد، ولی نسخه آن با نسخه مشخص شده متفاوت است، بدون این که نسخه مشخص شده را به پروژه اضافه کنی، تنها یک اخطار به کاربر نشان بده.
همانطور که میبینیم، صرفِ مشخص کردن شماره نسخه یک پکیج در قسمت peerDependencies باعث نمیشود که دستور npm install
آن را نصب کند.
نیازمندیهای همتا در مواقع خاصی کاربرد دارند. فرض کنید داریم کامپوننتی را بر اساس انگولار نسخه 5 مینویسیم، و بعداً هم میخواهیم در پروژهای از آن استفاده کنیم که خود از انگولار نسخه 6 استفاده میکند. در این حالت هم کامپوننتِ در دست طراحیِ ما به پکیج angular/core نیاز خواهد داشت و هم پروژه انگولاری که قرار است از کامپوننت ما استفاده کند. اگر برایمان مهم است که در codebase پروژه، دو نسخه متفاوت از angular/core نصب نشود، استفاده از نیازمندی همتا به کمکمان میآید و میتوانیم angular/core را بعنوان نیازمندی همتای کامپوننت در نظر بگیریم. به این ترتیب هم وابستگیِ کامپوننتمان به نسخه خاصی از angular/core را مشخص میکنیم، و هم از نصب نسخه متفاوت در پروژه جلوگیری میکنیم.
پلاگینهایی که برای فریمورکهایی نظیر angular و react و .. مینویسیم، از جمله مثالهای معروف کاربرد نیازمندیهای همتا هستند.
قبلاً در این سری مقالات، بطور کامل تشریح کردیم که npm با نسخههای متفاوت یک پکیج چهطور رفتار میکند. گفتیم که اگر نیازمندیهای یک پروژه، هر یک به نسخه متفاوتی از یک پکیج نیاز داشته باشند، یکی از نسخههای این پکیج بعنوان sibling سایر پکیجها در فولدر node_modules
نصب میشود و الباقیِ نسخهها، در فولدر node_modules
پکیجهای وابسته به آن. حال اگر این نسخههای متفاوت از یک پکیج، با یکدیگر ناسازگاری(conflict) داشته باشند، لازم است طراحان پکیجهای وابسته به پکیج ناسازگار، این موضوع را در نظر بگیرند و پکیج ناسازگار را بعنوان نیازمندی همتای خود تعریف کنند.
پس شرط اصلی استفاده از نیازمندی همتا، امکان بروز ناسازگاری میباشد. بنابراین اگر نسخههای متفاوت از یک پکیج، با یکدیگر ناسازگاری نداشتند، میتوانند بدون هیچ مشکلی در کنار یکدیگر نصب شوند و نیازی هم به استفاده از نیازمندی همتا نیست.
بطور کلی، در موارد زیر میتوان از نیازمندی همتا بهره گرفت:
1. وقتی حضور چند نمونه از یک پکیج (با نسخههای متفاوت) باعث بروز ناسازگاری میشود.
2. وقتی پکیج نیازمندی در interface دیده میشود.
3. وقتی میخواهیم برنامهنویسی که از پکیج ما استفاده میکند، خودش تصمیم بگیرد که چه نسخهای از پکیج مورد نظر را نصب کند.
لینک زیر آدرس یک ویدیوی کوتاه و مفید برای درک بهتر توضیحات بالاست:
https://www.youtube.com/watch?v=ChDG13gsDnw
این هم یک مقاله عالی برای درک بهتر peerDependency ها:
https://indepth.dev/npm-peer-dependencies/
bundledDependency
همانطور که قبلاً گفتیم، وقتی در دایرکتوری اصلی پروژه دستور npm pack
را وارد میکنیم، نسخه bundle شدهای از آن در قالب یک فایل tarball ایجاد میشود.(مثلاً فایلی با فرمت .tgz) اگر در فایل package.json
و در قسمت bundledDependencies نام هیچ پکیجی را وارد نکرده باشیم، و از دستور npm pack
استفاده کنیم، مشاهده میکنیم که در فایل .tgz نهایی، فولدر node_modules
وجود ندارد و به این ترتیب هیچیک از نیازمندیهای پروژه، در نسخه bundled نیستند.مقدار مشخصه bundledDependencies در فایل package.json، یک آرایه از نام پکیجهای پروژه است که میخواهیم موقع bundle کردن پروژه، در نسخه فشردهمان حضور داشته باشند. وقتی نام پکیجی در bundledDependencies میآید، به npm میگوید که به ازای دستور npm pack، در فایل فشردهای که تولید میکند، یک فولدر node_modules ایجاد کند که پکیج(های) مشخص شده در bundledDependencies و تمامی نیازمندیهای آن(ها) در این فولدر حضور داشته و نصب باشند.
لازم به ذکر است اگر نام پکیجی در bundledDependencies باشد، آن پکیج به ازای دستور npm install
نصب خواهد شد. در قسمت bundledDependencies امکان تعیین نسخه پکیج نیازمندی نیست و برای این کار باید از مشخصه dependencies استفاده کنیم.
بطور کلی موارد استفاده از bundledDependency ها عبارتند از:
1. وقتی داریم از یک پکیج در پروژه استفاده میکنیم که آن پکیج در رجیستری npm وجود ندارد، بنابراین اگر صرفاً در قسمت dependencies باشد، بعداً نمیتوان آن را دانلود و نصب کرد، و از این رو حتماً باید در پکیج حضور داشته باشند.
2. وقتی که بعداً میخواهیم از پروژه خودمان بعنوان module استفاده کنیم.
3. وقتی که میخواهیم پکیجی را به همراه پکیجمان منتشر کنیم.
شما همراهان عزیز سکان آکادمی می توانید سؤالات خود درباره مباحث پیشرفته npm را در تالار گفتگو با کارشناسان سکان آکادمی در میان بگذارید. همچنین می توانید نظرات خود را در قالب کامنت منتقل کنید.