Danial.bakhtiari
توسعه فرانت‌اند و رابط کاربری

NPX چیست؟

Hasti Taheri8 دقیقه مطالعهبازدید: ۱۲
what-is-npx

چند وقت پیش درباره‌ی NPM نوشتیم و گفتیم چطور نصب و مدیریت بسته‌ها را برای برنامه‌نویس‌های جاوااسکریپت راحت کرده. اما اگر همان مقاله را با دقت خوانده باشید، حتماً یادتان هست که چند بار اسم npx هم وسط حرف‌ها آمد؛ همان ابزاری که با NPM نصب می‌شود ولی کارش کاملاً فرق دارد. حالا وقتش رسیده که کامل سراغش برویم و ببینیم npx دقیقاً چه‌کاری انجام می‌دهد، چرا اصلاً به وجود آمده و چطور می‌شود روزانه از آن استفاده کرد. اگر آن مقاله را نخوانده باشید هم مشکلی نیست؛ همین‌جا هم هرجا لازم باشد اشاره‌ای کوتاه به NPM می‌کنیم تا زمینه دستتان بیاید، اما تمرکز اصلی همین مقاله کاملاً روی npx است.

اول از همه، npx یعنی چه؟

npx مخفف Node Package Execute است؛ یعنی «اجرای بسته‌ی نود». اسمش هم دقیقاً همان کاری را نشان می‌دهد که انجام می‌دهد: به شما اجازه می‌دهد یک بسته را اجرا کنید، بدون این‌که لازم باشد قبلش آن را نصب کرده باشید. یعنی برخلاف NPM که بیشتر دور و بر «نصب و نگهداری بسته‌ها» می‌چرخد، npx دور و بر «اجرای سریع و یک‌باره‌ی یک ابزار» می‌چرخد.

برای این‌که ماجرا دستتان بیاید، یک مثال ساده بزنیم. فرض کنید می‌خواهید یک پروژه‌ی React تازه بسازید. روش قدیمی این بود که اول بسته‌ی create-react-app را به‌صورت سراسری نصب کنید، بعد با آن پروژه بسازید و در آخر هم اگر دیگر لازمش نداشتید، حذفش کنید. با npx همه‌ی این مراحل در یک خط جمع می‌شود:

npx create-react-app my-app

همین یک دستور، بسته را موقتاً دانلود می‌کند، اجرایش می‌کند و بعد از تمام‌شدن کار، دیگر روی سیستم شما جایی نمی‌ماند که فضا اشغال کند یا بعداً یادتان برود باید حذفش کنید.

npx از کجا آمد؟

npx در سال ۲۰۱۷ و همراه با انتشار NPM نسخه‌ی ۵.۲ معرفی شد. قبل از آن، اگر می‌خواستید یک ابزار خط‌فرمانی جاوااسکریپتی را فقط برای یک‌بار امتحان کنید، دو راه بیشتر نداشتید: یا آن را سراسری (global) نصب می‌کردید که کم‌کم سیستم پر می‌شد از بسته‌هایی که فقط یک‌بار به کارتان آمده بودند، یا مسیر پیچیده‌تری می‌رفتید و از داخل پوشه‌ی node_modules/.bin فایل اجرایی را دستی صدا می‌زدید.

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

چرا اصلاً به چنین ابزاری نیاز داریم؟

شاید بپرسید خب چه اشکالی دارد که یک ابزار را سراسری نصب کنیم؟ چند مشکل واقعی وجود دارد:

  • سیستم شما کم‌کم پر می‌شود از ابزارهایی که شاید فقط یک یا دوبار استفاده‌شان کرده‌اید.
  • نسخه‌ی نصب‌شده‌ی سراسری ممکن است قدیمی بماند و با نسخه‌ای که پروژه‌ی جدید نیاز دارد جور نباشد.
  • روی سرورهای CI یا محیط‌های موقتی، اصلاً منطقی نیست چیزی را سراسری نصب کنید که فقط یک‌بار قرار است اجرا شود.
  • وقتی چند پروژه با نسخه‌های مختلف یک ابزار کار می‌کنید (مثلاً نسخه‌های مختلف TypeScript)، نصب سراسری فقط یک نسخه می‌تواند فعال باشد.

npx دقیقاً همین مشکلات را حل می‌کند. هر بار که آن را صدا می‌زنید، یا از نسخه‌ای که در پروژه‌تان نصب است استفاده می‌کند، یا اگر بسته اصلاً نصب نیست، آخرین نسخه‌اش را موقتاً از رجیستری NPM می‌گیرد، اجرا می‌کند و بعد رهایش می‌کند.

نصب npx

همان‌طور که گفتیم، از نسخه‌ی ۵.۲ به بعد NPM، npx هم خودکار همراهش نصب می‌شود. یعنی اگر Node.js و NPM را روی سیستم دارید، احتمالاً npx را هم دارید. برای اطمینان، همین دستور را در ترمینال بزنید:

npx -v

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

npm install -g npx

npx دقیقاً چطور کار می‌کند؟

وقتی دستوری مثل npx some-tool را می‌زنید، npx چند مرحله را پشت سر هم طی می‌کند:

  • اول نگاه می‌کند ببیند آیا some-tool در پوشه‌ی node_modules/.bin پروژه‌ی فعلی وجود دارد یا نه. اگر بود، همان نسخه‌ی محلی را اجرا می‌کند.
  • اگر پیدایش نکرد، سراغ نصب‌های سراسری می‌رود.
  • اگر باز هم چیزی پیدا نکرد، بسته را موقتاً از رجیستری NPM دانلود می‌کند، در یک پوشه‌ی موقت (کش) اجرا می‌کند و بعد از پایان کار، آن را نگه نمی‌دارد.

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

کاربردهای روزمره‌ی npx

اجرای یک ابزار بدون نصب دائمی

ساده‌ترین و رایج‌ترین کاربرد npx همین است؛ امتحان کردن یک ابزار بدون این‌که سیستمتان شلوغ شود. مثلاً برای ساخت سریع یک سرور محلی:

npx http-server

یا برای یک تفریح کوچک:

npx cowsay "سلام"

اجرای ابزارهایی که در پروژه نصب‌اند

خیلی از پروژه‌ها ابزارهایی مثل jest، eslint یا tsc را به‌عنوان وابستگی توسعه (dev dependency) دارند، نه سراسری. به‌جای این‌که مسیر کامل فایل اجرایی را در node_modules/.bin پیدا کنید، کافی است بنویسید:

npx jest
npx eslint .
npx tsc --init

npx خودش می‌فهمد این ابزارها همین‌جا، داخل پروژه، نصب هستند و مستقیم همان‌ها را صدا می‌زند.

اجرای یک نسخه‌ی خاص از یک بسته

گاهی لازم دارید دقیقاً یک نسخه‌ی مشخص از یک ابزار را امتحان کنید، نه آخرین نسخه‌اش. برای این کار کافی است بعد از اسم بسته، نسخه را با @ مشخص کنید:

npx cowsay@1.5.0 "نسخه‌ی خاص"

ساخت سریع پروژه‌های تازه

بیشتر ابزارهای «داربست‌ساز» (scaffolding tools) امروزه با npx معرفی می‌شوند، چون دقیقاً همان چیزی هستند که فقط یک‌بار در ابتدای پروژه لازمشان دارید:

npx create-vite my-app
npx create-next-app my-app
npx degit user/repo my-project

وقتی اسم بسته با اسم دستور فرق دارد

بعضی بسته‌ها چند دستور اجرایی دارند یا اسم دستورشان با اسم خود بسته یکی نیست. در این‌جور مواقع از فلگ --package کمک می‌گیریم:

npx --package=typescript tsc --version

جلوگیری از دانلود ناخواسته

اگر می‌خواهید مطمئن شوید npx هیچ‌وقت چیزی را از اینترنت دانلود نمی‌کند و فقط از نسخه‌های نصب‌شده استفاده می‌کند (مثلاً برای اسکریپت‌های خودکار)، از فلگ --no-install استفاده کنید:

npx --no-install jest

در این حالت، اگر بسته پیدا نشود، npx خطا می‌دهد به‌جای این‌که خودش را دانلود کند.

اجرای اسکریپت از گیت‌هاب یا گیست

یکی دیگر از قابلیت‌های کمتر شناخته‌شده‌ی npx این است که می‌تواند مستقیم از یک مخزن گیت‌هاب یا حتی یک گیست کد بگیرد و اجرایش کند:

npx github:user/repo

این ویژگی برای امتحان سریع یک ابزار کوچک یا اسکریپت اشتراکی خیلی به‌کار می‌آید، اما همان‌طور که در بخش امنیت هم اشاره می‌کنیم، باید با احتیاط استفاده شود.

چند نکته‌ی امنیتی درباره‌ی npx

همین راحتی و سرعت npx یک روی دیگر هم دارد: چون کد را مستقیم از رجیستری یا حتی از یک مخزن گیت‌هاب می‌گیرد و اجرا می‌کند، اگر بی‌احتیاط عمل کنید، ممکن است کد ناشناخته و بالقوه خطرناکی روی سیستمتان اجرا شود. چند توصیه‌ی ساده:

  • قبل از اجرای یک بسته‌ی ناآشنا با npx، حداقل یک نگاه سریع به صفحه‌ی آن در سایت NPM بیندازید.
  • به تعداد دانلودها، تاریخ آخرین آپدیت و اعتبار توسعه‌دهنده توجه کنید.
  • در محیط‌های حساس یا سرورهای تولید (production)، ترجیحاً از فلگ --no-install استفاده کنید تا هیچ کد ناخواسته‌ای موقع اجرای اسکریپت‌ها دانلود نشود.
  • هیچ‌وقت دستور npx را از منابعی که به آن‌ها اعتماد ندارید کپی‌پیست نکنید، حتی اگر ساده و بی‌خطر به نظر برسد.

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

آیا داخل package.json هم به npx نیاز داریم؟

این‌جا یک نکته‌ی ظریف وجود دارد که خیلی از تازه‌کارها گیج‌شان می‌کند. وقتی داخل بخش scripts فایل package.json یک دستور تعریف می‌کنید، مثلاً:

"scripts": {
  "test": "jest"
}

دیگر لازم نیست بنویسید npx jest. علتش این است که وقتی با npm run یک اسکریپت را اجرا می‌کنید، NPM خودش موقتاً پوشه‌ی node_modules/.bin را به مسیر (PATH) اضافه می‌کند و همه‌ی ابزارهای نصب‌شده در پروژه، بدون نیاز به npx، مستقیم قابل صدا زدن‌اند. یعنی npx بیشتر برای وقتی به‌کار می‌آید که مستقیم داخل ترمینال کار می‌کنید، نه داخل اسکریپت‌های از‌پیش‌تعریف‌شده‌ی خود پروژه.

جایگزین‌های npx در ابزارهای دیگر

همان‌طور که در مقاله‌ی قبل گفتیم، NPM تنها مدیر بسته‌ی موجود نیست؛ Yarn و pnpm هم طرفداران خودشان را دارند. طبیعی است که هرکدام از این ابزارها هم معادلی برای npx در خودشان تعبیه کرده باشند:

  • Yarn: از دستور yarn dlx برای اجرای موقتی یک بسته استفاده می‌کند (dlx مخفف download and execute است).
  • pnpm: معادلش pnpm dlx است که همان فلسفه‌ی سبک و سریع pnpm را دنبال می‌کند.

ایده‌ی پشت همه‌ی این‌ها یکی است: اجرای سریع یک ابزار بدون آلوده‌کردن سیستم با نصب‌های دائمی. تفاوت‌شان بیشتر در جزئیات فنی، سرعت و نحوه‌ی مدیریت کش است، نه در هدف اصلی.

پس این وسط، NPM و npx چه فرقی با هم دارند؟

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

حرف آخر

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

همان‌طور که دیدید، در همین مقاله چند بار به تفاوت‌های npx و NPM اشاره کردیم، اما فقط سطحی از آن گذشتیم. در مقاله‌ی بعدی، دقیقاً همین موضوع را باز می‌کنیم و قدم‌به‌قدم بررسی می‌کنیم که NPM و npx در چه مواردی شبیه‌اند، در چه مواردی کاملاً از هم جدا می‌شوند و در عمل، کِی باید سراغ کدام‌یک برویم.

مطالب مرتبط