آموزش Node.js: آشنایی با npm و npx – بخش پنجم


در بخش قبلی این سری مقالات آموزش Node.js به توضیح برخی ویژگیهای فایل Package.json پرداختیم. اینک به توضیح npm و npx میپردازیم. برای مطالعه بخش قبلی میتوانید به لینک زیر مراجعه کنید:
برای دیدن آخرین نسخه از پکیج npm نصب شده شامل وابستگیهایش از دستور زیر استفاده کنید:
npm list
مثال:
❯ npm list /Users/flavio/dev/node/cowsay └─┬ cowsay@1.3.1 ├── get-stdin@5.0.1 ├─┬ optimist@0.6.1 │ ├── minimist@0.0.10 │ └── wordwrap@0.0.3 ├─┬ string-width@2.1.1 │ ├── is-fullwidth-code-point@2.0.0 │ └─┬ strip-ansi@4.0.0 │ └── ansi-regex@3.0.0 └── strip-eof@1.0.0
همچنین میتوانید فایل package-lock.json را باز کنید، اما نیازمند کمی کاوش است. دستور npm list –g نیز کار فوق را اما منحصراً در مورد پکیجهای سراسری انجام میدهد.
برای دریافت پکیجهای سطح بالا، یعنی آنها را که به npm گفتهاید نصب کند و در package.json لیست شدهاند، دستور زیر را اجرا کنید:
npm list --depth=0
خروجی:
❯ npm list --depth=0 /Users/flavio/dev/node/cowsay └── cowsay@1.3.1
میتوان نسخه یک پکیج خاص را از طریق تعیین نام آن به دست آورد:
❯ npm list cowsay /Users/flavio/dev/node/cowsay └── cowsay@1.3.1
این دستور در مورد وابستگیهای پکیجهای نصب شده نیز اجرا میشود:
❯ npm list minimist /Users/flavio/dev/node/cowsay └─┬ cowsay@1.3.1 └─┬ optimist@0.6.1 └── minimist@0.0.10
اگر میخواهید ببینید آخرین نسخه پکیج روی یک ریپازیتوری چیست دستور زیر را اجرا کنید:
npm view [package_name] version
خروجی:
❯ npm view cowsay version
نصب یک نسخه قدیمیتر از یک پکیج npm
نصب نسخههای قدیمیتر از یک پکیج npm در برخی موارد میتواند برای حل یک مشکل تطبیقپذیری مناسب باشد.
شما می توانید یک نسخه قدیمی از یک پکیج npm را با استفاده از ساختار @ نصب کنید:
npm install <package>@<version>
مثال:
npm install cowsay
دستور فوق نسخه 1.3.1 (که آخرین نسخه در زمان نگارش این مقاله است) را نصب میکند، برای نصب نسخه 1.2.0 میتوانید از دستور زیر استفاده کنید:
npm install cowsay@1.2.0
همین کار را میتوان با استفاده از پکیجهای سراسری نیز اجرا کرد:
npm install -g webpack@4.16.4
همچنین ممکن است بخواهید همه نسخههای قبلی یک پکیج را نصب کنید. این کار با اجرای دستور زیر ممکن است:
npm view <package> versions
خروجی:
❯ npm view cowsay versions [ '1.0.0', '1.0.1', '1.0.2', '1.0.3', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.2.0', '1.2.1', '1.3.0', '1.3.1' ]
بهروزرسانی همه وابستگیهای Node به آخرین نسخهها
هنگامی که یک پکیج را با استفاده از دستور <npm install <packagename نصب میکنید، جدیدترین نسخههای ممکن پکیج دانلود میشوند و در پوشه node_modules قرار میگیرند و یک مدخل متناظر به فایل package.json و package-lock.json اضافه میشود که در پوشه جاری حضور دارند.
npm وابستگیها را محاسبه کرده و جدیدترین نسخههای آنها را نیز نصب میکند. فرض کنید میخواهید پکیج cowsay را نصب کنید که یک ابزار جالب خط فرمان است که امکان ایجاد شکل یک «گاو» در حال بیان یک پیام را میدهد. هنگامی که دستور npm install cowsay را اجرا کنید، مدخل زیر به فایل package.json اضافه خواهد شد:
1{
2 "dependencies": {
3 "cowsay": "^1.3.1"
4 }
5}
و در ادامه خروجی package-lock.json را مشاهده میکنید که برای وضوح بیشتر در آن وابستگیهای تودرتو حذف شدهاند:
1{
2 "requires": true,
3 "lockfileVersion": 1,
4 "dependencies": {
5 "cowsay": {
6 "version": "1.3.1",
7 "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz",
8 "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==",
9 "requires": {
10 "get-stdin": "^5.0.1",
11 "optimist": "~0.6.1",
12 "string-width": "~2.1.1",
13 "strip-eof": "^1.0.0"
14 }
15 }
16 }
17}
اینک این 2 فایل به ما میگویند که نسخه نصب شده cowsay 1.3.1 است. قاعده ما برای بهروزرسانی به صورت 1.3.1^ است که بر اساس قواعد نسخهبندی npm بدان معنی است که میتواند انتشارهای فرعی و وصلهها یعنی 0.13.1، 0.14.0 و غیره را بهروزرسانی کند.
اگر یک انتشار فرعی یا وصله وجود داشته باشد و دستور npm update را وارد کنیم، نسخه نصبی بهروزرسانی میشود و فایل package-lock.json با نسخه جدید پر میشود، اما فایل package.json بیتغییر باقی میماند. برای یافتن انتشارهای جدید پکیجها میتوانید دستور npm outdated را وارد کنید.
در ادامه فهرستی از پکیجهای تاریخ گذشته را در یک ریپازیتوری که اخیراً بهروزرسانی نشدهاند مشاهده میکنید:
برخی از این بهروزرسانیها انتشار اصلی هستند. اجرای دستور npm update نسخه این موارد را بهروزرسانی نخواهد کرد. انتشارهای اصلی هرگز به این روش بهروزرسانی نمیشوند، چون آنها (برحسب تعریف) تغییرهای گسستهای ایجاد میکنند و npm میخواهید شما را در برابر بروز مشکلات محافظت کند.
برای بهروزرسانی یک نسخه اصلی از همه پکیجها، باید پکیج npm-check-updates را به صورت سراسری نصب کنید:
npm install -g npm-check-updates
و سپس دستور زیر را اجرا کنید:
ncu –u
دستور فوق همه نسخههای موجود در فایل package.json را به dependencies و devDependencies بهروزرسانی میکند به طوری که npm میتواند نسخه جدید اصلی را نصب کند.
اکنون آماده هستید که بهروزرسانی را اجرا کنید:
npm update
اگر پروژه را بدون وابستگیهای node_modules دانلود کردهاند و میخواهید ابتدا نسخههای جدید را نصب کنید، میتوانید دستور زیر را اجرا کنید:
npm install
نسخهبندی معناشناختی با استفاده از npm
نسخهبندی معناشناختی یک قرارداد است که به نسخههای مختلف معنا میبخشد. اگر در مورد پکیجهای Node تنها یک نکته مهم وجود داشته باشد، آن این است که همه افراد روی استفاده از نسخهبندی معناشناختی در تعیین اعداد نسخه توافق دارند.
مفهوم نسخهبندی معناشناختی ساده است. همه نسخهها سه رقم به صورت x.y.z دارند که هرکدام معنی مشخصی دارند:
- رقم نخست نشاندهنده نسخه اصلی است.
- رقم دوم نشاندهنده نسخه فرعی است.
- رقم سوم نشاندهنده نسخه وصله است.
زمانی که یک انتشار جدید انجام مییابد، اعداد به صورت تصادفی انتساب نمییابند، بلکه قواعد خاصی وجود دارند:
- عدد اصلی نسخه زمانی افزایش مییابد که تغییرهای ناسازگاری با نسخههای قبلی در API ایجاد شده باشد.
- نسخههای فرعی زمانی اضافه میشوند که یک کارکرد به روش سازگار با نسخههای قبل اضافه شده باشد.
- نسخه وصله نیز شامل اصلاحیههای باگ مطابق با نسخههای قبلی است.
این قرارداد از سوی همه زبانهای برنامهنویسی پذیرش یافته است و بسیار مهم است که همه پکیجهای npm به آن پایبند باشند، چون کل سیستم به آن وابسته است.
چرا نسخهبندی معنایی مهم است؟
از آنجا که npm برخی قواعد را تعیین کرده است، میتوانیم در زمان اجرای دستور npm update از این قواعد در فایل package.json استفاده کنیم تا نسخهای را که میتواند پکیج را به آن بهروزرسانی کند انتخاب کنیم.
در این قواعد از نمادهای زیر استفاده میشود:
- ~
- >
- >=
- <
- <=
- =
- -
- ||
در ادامه هر یک از نمادهای فوق را توضیح میدهیم:
نماد ^: اگر قاعدهای به صورت 0.13.0^ بنویسیم، وقتی که دستور npm update را اجرا میکنید، میتوانید انتشارهای فرعی و وصله را بهروزرسانی کند. برای مثال 0.13.1، 0.14.0 و غیره.
نماد ~: اگر قاعدهای به صورت 0.13.0~ بنویسید هنگامی که دستور npm update را اجرا میکنید، تنها نسخههای وصله بهروزرسانی میشوند. بین ترتیب 0.13.1 درست است، اما 0.14.0 چنین نیست.
نماد >: بدین ترتیب هر نسخهای بالاتر از عددی که ذکرمی شود قابل قبول خواهد بود.
نماد >=: هر نسخهای برابر یا بالاتر از آن که تعیین کردهاید مورد قبول است.
نماد <=: هر نسخهای برابر با پایینتر از عددی تعیین شده قابل قبول است.
نماد <: هر نسخهای پایینتر از عدد ذکر شده مورد پذیرش است.
نماد =: عدد دقیق نسخه مورد قبول است.
نماد –: بازهای از نسخهها مورد قبول است.
نماد | |: چند بازه با هم ترکیب میشوند برای مثال: < 2.1 || > 2.6
شما میتوانید برخی از این نمادها را با هم ترکیب کنید، برای نمونه از 1.0.0 || >=1.1.0 <1.2.0 استفاده کنید تا از نسخه 1.0.0 یا یکی از انتشارهای 1.1.0 به بالا اما پایینتر از 1.2.0 استفاده کنید.
قواعد دیگری نیز وجود دارند:
- بدون نماد: شما تنها نسخه دقیقی را که تعیین شده (برای نمونه 1.2.1) میپذیرید.
- Latest: در این حالت تنها از آخرین نسخه موجود استفاده میشود.
لغو نصب پکیجهای npm به صورت محلی یا سراسری
برای لغو نصب پکیجهایی که قبلاً به صورت محلی با استفاده از <npm install <package-name در پوشه node_modules نصب شدهاند، باید دستور زیر را اجرا کنید:
npm uninstall <package-name>
با استفاده از فلگ s- یا save— این عملیات نیز موجب حذف ارجاع در فایل package.json میشود.
اگر پکیج یک وابستگی توسعه باشد، در بخش devDependencies در فایل package.json فهرست شده است و باید از فلگ D / --save-dev- برای حذف آن از فایل استفاده کنید:
npm uninstall -S <package-name> npm uninstall -D <package-name>
اگر پکیج به صورت سراسری نصب شده باشد، باید فلگ g / --global- را اضافه کنید:
npm uninstall -g <package-name>
مثال:
npm uninstall -g webpack
و میتوانید این دستور را از هر جایی که میخواهید روی سیستم اجرا کنید، چون پوشهای که اکنون در آن قرار دارید اهمیتی ندارد.
پکیجهای محلی یا سراسری npm
اینک شاید بپرسید نصب محلی پکیجها بهتر است یا نصب سراسری آنها و دلیل آن چیست؟ تفاوت اصلی بین پکیجهای محلی و سراسری به شرح زیر است:
پکیجهای محلی
این پکیجها در همان دایرکتوری که دستور <npm install <package-name اجرا میشود، نصب خواهند شد و در پوشه node_modules زیر این دایرکتوری قرار میگیرند.
پکیجهای سراسری
این پکیجها در یک مکان منفرد در سیستم قرار میگیرند که موقعیت دقیق آن به تنظیمات سیستم وابسته است و مهم نیست که دستور <npm install -g <package-name از کجا اجرا شده باشد.
در کد هر دو پکیج به طرز یکسانی «الزام» (require) میشوند:
require('package-name')
اینک شاید بپرسید که پکیجها را باید به چه روشی نصب کنید؟ به طور کلی همه پکیجها باید به صورت محلی نصب شوند. بین ترتیب این اطمینان حاصل میشود که میتوانید اپلیکیشنهای مختلفی روی سیستم خود داشته باشید که در صورت نیاز نسخههای متفاوتی از هر پکیج را اجرا کنند.
بهروزرسانی یک پکیج سراسری موجب میشود که همه پروژهها از انتشارهای جدید استفاده کنند و همان طور که حدس میزنید این وضعیت ازنظر نگهداری اپلیکیشنها یک کابوس محسوب میشود، چون برخی پکیجها ممکن است با وابستگیهای دیگر ناسازگار باشند.
وقتی همه پروژهها نسخههای محلی خود را از یک پکیج دارند، حتی اگر به نظر بیاید که موجب هدررفت منابع میشود، اما این هزینه در برابر عواقب منفی نصب سراسری پکیجها ناچیز است.
یک پکیج زمانی باید به صورت سراسری نصب شود که دستور اجرایی داشته باشد که بتوانید از پوسته (CLI) اجرا کنید و در روی پروژهها قابلیت استفاده مجدد داشته باشد. همچنین میتوانید دستورهای اجرایی را به صورت محلی و با استفاده از npx اجرا کنید، اما برخی پکیجها وقتی که به صورت سراسری نصب میشوند بهتر هستند.
نمونههایی از پکیجهای سراسری که ممکن است بشناسید، به شرح زیر هستند:
- npm
- create-react-app
- vue-cli
- grunt-cli
- mocha
- react-native-cli
- gatsby-cli
- forever
- nodemon
شما ممکن است از قبل برخی پکیجها را روی سیستم خود داشته باشید که به صورت سراسری نصب شده باشند. آنها را میتوان با اجرای دستور زیر در خط فرمان مشاهده کرد:
npm list -g --depth 0
وابستگیهای dependencies و devDependencies
چه زمانی میتوان گفت که یک پکیج، وابستگی (dependency) است و چه هنگام میتوان آن را وابستگی توسعه (DevDependency) نامید؟
زمانی که یک پکیج npm را با استفاده از دستور زیر نصب میکنید، آن را به صورت یک وابستگی نصب کردهاید:
npm install <package-name>
این پکیج به صورت خودکار در فایل package.json و زیر dependencies فهرست میشود. زمانی که فلگ D- را اضافه میکنید یا از فلگ save-dev- استفاده میکنید، پکیج را به صورت یک وابستگی توسعه نصب میکنید و به فهرست devDependencies اضافه میشود.
وابستگیهای توسعه به این منظور ارائه شدهاند که پکیجهایی صرفاً در محیط توسعه اپلیکیشن نصب شوند و قرار نیست در محیط عرضه نهایی (Production) حضور داشته باشند. برای نمونه پکیجهای تست، webpack یا Babel چنین خصوصیتهایی دارند.
زمانی که به محیط Production میرویم، اگر دستور npm install را وارد کنیم و آن پوشه شامل فایل package.json باشد، این پکیجها به صورتی نصب میشوند که npm تصور میکند این یک توزیع توسعه (Development) است.
بدین ترتیب باید فلگ production– را طوری تنظیم کنید (npm install --production) که از نصب این وابستگیهای توسعه جلوگیری کند.
Node Package Runner به نام npx
npx یک روش بسیار جالب برای اجرای کدهای Node.js محسوب میشود و قابلیتهای مفید زیادی ارائه کرده است. در این بخش یک دستور بسیار قدرتمند را معرفی میکنیم که از نسخه 5.2 npm به بعد وجود داشته است. این نسخه که در جولای 2017 انتشار یافته به نام npx شناخته میشود. اگر نمیخواهید npm را نصب کنید، میتوانید آن را به صورت یک پکیج مستقل نصب کنید. npx امکان اجرای کد ساخته شده با Node.js و انتشار یافته از طریق ریپازیتوری npm را فراهم میکند.
اجرای آسان دستورهای محلی
توسعهدهندگان Node.js عادت دارند که اغلب دستورهای اجرایی را به صورت پکیجهای سراسری منتشر کنند تا بیدرنگ در دسترسشان بوده و قابلیت اجرایی داشته باشند. این روش پردردسری است، زیرا عملاً امکان نصب نسخههای مختلفی از یک دستور واحد وجود ندارد. اجرای دستور npx commandname به صورت خودکار باعث میشود که ارجاع صحیحی از دستور در مسیر جاری کاربر، بدون نیاز به دانستن مسیر دقیق و بدون الزام نصب سراسری پکیج، درون پوشه node_modules یک پروژه پیدا شود.
اجرای دستورها بدون نیاز به نصب
npm قابلیت عالی دیگری نیز دارد که امکان اجرای دستورها بدون نصب آنها را فراهم میسازد. این قابلیت بسیار مفید است چون:
- نیاز به نصب هیچ چیزی وجود ندارد.
- میتوان نسخههای مختلفی از یک دستور را با استفاده از ساختار @vrsion اجرا کرد.
یک نمایش نوعی برای استفاده از npx دستور cowsay است. cowsay یک «گفته گاوی» نمایش میدهد که در آن دستوری نوشته شده است. برای نمونه cowsay کاراکترهای زیر را روی صفحه نمایش میدهد:
1_______
2< Hello >
3 -------
4 \ ^__^
5 \ (oo)\_______
6 (__)\ )\/\
7 ||----w |
8 || ||
این وضعیت زمانی است که دستور cowsay را قبلاً به صورت سراسری از npm نصب کرده باشید، در غیر این صورت زمانی که دستور را اجرا کنید، با خطایی مواجه میشوید.
npx امکان اجرای آن دستور npm را بدون الزام به نصب محلی فراهم میسازد:
npx cowsay "Hello"
همان طور که میبینید این یک دستور جالب بیفایده است. سناریوهای دیگر به صورت زیر هستند:
اجرای ابزار CLI مربوط به Vue برای ایجاد اپلیکیشنهای جدید و اجرای آنها با دستور زیر:
npx vue create my-vue-app
ایجاد اپلیکیشن ریاکت جدید با استفاده از :create-react-app:
npx create-react-app my-react-app
و موارد بسیار دیگر؛ زمانی که آن را دانلود کنید، کد دانلود شده پاک میشود.
اجرای برخی کدها با نسخههای مختلف Node.js
با استفاده از @ میتوان اقدام به تعیین نسخه و ترکیب کردن آنها با پکیج npm در node کرد:
npx node@6 -v #v6.14.3 npx node@8 -v #v8.11.3
این وضعیت کمک میکند که دیگر از ابزارهایی مانند nvm یا دیگر ابزارهای مدیریت نسخه Node استفاده نکنیم.
اجرای مستقیم قطعه کدهای دلخواه از یک URL
npx شما را محدود به پکیجهای انتشار یافته روی رجیستری npm نمیکند. بدین ترتیب برای مثال میتوان کدی را که در یک gist گیتهاب قرار دارد اجرا کرد:
npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32
البته هنگام اجرای کدی که روی آن کنترل ندارید، باید مراقب باشید چون چنان که میدانید قدرت زیاد نیاز به مسئولیتپذیری زیادی هم دارد. بدین ترتیب به پایان بخش پنجم از سری مقالات آموزش جامع Node.js رسیدیم و توضیحاتی که در مورد npm وجود داشت را به پایان بردیم. در بخش بعدی در مورد حلقهها، و تایمرها در Node.js خواهیم خواند. برای مطالعه بخش بعدی به لینک زیر رجوع کنید:
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوااسکریپت)
- Node.js چیست و چه نقشی در توسعه وب دارد؟ — به زبان ساده
- مجموعه آموزشهای برنامهنویسی
- Node.js چیست؟ — به زبان ساده
- آموزش Node.js: مفاهیم مقدماتی — بخش اول
==