در هنگام شروع یک پروژه یا نصب یک پکیج یا فریمورک گاها ممکن است یک چیز جدیدی را ببینیم و برایمان سوال باشد، مثلا شما می خواهید یک پیکج جاوا اسکریپت را نصب کنید و در هنگام نصب با سه تا پکیج منیجر مختلف روبه رو شوید و برایتان سوال پیش می آید این پکیج منیجر ها چه تفاوتی با هم دارند ما نیز در این مقاله می خواهیم با همدیگر این پکیج منیجر ها را با هم دیگر مقایسه کنیم، پس با ما همراه باشید.
امروزه سه بازیگر اصلی در زمینه package managers وجود دارد:
- npm
- Yarn - به زودی خواهیم دید که Yarn می تواند به Yarn Classic (< v2) یا نسخه مدرن تر آن Yarn Berry (≥ v2) اشاره کند.
- Performant npm (pnpm)
تقریباً، ما به برابری ویژگیها در بین همه package managers دست یافتهایم، بنابراین به احتمال زیاد شما تصمیم میگیرید از کدام package manager بر اساس نیازهای غیرعملکردی، مانند سرعت نصب، مصرف ذخیرهسازی، یا نحوه تطابق آن با جریان کاری فعلیتان، استفاده کنید.
البته نحوه استفاده از هر پکیج منیجر متفاوت است، اما همه آنها مجموعه ای از مفاهیم اصلی را به اشتراک می گذارند. با هر یک از این پکیج منیجرها می توانید کارهای زیر را انجام دهید:
- مدیریت و نوشتن متادیتا
- نصب دسته ای یا به روز رسانی همه وابستگی ها
- افزودن، به روز رسانی و حذف وابستگی ها
- اسکریپت ها را اجرا کنید
- پکیج ها را منتشر کنید
- انجام کار های امنیتی
با وجود این برابری، package managersها در ظاهر متفاوت هستند. به طور سنتی، npm و Yarn وابستگی هایی را در یک پوشه node_modules نصب می کنند. اما این استراتژی حل وابستگی خالی از انتقاد نیست.
بنابراین، pnpm مفاهیم جدیدی را برای ذخیره سازی وابستگی ها در یک پوشه تودرتو node_modules
معرفی کرده است. Yarn Berry با حذف کامل node_modules
با حالت Plug'n'Play (PnP) خود حتی فراتر می رود.
تاریخچه مختصری از package managers جاوا اسکریپت
اولین package manager ای که تا به حال منتشر شد npm بود، در ژانویه 2010. اصول اصلی نحوه کار package managers امروزی را ایجاد کرد.
اگر npm بیش از 10 سال است که وجود دارد، اصلاً چرا جایگزینی وجود دارد؟ در اینجا چند دلیل اصلی وجود دارد:
- الگوریتمهای تفکیک وابستگی مختلف با ساختارهای مختلف پوشه node_modules (تودرتو در مقابل.flat و node_modules در مقابل حالت PnP)
- پشتیبانی متفاوت برای میزبانی(hoisting)، که پیامدهای امنیتی داردفرمتهای مختلف فایل lock، که هر کدام پیامدهای عملکردی دارند
- رویکردهای مختلف برای ذخیره پکیج ها بر روی دیسک، که پیامدهایی بر کارایی فضای دیسک دارد
- پشتیبانی متفاوت از پروژههای چند پکیج (معروف به فضاهای کاری) که بر قابلیت نگهداری و سرعت مونورپوهای بزرگ تأثیر میگذارد.
- نیازهای متفاوت به ابزارها و دستورات جدید که هر کدام دارای مفاهیم DX هستند
- در همین راستا، نیازهای متفاوتی برای توسعه پذیری از طریق افزونه ها و ابزارهای جامعه وجود دارد
- درجات مختلف پیکربندی و انعطاف پذیری
بیایید به تاریخچه مختصری بپردازیم که چگونه این نیازها پس از برجسته شدن npm شناسایی شدند، چگونه Yarn Classic برخی از آنها را حل کرد، چگونه pnpm این مفاهیم را گسترش داد و چگونه Yarn Berry به عنوان جانشین Yarn Classic سعی کرد مجموعه قالب را بشکند. با این مفاهیم و فرآیندهای سنتی.
npm، پیشگام
npm پدر package managers است. به اشتباه، بسیاری از مردم معتقدند npm مخفف Node Package Manager است اما اینطور نیست. با این وجود، با زمان اجرا Node.js همراه است.
انتشار آن یک انقلاب بود زیرا تا آن زمان، وابستگی های پروژه به صورت دستی دانلود و مدیریت می شدند. مفاهیمی مانند فایل package.json
با فیلدهای متا دیتا آن (به عنوان مثال، devDependencies
)، ذخیره وابستگی ها در node_modules
، اسکریپت های سفارشی، رجیستری پکیج های عمومی و خصوصی و موارد دیگر، همگی توسط npm معرفی شدند.
در سال 2020، GitHub npm را به دست آورد، بنابراین در اصل، npm اکنون تحت نظارت مایکروسافت است. در زمان نگارش این مقاله، جدیدترین نسخه اصلی v9 است که در اکتبر 2022 منتشر شد.
Yarn (v1 / Classic)، مسئول بسیاری از نوآوری ها است
فیسبوک در یک پست وبلاگی اکتبر 2016، تلاش مشترکی با گوگل و چند نفر دیگر را برای ایجاد یک package manager جدید اعلام کرد که مشکلات مربوط به ثبات، امنیت و عملکردی را که npm در آن زمان داشت، حل کند. آنها نام جایگزین Yarn را نامگذاری کردند که مخفف Yet Another Resource Negotiator است.
اگرچه آنها طراحی معماری Yarn را بر اساس بسیاری از مفاهیم و فرآیندهایی که npm ایجاد کردند، پایه گذاری کردند، Yarn در انتشار اولیه خود تأثیر زیادی بر چشم انداز مدیریت پکیج داشت. برخلاف npmکه Yarn عملیات را موازی کرد تا فرآیند نصب را تسریع بخشد، که برای نسخههای اولیه npm یک نقطه دردناک اصلی بود.
Yarn نوار را برای DX، امنیت و عملکرد بالاتر قرار داد و همچنین مفاهیم بسیاری را ابداع کرد، از جمله:
- پشتیبانی مونورپو بومی(در ادامه توضیح داده خواهد شد)
- نصب های با آگاهی از حافظه پنهان
- ذخیره آفلاین
- قفل کردن فایل ها
Yarn v1 در سال 2020 وارد حالت تعمیر و نگهداری شد. از آن زمان، خط v1.x به عنوان میراث در نظر گرفته شد و به Yarn Classic تغییر نام داد. جانشین آن، Yarn v2 یا Berry، اکنون شاخه توسعه فعال است.
pnpm، سریع و کارآمد از نظر دیسک
نسخه 1 pnpm در سال 2017 توسط زولتان کوچان منتشر شد. این یک جایگزین برای npm است، بنابراین اگر پروژه npm دارید، می توانید بلافاصله از pnpm استفاده کنید!
مشکل اصلی سازندگان pnpm با npm و Yarn ذخیره اضافی وابستگی هایی بود که در پروژه ها استفاده می شد. اگرچه Yarn Classic نسبت به npm مزایای سرعت داشت، اما از همان رویکرد وضوح وابستگی استفاده کرد که برای سازندگان pnpm ممنوع بود: npm و Yarn Classic از هاستینگ برای صاف کردن node_modules
خود استفاده کردند.
به جای بالا بردن، pnpm یک استراتژی حل وابستگی جایگزین را معرفی کرد: ذخیرهسازی آدرسپذیر محتوا. این روش منجر به یک پوشه تودرتو node_modules
می شود که پکیج ها را در یک مکان گلوبال در پوشه اصلی شما (/pnpm-store./~
) ذخیره می کند. هر نسخه از یک وابستگی به صورت فیزیکی فقط یک بار در آن پوشه ذخیره می شود، که یک منبع واحد از حقیقت را تشکیل می دهد و مقدار زیادی از فضای دیسک را ذخیره می کند.
این امر از طریق طرحبندی node_modules
، با استفاده از پیوندهای نمادین برای ایجاد یک ساختار تودرتو از وابستگیها، که در آن هر فایل از هر پکیج در داخل پوشه یک لینک سخت به فروشگاه است، به دست میآید. نمودار زیر از اسناد رسمی این موضوع را روشن می کند.
تأثیر pnpm را می توان در گزارش 2021 آنها مشاهده کرد: رقبا می خواهند از مفاهیم نصب pnpm استفاده کنند، مانند ساختار node_modules به هم پیوسته و مدیریت دیسک کارآمد پکیج ها به دلیل نوآوری هایشان در ذخیره سازی آدرس پذیر محتوا.
Yarn (v2، Berry)، چرخ را با Plug’n’Play دوباره اختراع می کند
Yarn 2 در ژانویه 2020 منتشر شد و به عنوان یک ارتقاء اصلی از Yarn اصلی اعلام شد. تیم Yarn شروع به معرفی آن به عنوان Yarn Berry کرد تا مشخص کند که اساساً یک package manager جدید با پایه کد جدید و اصول جدید است
.
نوآوری اصلی Yarn Berry رویکرد Plug'n'Play (PnP) آن است که به عنوان یک استراتژی برای تعمیر node_modules به وجود آمد. به جای تولید node_modules
، یک فایل pnp.cjs.
با جداول جستجوی وابستگی تولید می شود که می تواند کارآمدتر پردازش شود زیرا به جای ساختار پوشه تودرتو، یک فایل واحد است. علاوه بر این، هر پکیج به عنوان یک فایل zip در داخل پوشه /yarn/cache.
ذخیره می شود که فضای دیسک کمتری را نسبت به پوشه node_modules
اشغال می کند.
همه این تغییرات، و به سرعت، پس از انتشار به جنجال زیادی منجر شد. تغییرات شکستن PnP، نگهبانان را ملزم می کرد تا پکیج های موجود خود را به روز کنند تا با آن سازگار باشند. رویکرد کاملاً جدید PnP به طور پیشفرض مورد استفاده قرار گرفت، و بازگشت به node_modules
در ابتدا ساده نبود، که باعث شد بسیاری از توسعهدهندگان برجسته آشکارا از Yarn 2 به دلیل عدم شرکت در آن انتقاد کنند.
تیم Yarn Berry از آن زمان تاکنون در نسخههای بعدی خود با بسیاری از مشکلات مقابله کرده است. برای رفع ناسازگاری PnP، تیم راههایی برای تغییر آسان حالت عملکرد پیشفرض ارائه کرد. با کمک یک پلاگین node_modules، فقط یک خط پیکربندی برای استفاده از رویکرد node_modules
سنتی مورد نیاز بود.
علاوه بر این، اکوسیستم جاوا اسکریپت در طول زمان پشتیبانی بیشتری از PnP ارائه کرده است، همانطور که در این جدول سازگاری مشاهده می کنید، و برخی از پروژه های بزرگ به سمت استفاده از Yarn Berry حرکت کرده اند.
اگرچه Yarn Berry کاملاً جوان است، اما در حال حاضر نیز بر چشم انداز مدیریت پکیج تأثیر گذاشته است - pnpm رویکرد PnP را در اواخر سال 2020 اتخاذ کرد.
جریان کار نصب
ابتدا باید یک package manager بر روی سیستم های محلی و CI/CD هر توسعه دهنده نصب شود.
npm
npm با Node.js ارسال می شود، بنابراین نیازی به مرحله اضافی نیست. علاوه بر دانلود نصب کننده Node.js برای سیستم عامل خود، استفاده از ابزارهای CLI برای مدیریت نسخه های نرم افزار به یک روش معمول تبدیل شده است. در زمینه Node، Node Version Manager (nvm) یا Volta به ابزارهای بسیار مفیدی تبدیل شده اند.
Yarn Classic و Yarn Berry
شما می توانید Yarn 1 را به روش های مختلف نصب کنید، به عنوان مثال، به عنوان یک پکیج npm با npm i -g yarn$
.
برای مهاجرت از Yarn Classic به Yarn Berry، روش توصیه شده این است:
- Yarn Classic را به آخرین نسخه 1.x نصب یا به روز کنید
- از دستور
yarn set version
برای ارتقا به آخرین نسخه مدرن استفاده کنید:yarn set version berry$
با این حال، روش توصیه شده برای نصب Yarn Berry از طریق Corepack است.
Corepack توسط افراد Yarn Berry ساخته شده است. این ابتکار در ابتدا package manager مدیریت (pmm) نامگذاری شد و با Node در LTS v16 ادغام شد.
با کمک Corepack، نیازی نیست که مدیریت پکیج های جایگزین npm را به طور جداگانه نصب کنید، زیرا Node شامل Yarn Classic، Yarn Berry و pnpm باینری ها به عنوان shims است. این شیمها به کاربران اجازه میدهند تا دستورات Yarn و pnpm را بدون نیاز به نصب ابتدا و بدون بهم ریختگی توزیع Node اجرا کنند.
Corepack با Node.js ≥ v16.9.0 از پیش نصب شده است. با این حال، برای نسخه های قدیمی Node، می توانید آن را با استفاده از npm install -g corepack$
نصب کنید.
قبل از استفاده، ابتدا Corepack را فعال کنید. مثال نشان می دهد که چگونه آن را در Yarn Berry v3.1.1 فعال کنید.
# you need to opt-in first
$ corepack enable
# shim installed but concrete version needs to activated
$ corepack prepare yarn@3.1.1 --activate
pnpm
شما می توانید pnpm را به عنوان یک پکیج npm با npm i -g pnpm$
نصب کنید. همچنین می توانید pnpm را با Corepack نصب کنید: $corepack prepare pnpm@6.24.2 --activate
ساختارهای پروژه
در این بخش، ویژگی های اصلی package managers های مختلف را در یک نگاه خواهید دید. شما به راحتی می توانید تشخیص دهید که کدام فایل ها در پیکربندی package managers خاص نقش دارند و کدام فایل ها با یک مرحله نصب تولید می شوند.
همه package managers تمام اطلاعات متا مهم را در فایل مانیفست پروژه، package.json ذخیره می کنند. علاوه بر این، یک فایل پیکربندی در سطح ریشه می تواند برای تنظیم رجیستری های خصوصی یا روش های حل وابستگی استفاده شود.
با یک مرحله نصب، وابستگی ها در یک ساختار فایل (به عنوان مثال، در node_modules
) ذخیره می شوند و یک فایل lock ایجاد می شود. این بخش تنظیم فضای کاری را در نظر نمی گیرد، بنابراین همه نمونه ها فقط یک مکان واحد را نشان می دهند که وابستگی ها در آن ذخیره می شوند.
npm
با npm install $
یا کوتاهتر npm i $
، یک فایل package-lock.json و یک پوشه node_modules
ایجاد می شود. یک فایل پیکربندی اختیاری npmrc را می توان در سطح ریشه قرار داد. برای اطلاعات بیشتر در مورد فایل های lock به بخش بعدی مراجعه کنید.
.
├── node_modules/
├── .npmrc
├── package-lock.json
└── package.json
Yarn کلاسیک
اجرای yarn$
یک فایل yarn.lock و یک پوشه node_modules
ایجاد می کند. یک فایل yarnrc.
نیز می تواند یک گزینه پیکربندی باشد. Yarn Classic همچنین فایل های npmrc.
را نیز قرار می دهد. به صورت اختیاری، می توان از یک پوشه حافظه پنهان (/yarn/cache.
) و مکانی که نسخه فعلی Yarn Classic (.yarn/releases/
) را ذخیره می کند استفاده کرد. روش های مختلف برای پیکربندی این را می توان در بخش مقایسه پیکربندی ها مشاهده کرد.
.
├── .yarn/
│ ├── cache/
│ └── releases/
│ └── yarn-1.22.17.cjs
├── node_modules/
├── .yarnrc
├── package.json
└── yarn.lock
Yarn Berry با node_modules
مستقل از حالت نصب، باید فایلها و پوشههای بیشتری را در پروژههای Yarn Berry مدیریت کنید تا پروژههایی که از سایر package managers استفاده میکنند. برخی اختیاری و برخی اجباری هستند.
Yarn Berry دیگر به فایل های npmrc.
یا yarnrc.
نیازی ندارد و توجه نمی کند. در عوض، یک فایل پیکربندی yarnrc.yml. مورد نیاز است. برای یک جریان کاری سنتی با پوشه node_modules
تولید شده، باید یک پیکربندی nodeLinker ارائه کنید که از نوع نصب node_modules
یا pnpm الهام گرفته شده استفاده کند.
# .yarnrc.yml
nodeLinker: node-modules # or pnpm
اجرای yarn$
همه وابستگی ها را در یک پوشه node_modules
نصب می کند. یک فایل yarn.lock
ایجاد می شود که جدیدتر است اما با توجه به Yarn Classic ناسازگار است. علاوه بر این، یک پوشه /yarn/cache.
ایجاد می شود که برای نصب آفلاین استفاده می شود. همانطور که در بخش مقایسه پیکربندی ها خواهیم دید، پوشه انتشار اختیاری است و نسخه Yarn Berry را که توسط پروژه استفاده می شود، ذخیره می کند.
.
├── .yarn/
│ ├── cache/
│ └── releases/
│ └── yarn-3.1.1.cjs
├── node_modules/
├── .yarnrc.yml
├── package.json
└── yarn.lock
Yarn Berry با PnP
برای هر دو حالت PnP سخت و شل، اجرایyarn$
و yarn/cache.
و /yarn/unplugged.
را به همراه فایلهای pnp.cjs و yarn.lock ایجاد میکند. PnP strict حالت پیش فرض است، اما برای شل، یک پیکربندی لازم است.
# .yarnrc.yml
nodeLinker: pnp
pnpMode: loose
در یک پروژه PnP، پوشه /yarn.
به احتمال زیاد حاوی یک پوشه /sdk
برای ارائه پشتیبانی IDE در کنار یک پوشه /releases
است. پکیج به مورد استفاده شما، حتی پوشه های بیشتری وجود دارند که می توانند بخشی از /yarn.
باشند.
.
├── .yarn/
│ ├── cache/
│ ├── releases/
│ │ └── yarn-3.1.1.cjs
│ ├── sdk/
│ └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock
pnpm
وضعیت اولیه یک پروژه pnpm دقیقاً شبیه یک پروژه npm یا یک پروژه Yarn Classic است — به یک فایل package.json
نیاز دارید. پس از نصب وابستگیها با pnpm i$
، یک پوشه node_modules
ایجاد میشود، اما ساختار آن به دلیل رویکرد ذخیرهسازی آدرسپذیر محتوا، کاملاً متفاوت است.
pnpm همچنین نسخه خود را از یک فایل قفل، pnp-lock.yml
تولید می کند. می توانید پیکربندی اضافی را با یک فایل npmrc.
اختیاری ارائه دهید.
.
├── node_modules/
│ └── .pnpm/
├── .npmrc
├── package.json
└── pnpm-lock.yml
قفل کردن فایل ها و ذخیره سازی وابستگی
همانطور که در بخش قبل توضیح داده شد، هر package manager فایل های lock را ایجاد می کند.
فایلهای lockدقیقاً نسخههای هر وابستگی نصب شده برای پروژه شما را ذخیره میکنند و نصبهای قابل پیشبینی و قطعیتری را امکانپذیر میسازند. این مورد ضروری است زیرا نسخههای وابستگی به احتمال زیاد با محدودههای نسخه اعلام میشوند (مثلاً نسخه 1.2.5 ≥) و بنابراین، اگر نسخههای خود را «lock» نکنید، نسخههای نصبشده واقعی ممکن است متفاوت باشند.
فایلهای lock نیز گاهی اوقات چکسومها را ذخیره میکنند، که در بخش امنیت به طور عمیقتری به آنها خواهیم پرداخت.
فایلهای lock از نسخه 5 (package-lock.json
)، در pnpm از روز اول (pnpm-lock.yaml
) و در قالب جدید YAML در Yarn Berry (yarn.lock
) یک ویژگی npm بودهاند.
در بخش قبل، رویکرد سنتی را دیدیم که در آن وابستگی ها در ساختار پوشه node_modules
نصب می شوند. این طرح npm، Yarn Classic و pnpm است که همه از آن استفاده میکنند، که در آن pnpm آن را کارآمدتر از بقیه انجام میدهد.
Yarn Berry در حالت PnP این کار را متفاوت انجام می دهد. به جای پوشه node_modules
، وابستگی ها به صورت فایل های فشرده در ترکیبی از فایل /yarn/cache.
و pnp.cjs.
ذخیره می شوند.
بهتر است این فایلهای lock را تحت کنترل نسخه داشته باشید زیرا مشکل «روی دستگاه من کار میکند» را حل میکند – هر عضو تیم نسخههای مشابهی را نصب میکند.
دستورات CLI
npm و pnpm به ویژه دارای نام مستعار دستورات و گزینههایی هستند، به این معنی که دستورات میتوانند نامهای مختلفی داشته باشند، یعنی npm install$
همان npm$ add
است. بعلاوه، بسیاری از گزینه های CLI دارای نسخه های کوتاه هستند، به عنوان مثال، D-
به جای save-dev--
.
اجرای پکیج
مثالهای زیر نشان میدهند که چگونه میتوان پکیجهایی را که ابزارهای کاربردی را تشکیل میدهند در طول زمان توسعه مدیریت کرد - باینریهایی که با نام مستعار، مانند ntl، برای اجرای تعاملی اسکریپتها.
فایل های پیکربندی
پیکربندی package managers هم در فایل های package.json و هم در فایل های پیکربندی اختصاصی انجام می شود. نمونه هایی برای گزینه های پیکربندی عبارتند از:
- نسخه دقیق مورد استفاده را تعریف کنید
- از استراتژی حل وابستگی خاصی استفاده کنید
- پیکربندی دسترسی به یک رجیستری خصوصی
- به package manager بگویید کجا فضاهای کاری را در یک monorepo پیدا کند
npm
بیشتر پیکربندی ها در یک فایل پیکربندی اختصاصی (npmrc.) انجام می شود.
اگر میخواهید از ویژگی فضاهای کاری npm استفاده کنید، باید با استفاده از فیلد متادیتا فضاهای کاری پیکربندی را به package.json اضافه کنید تا به npm بگویید به ترتیب پوشههای تشکیلدهنده پروژههای فرعی یا فضاهای کاری را کجا پیدا کند.
{
// ...
"workspaces": [
"hooks",
"utils"
]
}
هر پکیج منیجر خارج از جعبه با رجیستری عمومی npm کار می کند. در یک زمینه شرکتی با کتابخانه های مشترک، به احتمال زیاد می خواهید از آنها بدون انتشار در یک ثبت عمومی استفاده مجدد کنید. برای پیکربندی یک رجیستری خصوصی، می توانید این کار را در یک فایل npmrc.
انجام دهید.
Yarn کلاسیک
می توانید فضای کاری Yarn را در package.json خود راه اندازی کنید. مشابه npm است، اما فضای کاری باید یک پکیج خصوصی باشد.
{
// ...
"private": true,
"workspaces": ["workspace-a", "workspace-b"]
}
هر پیکربندی اختیاری به یک فایل yarnrc.
می رود. یک گزینه پیکربندی رایج، تنظیم یک مسیر Yarnی است که یک نسخه باینری خاص را برای استفاده توسط هر عضو تیم اعمال می کند. مسیر رشته به پوشه ای هدایت می شود (به عنوان مثال، /yarn/releases.
) حاوی یک نسخه Yarn خاص. با دستور yarn policy می توانید نسخه Yarn Classic را نصب کنید.
Yarn Berry
پیکربندی فضاهای کاری در Yarn Berry نیز مشابه نحوه انجام آن در Yarn Classic با یک package.json
است. اکثر پیکربندیهای Yarn Berry در yarnrc.yml.
انجام میشود و گزینههای پیکربندی زیادی در دسترس است. مثال Yarn Classic نیز امکان پذیر است، اما فیلد متادیتا به yarnPath تغییر نام داده است.
# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs
Yarn Berry را می توان با افزونه ها با استفاده از واردات افزونه yarn گسترش داد. این دستور yarnrc.yml.
را به روز می کند.
# .yarnrc.yml
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs
spec: "https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js"
همانطور که در بخش تاریخ توضیح داده شد، ممکن است در حالت سخت PnP به دلیل ناسازگاری، مشکلاتی با وابستگی ها وجود داشته باشد. یک راه حل معمولی برای چنین مشکل PnP وجود دارد: ویژگی پیکربندی packageExtensions.
# .yarnrc.yml
packageExtensions:
"styled-components@*":
dependencies:
react-is: "*"
pnpm
pnpm از همان مکانیزم پیکربندی npm استفاده می کند، بنابراین می توانید از یک فایل npmrc.
استفاده کنید. پیکربندی یک رجیستری خصوصی نیز مانند npm عمل می کند.
- با ویژگی فضای کاری pnpm، پشتیبانی از پروژه های چند پکیج در دسترس است. برای مقداردهی اولیه یک monorepo، باید محل پکیج ها را در یک فایل
pnpm-workspace.yaml
مشخص کنید.
# pnpm-workspace.yaml
packages:
- 'packages/**'
پشتیبانی Monorepo
مونورپو چیست؟
مونورپو مخزنی است که چندین پروژه را در خود جای می دهد که به آنها فضاهای کاری یا پکیج ها می گویند. این یک استراتژی سازمان پروژه است که به جای استفاده از چندین مخزن، همه چیز را در یک مکان نگه می دارد.
البته، این با پیچیدگی اضافی همراه است. Yarn Classic اولین کسی بود که این قابلیت را فعال کرد، اما اکنون هر package manager اصلی یک ویژگی فضای کاری را ارائه می دهد. این بخش نحوه پیکربندی فضاهای کاری با هر یک از package managers های مختلف را نشان می دهد.
npm
تیم npm ویژگی مورد انتظار فضای کاری npm را در نسخه 7 منتشر کرد. این شامل تعدادی از دستورات CLI بود که به مدیریت پروژه های چند پکیج از داخل یک پکیج ریشه کمک می کرد. بیشتر دستورات را می توان با گزینه های مربوط به فضای کاری استفاده کرد تا به npm بگوییم که آیا باید در برابر یک فضای کاری خاص، چندگانه یا همه اجرا شود.
# Installing all dependencies for all workspaces
$ npm i --workspaces.
# run against one package
$ npm run test --workspace=hooks
# run against multiple packages
$ npm run test --workspace=hooks --workspace=utils
# run against all
$ npm run test --workspaces
# ignore all packages missing test
$ npm run test --workspaces --if-present
برخلاف سایر package managers، npm v8 در حال حاضر از فیلتر پیشرفته یا اجرای چندین دستور مرتبط با فضای کاری به صورت موازی پشتیبانی نمی کند.
Yarn کلاسیک
در آگوست 2017، تیم Yarn از پشتیبانی مونورپو درجه یک از نظر ویژگی فضای کاری خبر داد. قبل از این مرحله، تنها امکان استفاده از یک package manager در یک پروژه چند پکیج با نرم افزارهای شخص ثالث مانند لرنا وجود داشت. این اضافه شدن به Yarn راه را برای سایر package managers هموار کرد تا چنین ویژگی را پیاده سازی کنند.
همچنین قبلاً در مورد نحوه استفاده از ویژگی فضای کاری Yarn Classic با و بدون لرنا، در صورت علاقه، نوشته ام. اما این پست فقط برخی از دستورات ضروری را پوشش میدهد تا به شما در مدیریت وابستگیها در راهاندازی فضای کاری Yarn Classic کمک کند.
# Installing all dependencies for all workspaces
$ yarn
# display dependency tree
$ yarn workspaces info
# run start command only for one package
$ yarn workspace awesome-package start
# add Webpack to package
$ yarn workspace awesome-package add -D webpack
# add React to all packages
$ yarn add react -W
Yarn Berry
Yarn Berry از ابتدا دارای فضاهای کاری بود زیرا اجرای آن بر اساس مفاهیم Yarn Classic ساخته شده بود. در یک نظر Reddit، یکی از توسعه دهندگان اصلی Yarn Berry مروری کوتاه بر ویژگی های فضای کاری ارائه داد، از جمله:
yarn add --interactive$
: امکان استفاده مجدد از نسخه های دیگر فضاهای کاری را هنگام نصب پکیجyarn up$
: یک پکیج را در تمام فضاهای کاری به روز می کندyarn workspaces focus$
: وابستگی ها را فقط برای یک فضای کاری نصب می کندyarn workspaces foreach$
: دستوری را در تمام فضاهای کاری اجرا می کند
Yarn Berry به شدت از پروتکلها استفاده میکند، که میتوانند در فیلدهای وابستگی یا devDependencies
فایلهای package.json
استفاده شوند. یکی از آنها فضای کاری است: پروتکل.
برخلاف فضاهای کاری Yarn Classic، Yarn Berry به صراحت تعریف میکند که یک وابستگی باید یکی از پکیجهای این monorepo باشد. در غیر این صورت، Yarn Berry ممکن است سعی کند نسخه ای را از یک رجیستری راه دور دریافت کند اگر نسخه ها مطابقت ندارند.
{
// ...
"dependencies": {
"@doppelmutzi/hooks": "workspace:*",
"http-server": "14.0.0",
// ...
}
}
pnpm
با پروتکل فضای کاری خود، pnpm پروژه های monorepo را مشابه Yarn Berry تسهیل می کند. بسیاری از دستورات pnpm گزینه هایی مانند recursive (-r)--
یا filter---
را می پذیرند که به ویژه در زمینه monorepo مفید هستند. دستور فیلتر بومی آن نیز مکمل یا جایگزین خوبی برای لرنا است.
# prune all workspaces
pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml
# run all tests for all workspaces with scope @doppelmutzi
pnpm recursive run test --filter @MohammadAbdorrahmani
/
کارایی و کارایی فضای دیسک
عملکرد بخش مهمی از تصمیم گیری است. این بخش معیارهای من را بر اساس یک پروژه کوچک و یک پروژه متوسط نشان می دهد. در اینجا چند نکته در مورد پروژه های نمونه آورده شده است:
- هیچ یک از مجموعهای از معیارها از ویژگیهای فضای کاری استفاده نمیکنند
- پروژه کوچک 33 وابستگی را مشخص می کند
- پروژه متوسط 44 وابستگی را مشخص می کند
- من اندازهگیریها را برای سه مورد استفاده (UC) انجام دادم، یک بار برای هر یک از انواع مدیریت پکیجمان.
- UC 1: بدون cache/store، بدون فایل ;ock، بدون
node_modules
یاpnp.cjs.
- UC 2: حافظه cache/storeوجود دارد، هیچ فایل قفلی، بدون
node_modules
یاpnp.cjs.
- UC 3: که cache/store وجود دارد، فایلهای قفل وجود دارد،
node_modules
یاpnp.cjs.
وجود ندارد
در اینجا معیارهای رسمی تیم Yarn Berry و pnpm آمده است.
ویژگی های امنیتی
npm
npm هنگام کار با پکیجهای بد کمی بخشنده بوده است و آسیبپذیریهای امنیتی را تجربه کرده است که مستقیماً روی بسیاری از پروژهها تأثیر گذاشته است. به عنوان مثال، در نسخه 5.7.0، زمانی که دستور sudo npm را روی یک سیستم عامل لینوکس اجرا میکردید، امکان تغییر مالکیت فایلهای سیستم وجود داشت که سیستم عامل را غیرقابل استفاده میکرد.
حادثه دیگری در سال 2018 رخ داد و مربوط به سرقت بیت کوین بود. اساساً پکیج محبوب Node.js EventStream یک وابستگی مخرب در نسخه 3.3.6 خود اضافه کرد. این پکیج مخرب حاوی یک محموله رمزگذاری شده بود که سعی می کرد بیت کوین را از دستگاه توسعه دهنده بدزدد.
برای کمک به حل این مشکلات، نسخههای جدیدتر npm از الگوریتم رمزنگاری SHA-512 در package-lock.json
برای بررسی یکپارچگی پکیجهایی که نصب میکنید استفاده میکنند.
به طور کلی، npm بیشتر و بیشتر برای از بین بردن شکاف های امنیتی خود، به ویژه مواردی که در مقایسه با Yarn آشکارتر شده اند، انجام داده است.
Yarn
هم Yarn Classic و هم Yarn Berry یکپارچگی هر پکیج را با چکسامهای ذخیره شده در yarn.lock از ابتدا تأیید کردهاند. Yarn همچنین سعی میکند از بازیابی پکیجهای مخربی که در package.json شما اعلان نشدهاند در حین نصب جلوگیری کند: اگر عدم تطابق پیدا شود، نصب متوقف میشود.
Yarn Berry در حالت PnP از مشکلات امنیتی رویکرد node_modules
سنتی رنج نمی برد. برخلاف Yarn Classic، Yarn Berry امنیت اجرای فرمان را بهبود می بخشد. شما فقط می توانید باینری از وابستگی هایی را که به صراحت در package.json
خود اعلام کرده اید، اجرا کنید. این ویژگی امنیتی شبیه به pnpm است که در ادامه توضیح خواهم داد.
pnpm
pnpm همچنین از چکسامها برای تأیید صحت هر پکیج نصب شده قبل از اجرای کد آن استفاده میکند.
همانطور که در بالا اشاره کردیم، npm و Yarn Classic هر کدام به دلیل بالا بردن مشکلات امنیتی دارند. pnpm از این امر اجتناب می کند زیرا مدل آن از بالابر استفاده نمی کند. در عوض، پوشههای تودرتو node_modules
را ایجاد میکند که خطر دسترسی غیرقانونی به وابستگی را از بین میبرد. این بدان معنی است که وابستگی ها تنها در صورتی می توانند به وابستگی های دیگر دسترسی داشته باشند که به صراحت در package.json
اعلان شده باشند.
همانطور که در مورد آن بحث کردیم، این امر به ویژه در تنظیم monorepo بسیار مهم است، زیرا الگوریتم بالا بردن گاهی اوقات میتواند به وابستگیهای فانتوم و دپلگانگرها منجر شود.
تصویب توسط پروژه های محبوب
من بسیاری از پروژه های منبع باز محبوب را تجزیه و تحلیل کردم تا به این فکر کنم که امروزه از کدام package managers توسط "developer elite" استفاده می شود. برای من مهم بود که این پروژه ها به طور فعال نگهداری شوند و اخیراً آخرین بار به روز شوند. این ممکن است هنگام انتخاب یک package manager، دیدگاه دیگری به شما بدهد.
جالب اینجاست که در زمان نگارش این مقاله، هیچ یک از این پروژه های منبع باز از رویکرد PnP استفاده نمی کنند.
کدام package managers جاوا اسکریپت بهتر است؟
وضعیت فعلی package managers عالی است. ما عملاً به برابری ویژگی ها در بین تمام package managers های اصلی دست یافته ایم. اما با این حال، آنها در جزئیات کاملاً متفاوت هستند.
pnpm در ابتدا مانند npm به نظر می رسد زیرا استفاده از CLI آنها مشابه است، اما مدیریت وابستگی ها بسیار متفاوت است. روش pnpm منجر به عملکرد بهتر و بهترین کارایی فضای دیسک می شود. Yarn Classic هنوز بسیار محبوب است، اما نرم افزار قدیمی و پشتیبانی آن ممکن است در آینده نزدیک حذف شود. Yarn Berry PnP بچه جدید این بلوک است، اما پتانسیل خود را به طور کامل درک نکرده است تا یک بار دیگر چشم انداز package manager را متحول کند.
در طول سالها، بسیاری از کاربران در مورد اینکه چه کسی از کدام package managers استفاده میکند، سؤال کردهاند، و در کل، به نظر میرسد که مردم بهطور خاص به بلوغ و پذیرش Yarn Berry PnP علاقهمند هستند.
هدف این مقاله این است که دیدگاههای زیادی را در اختیار شما قرار دهد تا تصمیم بگیرید که از کدام package manager به تنهایی استفاده کنید. من می خواهم به این نکته اشاره کنم که من مدیریت پکیج خاصی را توصیه نمی کنم. بستگی به این دارد که چگونه نیازهای مختلف را وزن می کنید - بنابراین هنوز هم می توانید هر چیزی را که دوست دارید انتخاب کنید!
شما از چه پکیج منیجری استفاده می کنید و دلیل تان نیز برای ما در بخش نظرات بنویسید.