برنامه‌نویسی

مقایسه Package Managerهای npm، yarn و pnpm

مقایسه package managerهای npm، yarn و pnpm

برای توسعه‌ی برنامه‌های مدرن نیازی نیست تا همه‌ی قابلیت‌ها را از ابتدا توسعه دهیم و به کمک پکیج‌های متن‌باز می‌توانیم روند توسعه را سرعت ببخشیم. همچنین هر یک از آن پکیج‌ها تیم توسعه و نگه‌داری و همچنین جامعه‌ی کاربری مخصوص به خود را دارند بنابراین با استفاده از این پکیج‌ها می‌توانید از مزایایی مانند توسعه سریع‌تر، دسترسی به به‌روزرسانی‌های منظم و جدید، امنیت بیشتر و بهتر بهره‌مند شوید.

همچنین این مورد نیز معمول است که هر پکیج به چندین پکیج‌ دیگر به‌عنوان پیش‌نیاز احتیاج داشته باشد. مثلا بسیاری از پکیج‌ها به پکیج lodash وابسته هستند اما خود lodash به چندین پکیج پیش‌نیاز احتیاج دارد و این وابستگی‌های تودرتو می‌توانند به‌قدری پیچیده شوند که دیگر توسعه‌دهندگان قادر به مدیریت دستی وابستگی‌ها نباشند.

اینجاست که یک package manager می‌تواند بسیار مفید باشد. package managerها، ابزارهایی هستند که وابستگی‌های یک پروژه را به‌صورت خودکار کنترل می‌کنند. برای مثال یک package manager این قابلیت را در اختیار شما قرار می‌دهد تا فقط با اجرای یک دستور، پکیجی جدید یا نسخه‌ی جدید پکیجی که از قبل در پروژه خود داشته‌اید را نصب کنید. همچنین به‌دلیل اینکه همه ‌چیز خودکار است، احتمال رخ دادن خطای انسانی کم‌تر می‌شود. حال در این مقاله می‌خواهیم به سه package manager محبوب JavaScript بپردازیم و آن‌ها را با یکدیگر مقایسه کنیم:

بررسی کلی package managerها

npm در سال ۲۰۱۰ منتشر شد و اولین package manager بود که مفاهیم registry protocol و packaging standards را معرفی کرد. البته پذیرفته‌شدن رسمی این ابزار توسط تیم توسعه Node.js در مدتی پس از انتشار آن، نقطه‌ی عطفی برای npm بود.

پس از محبوبیت Node.js در میان توسعه‌دهندگان، npm نیز مورد توجه قرار گرفت. این ابزار توسعه‌دهندگان را قادر می‌ساخت تا پکیج‌های JavaScript خود را به‌صورت آنلاین ثبت و از طریق command line بتوانند آن پکیج‌ها را در پروژه‌های خود نصب کنند و همچنین آن‌ها قادر خواهند بود تا به‌روزرسانی پکیج‌های نصب شده را دریافت کنند.

اما توسعه‌دهندگان پس از مدتی به‌دلیل برخی اشکال‌های npm، تصمیم گرفتند تا yarn و pnpm را توسعه دهند. برای مثال سرعت npm از همتایان خود کندتر است و در نسخه‌های اولیه آن اشکال‌های امنیتی جدی وجود داشته است. بنابراین شرکت‌های بزرگ فناوری مانند Facebook و Google در استفاده از npm مردد بودند و به‌نوبه‌ی خود تلاش کردند تا ابزار جدیدی را تولید کنند که در نهایت yarn خلق شد. در همین حال نیز توسعه‌دهنده‌ی اوکراینی با نام Zoltan Kochan، ابزار pnpm را ایجاد کرد.

ویژگی‌های npm، yarn و pnpm

همه‌ی این package managerها متن‌باز هستند، به این معنی که شما به عملکردهای داخلی این ابزارها دسترسی خواهید داشت و حتی می‌توانید آن‌ها را مطابق با نیاز خود تغییر دهید.

مزایای npm:

  1. به‌طور خودکار یک فایل package-lock.json تولید می‌کند که برای commit کردن به یک version control system مفید است. به‌این ترتیب، سایر توسعه‌دهندگان یک تیم می‌توانند به‌راحتی وابستگی‌های مشابهی را در پروژه‌ خود نصب کنند.
  2. می‌توانید وابستگی‌های local یا global را به آسانی مدیریت کنید.
  3. این ابزار برای مدیریت چندین نسخه از وابستگی‌ها نیز مناسب است.
  4. شما به npmjs دسترسی خواهید داشت که تعداد پکیج‌های بیشتری نسبت به pypi، rubygems یا packagist در آن وجود دارد.

مزایای yarn:

  1. بسیاری از مشکل‌هایی که در Monorepo وجود داشتند را برطرف کرده است. برای مثال اگر چندین پکیج را در یک ریپازیتوری نگهداری می‌کنید و آن‌ها دارای فایل‌های package.json جداگانه هستند، می‌توانید تمام packageها را به‌راحتی با yarn به‌روزرسانی کنید. همچنین به لطف مفهوم workspaces می‌توانید وابستگی‌های تمام پکیج‌ها را به‌سادگی در یک ریپازیتوری نصب کنید. برخلاف این قابلیت yarn، در npm می‌بایستی دستور npm install را در تمامی مسیرهای پکیج‌ها اجرا کنید.
  2. yarn از مکانسیم offline cache استفاده می‌کند به این معنی که با اولین نصب یک پکیج، فایل‌های آن پکیج توسط yarn به پوشه‌ای مخصوص فایل‌های cache شده در مسیر ~/.yarn-cache اضافه می‌شوند. بنابراین دفعه‌ی دیگری که می‌خواهید این پکیج را نصب کنید، به‌جای ایجاد درخواست HTTP از فایل‌های cache شده استفاده می‌شود. این پشرفت کوچک باعث تحول قابل توجهی در عملکرد yarn نسبت به npm شده است.
  3. yarn از یک lock file با نام yarn.lock استفاده می‌کند، بنابراین پروژه‌های شما برای دیگر افراد تیم به‌درستی کار خواهد کرد. از این مفهوم با عنوان الگوریتم deterministic install نیز یاد می‌شود.
  4. این ابزار دارای یک بررسی کننده‌ی مجوز داخلی است که در سناریوهای مختلف توسعه‌ی برنامه نیز می‌تواند مفید باشد.
  5. yarn برخلاف npm از بارگیری موازی استفاده می‌کند که نتیجه‌ی آن فرایند build سریع‌تر پکیج‌ها است.
  6. در هنگامی که شبکه‌ی شما با خطای failure روبرو باشد، yarn قادر است تا درخواست‌های HTTP جدیدی ارسال کند و این قابلیت در زمانی که با مشکل‌های موقت اینترنت روبرو هستید بسیار مفید است.

مزایای pnpm:

  1. pnpm را می‌توان نسخه‌ی سازگار با npm دانست اما استفاده‌ی بهینه‌ای از دیسک را علاوه‌بر سرعت بالای آن شاهد هستیم.
  2. pnpm همه‌ی پکیج‌ها را در یک مسیر نصب و سپس از symlinkها استفاده می‌کند تا به آن‌ها دسترسی داشته باشید. این مفهوم کاملا جدید که با نام سیستم ذخیره‌سازی content-addressable شناخته می‌شود، pnpm را قادر می‌سازد تا تفاوت میان فایل‌ها را تشخیص دهد و به این صورت فایل‌های بدون تغییر را در دو نسخه مختلف در سیستم شما ذخیره نمی‌کند.
  3. در نسخه‌ی ۵.۸ یک shell-emulator به‌صورت cross platform ارائه شده است.
  4. pnpm یک مکانیسم کنترل دقیق دسترسی دارد، به این معنی که یک پکیج فقط می‌تواند به وابستگی‌هایی که در package.json تعریف شده دسترسی پیدا کند.

مقایسه package managerها

سهولت استفاده

تمامی package managerها اعم از npm، yarn و pnpm، دستورهای تقریبا یکسانی را برای عملکردهای مختلف ارائه می‌دهند و استفاده از همه‌ی آن‌ها آسان است.

npmyarnpnpm
npm installyarn installpnpm install
npm updateyarn upgradepnpm update

سرعت

زمانی‌که صحبت از سرعت و عملکرد در میان باشد، pnpm حرف اول را می‌زند. با توجه به benchmark که در ریپازیتوری pnpm قرار داده شده، تجربه‌ی سرعتی ۳ برابری را برای توسعه‌دهندگان به ارمغان می‌آورد. سرعت npm و yarn را می‌توانیم نزدیک به هم بدانیم اما مزیت‌های قابل توجهی در yarn وجود دارد که npm فاقد آن‌ها است اما در برخی سناریوها نیز npm گزینه مناسب‌تری است. برای مثال اگر فقط بخواهیم node_modules را در نظر بگیریم و از قابلیت‌های cache و lock file صرف نظر کنیم، سرعت ۵ برابری را در npm شاهد خواهیم بود اما در صورتی که هر سه ویژگی را در نظر بگیریم، عملکرد yarn حدودا ۱۱ برابر سریع‌تر از npm است.

امنیت

مزیت yarn نسبت به npm در این است که هر پکیج را با استفاده از checksumها بررسی و تایید می‌کند. فرایند تایید قبل از اجرای هر کد از پکیج انجام می‌شود بنابراین احتمال آسیب پذیری package hijacking از بین می‌رود اما npm از لحاظ امنیتی شهرت بدی را کسب کرده زیرا در گذشته بسیاری آسیب‌پذیری‌های امنیتی در آن وجود داشته که مستقیما بر روی بسیاری از پروژه‌ها تاثیرگذار بوده است و این package manager هنوز هم در راستای تکامل و ارتقا سطح ایمنی خود تلاش می‌کند.

با آسیب‌پذیری‌ که در نسخه‌ی ۵.۷.۰ وجود داشت می‌توانستیم ownership فایل‌های سیستمی را با اجرای دستور sudo npm که مربوط به سیستم‌عامل‌های مبتنی بر لینوکس است، تغییر دهیم و به این صورت سیستم‌عامل غیر قابل استفاده می‌شد.

به همین ترتیب در سال ۲۰۱۸ باری دیگر شاهد تاثیر اشکال‌های امنیتی npm در سرقت bitcoin بوده‌ایم. پکیج محبوب Node.js با نام EventStream، از یک وابستگی مخرب با نام flatmap-stream استفاده کرده بود و این پکیج مخرب رمزنگاری شده، سعی در سرقت bitcoin از دستگاه‌های توسعه‌دهندگان داشت.

pnpm توانست با ادغام ویژگی‌های npm و yarn، امنیت بهتری را فراهم کند. علاوه‌برآن‌ها یک مکانیسم کنترل دسترسی دقیق را پیاده‌سازی کرد که یک پکیج را فقط به استفاده از وابستگی‌ها خاص خود که در package.json تعریف شده است محدود می‌کند.

ثبات

npm، yarn و pnpm طی چند سال گذشته مرحله‌های مختلفی را پشت سر گذاشته‌اند و در طول زمان توانسته‌اند کدهای خود را به بلوغ کافی برسانند و از ظرفیت جامعه‌ی کاربری توسعه‌دهندگان متن‌باز استفاده‌ کنند. همچنین با گذشت زمان ممکن است مفاهیم و ایده‌های جدیدی نیز ظاهر شود که بتوانند تغییرهای مهمی را ایجاد کنند. همه‌ی این package managerها در زمان نوشتن این مقاله از وضعیت و ثبات خوبی برخوردار هستند و بدون هیچ مشکلی می‌توانید از آن‌ها در پروژه‌های خود استفاده کنید.

yarn نتیجه‌ی همکاری Facebook و Google است. npm نیز توسط Microsoft و Node.js توسعه داده شده و pnpm بیشتر به‌صورت شخصی توسعه داده می‌شود اما ۷۷ مشارکت کننده به توسعه‌ی این ابزار کمک کرده‌اند بنابراین می‌توان گفت قابل اعتماد است و می‌توانید از همه‌ی این package managerها به‌خوبی در پروژه‌ی بعدی خود استفاده کنید.

پشتیبانی از monorepos

اکثر شرکت‌‌های بزرگ فناوری از monorepos برای ذخیره‌سازی و مدیریت کدهای خود استفاده می‌کنند. npm فقط برای مدیریت پروژه‌های تکی طراحی شده است و از monorepos پشتیبانی نمی‌کند اما yarn و pnpm به لطف مفهوم workspaces از monorepos پشتیبانی می‌کنند.

فایل lock

هر سه package manager از lock file بهره می‌برند که به توسعه‌دهندگان مختلف کمک می‌کند نسخه‌ای مشابه از یک پکیج را در پروژها‌ی اشتراکی خود نصب ‌کنند. npm از فایل package-lock.json و به همین ترتیب yarn از yarn.lock و pnpm از pnpm-lock.yaml استفاده می‌کنند.

جمع‌بندی

اگر در جستجوی راه حلی هستید که سرعت و استفاده‌ی بهینه از حافظه در اولویت‌های شما باشد پس استفاده از pnpm را جدی بگیرید. اگر با monorepos سروکار دارید می‌توانید از yarn و pnpm استفاده کنید. بااین‌حال به‌خاطر داشته باشید که yarn برخی داده‌ها را به Facebook ارسال می‌کند که ممکن است در برخی سناریوها استفاده از yarn گزینه‌ی مناسبی نباشد.

در ادامه‌ی این صحبت‌ها باید اضافه کنیم که yarn از نسخه‌ی ۵ Node.js پشتیبانی نمی‌کند و npm به یک گزینه‌ی ارجح‌تر برای پروژه‌های Node.js تبدیل شده است زیرا تیم اصلی Node.js توصیه می‌کند که از npm استفاده کنید و حتی این روزها، npm به‌طور خودکار پس از نصب Node.js بر روی سیستم شما قابل استفاده است.

البته فراموش نکنید که تاریخچه‌ی npm از نظر مسائل امنیتی را در نظر داشته باشید که این موضوع باعث می‌شود قادر نباشید تا از این package manager در همه‌ی سناریوها استفاده کنید و اگر نگران امنیت پروژه هستید، انتخاب yarn می‌تواند مناسب باشد.

منبع: https://blog.logrocket.com/javascript-package-managers-compared