قبل از این که به توضیح در مورد npx بپردازیم، ابتدا کمی درباره فایلهای اجرایی صحبت میکنیم. در اینجا منظورمان از فایلهای اجرایی همان فایلهای binary یا executable ها هستند. همانطور که میدانیم، بعضی پکیجها مجموعهای از دستورات اجرایی در اختیارمان قرار میدهند که میتوانیم در ترمینال از آنها استفاده کنیم. مثلاً nodemon، create-react-app، vue-cli و ... . اما این دستورات چهطور نصب میشوند و ما چهطور از آنها استفاده میکنیم؟
اجازه دهید با مثال nodemon جلو برویم، همانطور که میدانیم، این پکیج به ما کمک میکند که تغییرات یک فایل .js را مشاهده کنیم و هر وقت محتویات آن فایل تغییر کرد، دوباره اجرایش کنیم. وقتی ما این پکیج را با دستور npm install nodemon
نصب میکنیم:
• npm فایلهای این پکیج را در دایرکتوری node_modules/nodemon
نصب میکند.
• اگر این پکیج فایلهای binary داشته باشد، آنها را کامپایل میکند.
• باینریهای کامپایل شده و هر باینری دیگری که در این پکیج وجود دارد را در دایرکتوری node_modules/.bin
ذخیره میکند.
در واقع فولدر node_modules/.bin
محل ذخیرهسازی قسمتهای باینریِ پکیجهای لوکالِ پروژهمان است. هنگامی که دستور nodemon test.js
را میزنیم تا از این پکیج استفاده کنیم، npm از دایرکتوری bin دستور nodemon را میخواند و آن را اجرا میکند. در این حالت اگر به دایرکتوری node_modules/.bin
برویم، میبینیم که سه فایل به نامهای nodemon (بدون اکستنشن و مخصوص لینوکس)، nodemon.cmd (مخصوص ویندوز) و nodemon.ps1 (مخصوص powershell) برای دستور nodemon در این دایرکتوری وجود دارد.
البته حواسمان باشد فولدر bin.
برای پکیجهایی میباشد که بصورت لوکال نصب شدهاند، و فایلهای باینری مربوط به پکیجهای گلوبال، در سیستمعاملهای یونیکسی(unix-based) در آدرس {prefix}/bin
و در سیستمعامل ویندوز در آدرس {prefix} ذخیره میشوند. مثلاً در لینوکس این فایلهای باینری در /usr/local/bin
و در ویندوز در AppData/npm
ذخیره میشوند.
بطور کلی اگر پکیجی که بصورت لوکال نصب شده است، فایل اجرایی داشته باشد و ما بخواهیم آن را اجرا کنیم، سه راه داریم:
• اول آنکه به دایرکتوریِ node_modules/.bin
برویم و بعد بصورت دستی آن را اجرا کنیم:
• دوم آنکه در قسمت “scripts”
فایل package.json
آن را بنویسیم:
حالا اگر در دایرکتوری روت دستور npm run package-name
را بزنیم، پکیجمان اجرا میشود.
• راه سوم هم استفاده از npx هست.
حالا سراغ npx میرویم ...
npx یک package runner است. از نسخه 5.2.0 به بعدِ npm، این دستور باینری به همراه npm نصب میشود و بدون نیاز به نصب هیچ چیز اضافهای، میتوان از آن استفاده کرد. البته npx خودش یک پکیج npm است و اگر هم خواستیم از طریق package manager های دیگر از آن استفاده کنیم، میتوانیم جداگانه آن را نصب کنیم: npm install -g npx
npx کار با باینریها را برایمان ساده میکند و دستوری را که به آن پاس میدهیم، به همراه همه ملزومات اجرای آن دستور برایمان انجام میدهد. مثلاً اگر پکیجی که دستور بوسیله آن اجرا میشود نصب نباشد، ابتدا آن پکیج را نصب میکند و بعد دستور مربوطه را اجرا مینماید.
حالا فرض کنیم میخواهیم با یک ابزار CLI، پروژه را شروع و ایجاد کنیم، ولی بعد از ایجاد پروژه، دیگر نمیخواهیم آن ابزار CLI در دایرکتوری گلوبال سیستمعاملمان نصب باشد و فضا اشغال کند(برای جلوگیری از package pollution در دایرکتوری گلوبال). در واقع برخی دستورات هستند که از آنها خیلی کم استفاده میکنیم، مثلاً به ازای هر پروژه فقط یک بار از آنها استفاده میکنیم. بنابراین دفعه بعد که به آنها نیاز داریم، مثلاً در پروژه بعدیمان، احتمال این که نسخهاش قدیمیباشد خیلی زیاد است، بنابراین نگه داشتن آن روی سیستم توجیهی ندارد و بهتر است هر بار که به آن نیاز داشتیم آن را نصب کنیم. پس در مثال CLI tool، ما میخواهیم بصورت موقّت ابزار را نصب کنیم، ابزار پروژه را برایمان ایجاد کند و بعد از بین برود و اثری از آن باقی نماند!
در این موارد npx به کمک ما میآید، بعنوان مثال میخواهیم پکیج @angular/cli را به این شیوه نصب کنیم:
قسمت اولِ دستور، پکیج @angular/cli را بطور موقت نصب میکند و قسمت دوم آن یک پروژه انگولار ایجاد میکند. بعد از اجرای این دستور اگر دایرکتوری گلوبال سیستمعامل را چک کنیم، هیچ اثری از @angular/cli نیست و مشاهده میکنیم که نصب نشدهاست.
یک روش کاربردی استفاده از npx، استفاده از آن در اسکریپتهای npm است:
حالا اگر در ترمینال بنویسیم: npm run create-angular-app
، دقیقاً مشابه حالت قبلی، یک پروژه انگولار برایمان ایجاد میکند.
فرض کنید ما چند unit test داریم که با mocha نوشته شدهاند و میخواهیم پروژه را با آنها تست کنیم، در این صورت به راحتی میتوانیم بگوییم:
مشاهده میکنیم که بدون نصبِ mocha نیز میتوان این تستها را انجام داد.
البته کاربردهای npx بیش از اینهاست، مثلاً اجرای دستورات مبتنی بر gist، استفاده از نسخههای مختلف پکیجهای npm، اجرای دستورات یک پکیج وقتی که اجازه نصب گلوبال آن را نداریم، و بسیاری چیزهای دیگر که جلوتر دربارهشان بیشتر توضیح دادهایم. میتوانید توضیح کاملتری از کاربردهای npx و همچنین گزینههای این دستور را در آدرس زیر ببینید:
https://www.npmjs.com/package/npx
و اما قالب کلی استفاده از npx به این شکل است:
npx دستور <command> را یا از دایرکتوری node_modules/.bin و یا از کَش مرکزی اجرا میکند و قبل از آن هر پکیجی را که برای اجرای <command> مورد نیاز باشد نصب میکند. بصورت پیشفرض npx ابتدا چک میکند دستوری که به آن دادهایم در $path یا در فایلهای باینری لوکال وجود دارد یا نه، اگر وجود داشت آن را اجرا میکند و اگر وجود نداشت، ابتدا آن را نصب، و سپس اجرا میکند.
برای درک بهتر این موضوع، با فرض این که از سیستمعامل ویندوز استفاده میکنیم، میتوانیم یک فایل آزمایشی به نام mytest.cmd در دایرکتوری node_modules/.bin ایجاد کنیم و در آن دستور ساده echo HelloWorld! را بنویسیم. حالا اگر در دایرکتوری روتِ پروژه دستور npx mytest
را بزنیم، میبینیم که فایل mytest.cmd اجرا میشود و عبارت HelloWorld! در ترمینال چاپ میگردد.
مواردی از کاربردهای npx:
• اجرای یک فایل باینری از دایرکتوری لوکال:
• اجرای دستور یک پکیج بدون نصب کردن آن در لوکال:
• اجرای یک دستور از پکیجی که روی مخزن گیت قرار دارد:
• اجرای یک دستورِ کاملِ shell با استفاده از چند پکیج مختلف:
• اجرای یک binary node با گزینه inspect--
:
• تعیین نسخه دلخواه node برای اجرای اسکریپتها:
میشود npx را طوری تنظیم کرد که وقتی در ترمینال دستوری را با علامت @ در انتها میزنیم، اگر آن دستور توسط npm پیدا نشد (یا به عبارتی not found شد) دستور npx جایگزین آن شود. یعنی اگر دستور پیدا نشد، آن وقت npx آن دستور را اجرا کند، و در نتیجه آن را نصب کند و مراحل لازم جهت اجرای آن را انجام دهد. البته این قابلیت صرفاً در ترمینالهای bash، zsh و fish پشتیبانی میشود. در مثال زیر، قبل از نصب mocha اقدام به استفاده از دستور آن کردیم، اگر تنظیمات لازم را انجام داده باشیم، خروجیمان اینگونه خواهد بود:
به این قابلیت shell auto fallback گفته میشود. توضیحات تکمیلی در این باره و همینطور نحوه پیکربندی را میتوانید در لینک زیر مشاهده کنید:
https://www.npmjs.com/package/npx#shell-auto-fallback
شما کاربران عزیز سکان آکادمی میتوانید با قرار دادن کامنت، نظرات و پرسشهای خود را با ما در میان بگذارید.
در مقاله بعد به بررسی دستور npm audit
میپردازیم که یکی از مهمترین دستورات npm محسوب میشود. با ما همراه باشید...