اذهب إلى المحتوى

دليلك الشامل إلى مدير الحزم npm في Node.js


Ola Abbas

يمثِّل مدير حزم نود npm -اختصارًا إلى Node Package Manager- أساس نجاح Node.js، فقد صدر تقرير في شهر 1 من عام 2017 بوجود أكثر من 350000 حزمة مُدرجَة في سجل npm، مما يجعله أكبر مستودع لشيفرات لغة على الأرض، فكُن على ثقة أنك ستجد فيه حزمةً لكل شيء تقريبًا.

01_npm.png

يُعَدّ npm مدير حزم Node.js المعياري، فقد اُستخدِم في البداية على أساس طريقة لتنزيل وإدارة اعتماديات حزم Node.js، لكنه أصبح بعدها أداةً تُستخدَم في واجهة جافاسكربت الأمامية أيضًا.

اقتباس

توضيح: يُعَدّ Yarn بديلًا عن npm.

إدارة تنزيل الحزم والمكتبات والاعتماديات

يدير npm تنزيلات جميع اعتماديات مشروعك.

تثبيت جميع الاعتماديات Dependencies

يمكنك استخدام الأمر التالي إذا احتوى المشروع على ملف packages.json:

npm install

سيثبِّت كل ما يحتاجه المشروع في المجلد node_modules مع إنشاء هذا المجلد إذا لم يكن موجودًا مسبقًا.

تثبيت حزمة واحدة

يمكنك أيضًا تثبيت حزمة معينة عن طريق تشغيل الأمر:

npm install <package-name>

سترى في أغلب الأحيان مزيدًا من الرايات flags المضافة إلى هذا الأمر مثل:

  • ‎--save التي تثبّت وتضيف مدخلة إلى اعتماديات ملف package.json وهي الافتراضية فلا داعي لإضافتها في كل مرة تثبت فيها حزمة في مشروعك.
  • ‎--save-dev التي تثبّت وتضيف مدخلة إلى اعتماديات تطوير devDependencies ملف package.json.

يتمثل الاختلاف الأساسي بينهما في أن اعتماديات التطوير devDependencis هي أدوات تطوير مثل مكتبة الاختبار، بينما تُجمَّع الاعتماديات dependencies مع التطبيق الذي يكون قيد الإنتاج.

يمكن تثبيت إصدار أقدم من حزمة npm أو تثبيت إصدار محدد بعينه، وهو شيء قد يكون مفيدًا في حل مشكلة التوافق، كما يمكنك تثبيت إصدار قديم من حزمة npm باستخدام صيغة @ كما يلي:

npm install <package>@<version>

يثبّت الأمر التالي الإصدار الإصدار الأخير الأحدث من حزمة cowsay:

npm install cowsay

يمكنك تثبيت الإصدار 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' ]

مكان تثبيت npm للحزم

يمكنك إجراء نوعين من التثبيت، عند تثبيت حزمة باستخدام npm أو yarn:

  • تثبيت محلي local install.
  • تثبيت عام global install.

إذا كتبتَ أمر تثبيت npm install مثل الأمر التالي، فستُثبَّت الحزمة في شجرة الملفات الحالية ضمن المجلد الفرعي node_modules افتراضيًا، ويضيف عندها npm أيضًا المدخلة lodash في خاصية الاعتماديات dependencies الخاصة بملف package.json الموجود في المجلد الحالي:

npm install lodash

يُطبَّق التثبيت العام باستخدام الراية ‎-g:

npm install -g lodash

لن يثبِّت npm الحزمة ضمن المجلد المحلي وإنما سيستخدم موقعًا عامًا، إذ سيخبرك الأمر npm root -g بمكان هذا الموقع الدقيق على جهازك، حيث يمكن أن يكون هذا الموقع ‎/usr/local/lib/node_modules في نظام macOS أو لينكس، ويمكن أن يكون C:\Users\YOU\AppData\Roaming\npm\node_modules على نظام ويندوز، لكن إذا استخدمت nvm لإدارة إصدارات Node.js، فقد يختلف هذا الموقع، حيث استخدمنا nvm على سبيل المثال وكان موقع الحزم هو ‎/Users/flavio/.nvm/versions/node/v8.9.0/lib/node_modules.

كيفية استخدام أو تنفيذ حزمة مثبتة باستخدام npm

هل تساءلت عن كيفية تضمين واستخدام حزمة مثبَّتة في مجلد node_modules في شيفرتك الخاصة؟ حسنًا، لنفترض أنك ثبَّت مكتبة أدوات جافاسكربت الشائعة lodash باستخدام الأمر التالي:

npm install lodash

سيؤدي ذلك إلى تثبيت الحزمة في مجلد node_modules المحلي التي يمكنك استخدامها في شيفرتك الخاصة من خلال استيرادها في برنامجك باستخدام require:

const _ = require('lodash)

إذا كانت حزمتك الخاصة قابلة للتنفيذ، فسيوضَع الملف القابل للتنفيذ ضمن المجلد node_modules/.bin/‎، وإحدى طرق إثبات ذلك هي استخدام الحزمة cowsay، حيث توفِّر هذه الحزمة برنامج سطر أوامر يمكن تنفيذه لإنشاء بقرة تقول شيئًا -وحيوانات أخرى أيضًا-، حيث ستثبِّت هذه الحزمة نفسها وعددًا من الاعتماديات في المجلد node_modules عند تثبيتها باستخدام الأمر npm install cowsay:

02_CowsayInstallation.png

يوجد مجلد ‎.bin‎‎ مخفي يحتوي على روابط رمزية إلى ملفات cowsay الثنائية:

03_CowsayBinFolder.png

يمكنك تنفيذ هذه الحزمة من خلال كتابة ‎./node_modules/.bin/cowsay لتشغيلها، لكن يُعَدّ npx المُضمَّن في الإصدارات الأخيرة من npm -منذ الإصدار 5.2- الخيار الأفضل، فما عليك إلا تشغيل الأمر التالي:

npx cowsay

وسيجد npx موقع الحزمة.

تحديث الحزم

أصبح التحديث سهلًا أيضًا عن طريق تشغيل الأمر:

npm update

سيتحقّق npm من جميع الحزم بحثًا عن إصدار أحدث يلبي قيود إدارة الأصدارات Versioning الخاصة بك، كما يمكنك تحديد حزمة واحدة لتحديثها أيضًا باستخدام الأمر:

npm update <package-name>

إذا أردت تحديث جميع اعتماديات npm المخزَّنة في الملف package.json -الذي سنشرحه بعد قليل- إلى أحدث إصدار متاح لها، فثبَّتَ حزمةً باستخدام الأمر npm install <packagename>‎ الذي سينزِّل أحدث إصدار متاح من الحزمة ويوضَع هذا الإصدار في مجلد node_modules، وستُضاف مدخلة مقابلة إلى الملف package.json والملف package-lock.json الموجودَين في مجلدك الحالي، إذ يحسب npm الاعتماديات ويثبّت أحدث إصدار متاح منها أيضًا.

لنفترض أنك ثبَّتَ الحزمة cowsay، وهي أداة سطر أوامر رائعة تتيح لك إنشاء بقرة تقول أشياء، فإذا ثبَّتَها باستخدام الأمر npm install cowsay، فستضاف المدخلة التالية إلى ملف package.json:

{
  "dependencies": {
     "cowsay": "^1.3.1"
  }
}

يمثّل ما يلي جزءًا من ملف package-lock.json، حيث أزلنا الاعتماديات المتداخلة للتوضيح:

{
  "requires": true,
  "lockfileVersion": 1,
  "dependencies": {
     "cowsay": {
        "version": "1.3.1",
        "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz",
        "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==",
        "requires": {
           "get-stdin": "^5.0.1",
           "optimist": "~0.6.1",
           "string-width": "~2.1.1",
           "strip-eof": "^1.0.0"
        }
     }
  }
}

يوضّح هذان الملفان أننا ثبَّتنا الإصدار 1.3.1 من الحزمة cowsay باستخدام قاعدة التحديثات ‎^1.3.1، والتي تعني بالنسبة لقواعد إدارة إصدارات npm أنه يمكن تحديث npm إلى إصدار حزمة التصحيح patch والإصدار الثانوي minor، أي 0.13.1 و0.14.0 وما إلى ذلك، فإذا كان هناك إصدار ثانوي أو إصدار حزمة تصحيح جديد وكتبنا الأمر npm update، فسيُحدَّث الإصدار المثبَّت، وسيُملَأ ملف package-lock.json بالإصدار الجديد، بينما يبقى الملف package.json دون تغيير، كما يمكنك اكتشاف إصدارات الحزم الجديدة من خلال تشغيل الأمر npm outdated، وفيما يلي قائمة ببعض الحزم القديمة في مستودع واحد لم نحدِّثها لفترة طويلة:

05_OutdatedPackages.png

تُعَدّ بعض هذه التحديثات إصدارات رئيسية، إذ لن يؤدي تشغيل الأمر 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 أيضًا -بالإضافة إلى التنزيلات العادية- عملية الأصدَرة versioning، بحيث يمكنك تحديد إصدار معيّن من الحزمة، أو طلب إصدار أحدث أو أقدم مما تحتاجه، وستجد في كثير من الأحيان أنّ المكتبة متوافقة فقط مع إصدار رئيسي لمكتبة أخرى، أو قد تجد خطأً غير مُصحَّح بعد في الإصدار الأخير من مكتبة، مما يسبِّب مشاكلًا، كما يساعد تحديد إصدار صريح من مكتبة أيضًا في إبقاء كل فريق العمل على إصدار الحزمة الدقيق نفسه، بحيث يشغّل الفريق بأكمله الإصدار نفسه حتى تحديث ملف package.json.

تساعد عملية تحديد الإصدار كثيرًا في جميع الحالات السابقة، حيث يتبع npm معيار إدارة الإصدارات الدلالية semantic versioning - أو semver اختصارًا- والذي سنشرحه تاليًا في قسم منفصل، وقد تحتاج عمومًا إلى معرفة إصدار حزمة معينة ثبَّتها في تطبيقك، وهنا يمكنك استخدم الأمر التالي لمعرفة الإصدار الأحدث من جميع حزم 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، فشغّل الأمر npm view [package_name] version كما يلي:

npm view cowsay version

1.3.1

إلغاء تثبيت حزم npm

قد تسأل نفسك ماذا لو أردت إلغاء تثبيت حزمة npm المُثبَّتة تثبيتًا محليًا أو عامًا؟ يمكنك إلغاء تثبيت حزمة مثبَّتة مسبقًا محليًا locally باستخدام الأمر npm install <packagename>‎ في مجلد node_modules من خلال تشغيل الأمر التالي في مجلد جذر المشروع، أي المجلد الذي يحتوي على مجلد 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>

إذا ثُبِّتت الحزمة تثبيتًا عامًا globally، فيجب إضافة الراية ‎-g أو الراية ‎--global كما يلي:

npm uninstall -g <package-name>

إليك المثال التالي:

npm uninstall -g webpack

كما يمكنك تشغيل هذا الأمر من أي مكان تريده على نظامك لأن المجلد الذي تتواجد فيه حاليًا غير مهم.

تشغيل مهام وتنفيذ سكربتات من سطر الأوامر

يدعم ملف package.json تنسيقًا لتحديد مهام سطر الأوامر التي يمكن تشغيلها باستخدام الأمر التالي:

npm run <task-name>

فمثلًا:

{
  "scripts": {
     "start-dev": "node lib/server-development",
     "start": "node lib/server-production"
  },
}

يشيع استخدام هذه الميزة لتشغيل Webpack:

{
  "scripts": {
     "watch": "webpack --watch --progress --colors --config webpack.conf.js",
     "dev": "webpack --progress --colors --config webpack.conf.js",
     "prod": "NODE_ENV=production webpack -p --config webpack.conf.js",
  },
}

يمكنك تشغيل الأوامر التالية بدلًا من كتابة الأوامر الطويلة السابقة التي يسهل نسيانها أو كتابتها بصورة خاطئة:

$ npm run watch
$ npm run dev
$ npm run prod

04_CowsayNpx.png

الملف package.json نقطة ارتكاز المشروع

يُعَدّ ملف package.json عنصرًا أساسيًا في كثير من قواعد شيفرات التطبيقات المستندة إلى نظام Node.js المجتمعي، فإذا استخدمت سابقًا لغة جافاسكريبت أو تعاملت مع مشروع JavaScript أو Node.js أو مشروع واجهة أمامية، فلا بد أنك صادفت ملف package.json، كما يُعَدّ ملف package.json بيانًا manifest لمشروعك، إذ يمكنه تطبيق أشياء غير مرتبطة متعددة، فهو مستودع مركزي لإعداد الأدوات مثلًا، كما أنه المكان الذي يخزّن فيه npm وyarn أسماء وإصدارات الحزم المُثبَّتة.

معمارية الملف package.json

فيما يلي مثال لملف package.json:

{

}

هذا الملف فارغ، إذ لا توجد متطلبات ثابتة لما يجب تواجده في ملف package.json خاص بتطبيقٍ ما، فالشرط الوحيد هو أنه يجب أن يتبع تنسيق JSON، وإلّا فلا يمكن أن تقرأه البرامج التي تحاول الوصول إلى خصائصه برمجيًا، وإذا أردت بناء حزمة Node.js التي ترغب في توزيعها عبر npm، فسيتغيّر كل شيء جذريًا، إذ يجب أن يكون لديك مجموعة من الخصائص التي ستساعد الأشخاص الآخرين على استخدام هذا الملف، حيث سنتحدّث عن ذلك لاحقًا، وإليك مثال آخر عن ملف package.json:

{
  "name": "test-project"
}

يعرِّف الملف السابق خاصية الاسم name والتي تعطي اسم التطبيق أو الحزمة الموجودة في المجلد نفسه الذي يوجد فيه هذا الملف، وإليك المثال التالي الأكثر تعقيدًا والمُستخرَج من عينة تطبيق Vue.js:

{
  "name": "test-project",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "main": "src/main.js",
  "private": true,
  "scripts": {
     "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
     "start": "npm run dev",
     "unit": "jest --config test/unit/jest.conf.js --coverage",
     "test": "npm run unit",
     "lint": "eslint --ext .js,.vue src test/unit",
     "build": "node build/build.js"
  },
  "dependencies": {
     "vue": "^2.5.2"
  },
  "devDependencies": {
     "autoprefixer": "^7.1.2",
     "babel-core": "^6.22.1",
     "babel-eslint": "^8.2.1",
     "babel-helper-vue-jsx-merge-props": "^2.0.3",
     "babel-jest": "^21.0.2",
     "babel-loader": "^7.1.1",
     "babel-plugin-dynamic-import-node": "^1.2.0",
     "babel-plugin-syntax-jsx": "^6.18.0",
     "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
     "babel-plugin-transform-runtime": "^6.22.0",
     "babel-plugin-transform-vue-jsx": "^3.5.0",
     "babel-preset-env": "^1.3.2",
     "babel-preset-stage-2": "^6.22.0",
     "chalk": "^2.0.1",
     "copy-webpack-plugin": "^4.0.1",
     "css-loader": "^0.28.0",
     "eslint": "^4.15.0",
     "eslint-config-airbnb-base": "^11.3.0",
     "eslint-friendly-formatter": "^3.0.0",
     "eslint-import-resolver-webpack": "^0.8.3",
     "eslint-loader": "^1.7.1",
     "eslint-plugin-import": "^2.7.0",
     "eslint-plugin-vue": "^4.0.0",
     "extract-text-webpack-plugin": "^3.0.0",
     "file-loader": "^1.1.4",
     "friendly-errors-webpack-plugin": "^1.6.1",
     "html-webpack-plugin": "^2.30.1",
     "jest": "^22.0.4",
     "jest-serializer-vue": "^0.3.0",
     "node-notifier": "^5.1.2",
     "optimize-css-assets-webpack-plugin": "^3.2.0",
     "ora": "^1.2.0",
     "portfinder": "^1.0.13",
     "postcss-import": "^11.0.0",
     "postcss-loader": "^2.0.8",
     "postcss-url": "^7.2.1",
     "rimraf": "^2.6.0",
     "semver": "^5.3.0",
     "shelljs": "^0.7.6",
     "uglifyjs-webpack-plugin": "^1.1.1",
     "url-loader": "^0.5.8",
     "vue-jest": "^1.0.2",
     "vue-loader": "^13.3.0",
     "vue-style-loader": "^3.0.1",
     "vue-template-compiler": "^2.5.2",
     "webpack": "^3.6.0",
     "webpack-bundle-analyzer": "^2.9.0",
     "webpack-dev-server": "^2.9.1",
     "webpack-merge": "^4.1.0"
  },
  "engines": {
     "node": ">= 6.0.0",
     "npm": ">= 3.0.0"
  },
  "browserslist": [
     "> 1%",
     "last 2 versions",
     "not ie <= 8"
  ]
}

هناك خاصيات متعددة يجب شرحها في المثال السابق:

  • name التي تضبط اسم التطبيق أو الحزمة.
  • version التي تشير إلى الإصدار الحالي.
  • description وهي وصف مختصَر للتطبيق أو للحزمة.
  • main التي تضبط نقطة الدخول للتطبيق.
  • private التي تمنع نشر التطبيق أو الحزمة عن طريق الخطأ على npm إذا ضُبِطت على القيمة true.
  • scripts التي تحدّد مجموعة من سكربتات نود التي يمكنك تشغيلها.
  • dependencies التي تضبط قائمة بحزم npm المثبَّتة كاعتماديات.
  • devDependencies التي تضبط قائمة بحزم npm المثبَّتة كاعتماديات تطوير.
  • engines التي تحدّد إصدار نود الذي تعمل عليه هذه الحزمة أو التطبيق.
  • browserslist التي تُستخدَم لمعرفة المتصفحات وإصداراتها التي تريد دعمها.

تُستخدَم جميع هذه الخصائص إما باستخدام npm أو باستخدام أدوات أخرى.

خاصيات الملف package.json

يشرح هذا القسم الخاصيات التي يمكنك استخدامها ضمن الملف package.json بالتفصيل، حيث سنطبّق كل شيء على الحزمة، ولكن يمكن تطبيق الشيء نفسه على التطبيقات المحلية التي لا تستخدِمها على أساس حزم، كما تُستخدَم معظم هذه الخاصيات فقط على npm، ويُستخدَم البعض الآخر بواسطة السكربتات التي تتفاعل مع شيفرتك مثل npm أو غيره.

name

تضبط هذه الخاصية اسم الحزمة مثل المثال التالي:

"name": "test-project"

يجب أن يتضمّن الاسم أقل من 214 محرفًا وألا يحتوي على مسافات، كما لا يمكن أن يحتوي إلّا على أحرف صغيرة أو واصلات - أو شرطات سفلية _، وذلك لأن الحزمة تحصل على عنوان URL الخاص بها بناءً على هذه الخاصية عند نشرها على npm، إذا نشرتَ هذه الحزمة علنًا على GitHub، فستكون القيمة المناسبة لهذه الخاصية هي اسم مستودع GitHub.

author

تعطي هذه الخاصية اسم مؤلف الحزمة مثل المثال التالي:

{
  "author": "Flavio Copes <flavio@flaviocopes.com> (https://flaviocopes.com)"
}

يمكن استخدامها أيضًا بالتنسيق التالي:

{
  "author": {
     "name": "Flavio Copes",
     "email": "flavio@flaviocopes.com",
     "url": "https://flaviocopes.com"
  }
}

contributors

يمكن أن يكون للمشروع مساهم أو أكثر بالإضافة إلى المؤلف، وهذه الخاصية هي مصفوفة تعطي قائمة المساهمين مثل المثال التالي:

{
  "contributors": [
     "Flavio Copes <flavio@flaviocopes.com> (https://flaviocopes.com)"
  ]
}

كما يمكن استخدام هذه الخاصية أيضًا بالتنسيق التالي:

{
  "contributors": [
     {
        "name": "Flavio Copes",
        "email": "flavio@flaviocopes.com",
        "url": "https://flaviocopes.com"
     }
  ]
}

bugs

تُستخدَم هذه الخاصية للربط بمتتبّع مشاكل الحزمة، أي بصفحة مشاكل GitHub مثلًا كما يلي:

{
  "bugs": "https://github.com/flaviocopes/package/issues"
}

homepage

تضبط هذه الخاصية صفحة الحزمة الرئيسية مثل المثال التالي:

{
  "homepage": "https://flaviocopes.com/package"
}

version

تشير هذه الخاصية إلى إصدار الحزمة الحالي مثل المثال التالي:

"version": "1.0.0"

تتبع هذه الخاصية صيغة إدارة الإصدارات الدلالية semver، مما يعني أنّ الإصدار يُعبَّر عنه دائمًا بثلاثة أعداد: x.x.x، حيث يمثِّل العدد الأول الإصدار الرئيسي، ويمثِّل العدد الثاني الإصدار الثانوي؛ أما العدد الثالث فهو إصدار حزمة التصحيح patch version، فالإصدار الذي يصلح الأخطاء فقط هو إصدار حزمة التصحيح، والإصدار الذي يقدّم تغييرات متوافقة مع الإصدارات السابقة هو الإصدار الثانوي، كما يمكن أن يحتوي الإصدار الرئيسي على تغييرات جذرية.

license

تشير إلى رخصة الحزمة مثل المثال التالي:

"license": "MIT"

keywords

تحتوي هذه الخاصية على مصفوفة من الكلمات المفتاحية المرتبطة بما تفعله حزمتك مثل المثال التالي:

"keywords": [
  "email",
  "machine learning",
  "ai"
]

تساعد هذه الخاصية في العثور على حزمتك عند التنقل بين حزم مماثلة، أو عند تصفح موقع npm.

description

تحتوي هذه الخاصية على وصف مختصَر للحزمة مثل المثال التالي:

"description": "A package to work with strings"

هذه الخاصية مفيدة إذا قرّرت نشر حزمتك على npm لمعرفة معلومات الحزمة.

repository

تحدّد هذه الخاصية مكان وجود مستودع الحزمة مثل المثال التالي:

"repository": "github:flaviocopes/testing",

لاحظ البادئة github، وهناك خدمات شائعة أخرى مثل gitlab:

"repository": "gitlab:flaviocopes/testing",

وأيضًا bitbucket:

"repository": "bitbucket:flaviocopes/testing",

يمكنك ضبط نظام التحكم بالإصدارات بصورة صريحة كما يلي:

"repository": {
  "type": "git",
  "url": "https://github.com/flaviocopes/testing.git"
}

كما يمكنك استخدام أنظمة مختلفة للتحكم بالإصدارات كما يلي:

"repository": {
  "type": "svn",
  "url": "..."
}

main

تضبط هذه الخاصية نقطة الدخول إلى الحزمة، وهي المكان الذي سيبحث فيه التطبيق عن عمليات تصدير الوحدة عند استيرادها في أحد التطبيقات مثل المثال التالي:

"main": "src/main.js"

private

إذا ضُبِطت هذه الخاصية على القيمة true، فستمنع نشر التطبيق أو الحزمة عن طريق الخطأ على npm كما يلي:

"private": true

scripts

تحدّد هذه الخاصية مجموعة سكربتات نود التي يمكنك تشغيلها مثل المثال التالي:

"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  "unit": "jest --config test/unit/jest.conf.js --coverage",
  "test": "npm run unit",
  "lint": "eslint --ext .js,.vue src test/unit",
  "build": "node build/build.js"
}

تُعَدّ هذه السكربتات تطبيقات سطر الأوامر، حيث يمكنك تشغيلها عن طريق استدعاء الأمر npm run XXXX أو yarn XXXX، حيث XXXX هو اسم الأمر مثل npm run dev، كما يمكنك إعطاء الأمر أيّ اسم تريده، ويمكن للسكربتات فعل أيّ شيء تريده.

dependencies

تضبط هذه الخاصية قائمة حزم npm المثبَّتة على أساس اعتماديات. إذا ثبَّتَ حزمةً باستخدام npm أو yarn كما يلي:

npm install <PACKAGENAME>
yarn add <PACKAGENAME>

ستُدخَل تلك الحزمة في هذه القائمة تلقائيًا، وإليك المثال التالي:

"dependencies": {
  "vue": "^2.5.2"
}

devDependencies

تضبط هذه الخاصية قائمة حزم npm المثبَّتة على أساس اعتماديات تطوير، وهي تختلف عن الخاصية dependencies لأنها مُخصَّصة للتثبيت على آلة تطوير فقط، وليست ضرورية لتشغيل الشيفرة في عملية الإنتاج، فإذا ثبَّتَ حزمةً باستخدام npm أو yarn:

npm install --dev <PACKAGENAME>
yarn add --dev <PACKAGENAME>

فستُدخَل تلك الحزمة في هذه القائمة تلقائيًا، وإليك المثال التالي:

"devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.22.1"
}

engines

تضبط هذه الخاصية إصدارات Node.js والأوامر الأخرى التي تعمل عليها هذه الحزمة أو التطبيق مثل المثال التالي:

"engines": {
  "node": ">= 6.0.0",
  "npm": ">= 3.0.0",
  "yarn": "^0.13.0"
}

browserslist

تُستخدَم هذه الخاصية لمعرفة المتصفحات وإصداراتها التي تريد دعمها، وقد أشارت إليها أدوات Babel وAutoprefixer وأدوات أخرى أنها تُستخدَم لإضافة تعويض نقص دعم المتصفحات polyfills والنسخ الاحتياطية fallbacks اللازمة للمتصفحات التي تستهدفها، وإليك المثال التالي:

"browserslist": [
  "> 1%",
  "last 2 versions",
  "not ie <= 8"
]

يعني الإعداد السابق أنك تريد دعم آخر إصدارين رئيسيين من جميع المتصفحات باستخدام 1‎%‎ على الأقل -من إحصائيات موقع caniuse- باستثناء الإصدار IE8 والإصدارات الأقدم (اطلع على المزيد من موقع حزمة).

خصائص خاصة بالأوامر

يمكن أن يستضيف ملف package.json أيضًا إعدادًا خاصًا بالأوامر مثل Babel وESLint وغير ذلك، فلكل منها خاصية معينة مثل eslintConfig وbabel وغيرها، وهذه هي الخصائص الخاصة بالأوامر، كما يمكنك العثور على كيفية استخدامها في توثيق الأمر أو المشروع المرتبط بها.

إصدارات الحزم

رأيت في الوصف أعلاه أرقام الإصدارات مثل: ‎~3.0.0 أو ‎^0.13.0، حيث يحدِّد الرمز الموجود على يسار رقم الإصدار التحديثات التي تقبلها الحزمة من تلك الاعتمادية، ولنفترض استخدام semver -الأصدَرة الدلالية semantic versioning-، حيث تتضمن جميع الإصدارات 3 خانات عددية، أولها هو الإصدار الرئيسي وثانيها هو الإصدار الثانوي وثالثها هو إصدار حزمة التصحيح patch release، وبالتالي لديك القواعد التالية:

  • ~: إذا كتبت ‎~0.13.0، فهذا يعني أنك تريد فقط تحديث إصدارات حزمة التصحيح، أي أنّ الإصدار 0.13.1 مقبول، ولكن الإصدار 0.14.0 ليس كذلك.
  • ^: إذا كتبت ‎^0.13.0، فهذا يعني أنك تريد تحديث إصدار حزمة التصحيح والإصدار الثانوي، أي الإصدارات 0.13.1 و0.14.0 وهكذا.
  • *: إذا كتبت *، فهذا يعني أنك تقبل جميع التحديثات بما في ذلك ترقيات الإصدارات الرئيسية.
  • <: أي أنك تقبل أي إصدار أعلى من الإصدار الذي تحدِّده.
  • =‎<: أي أنك تقبل أي إصدار مساوي أو أعلى من الإصدار الذي تحدِّده.
  • =>: أي أنك تقبل أي إصدار مساوي أو أدنى من الإصدار الذي تحدِّده.
  • >: أي أنك تقبل أي إصدار أدنى من الإصدار الذي تحدِّده.

وهناك قواعد أخرى هي:

  • بدون رمز: أي أنك تقبل فقط الإصدار الذي تحدّده.
  • latest: أي أنك تريد استخدام أحدث إصدار متاح.

كما يمكنك دمج معظم ما سبق ضمن مجالات مثل 1.0.0‎ || >=1.1.0 <1.2.0 لاستخدم إما الإصدار 1.0.0 أو أحد الإصدارات الأعلى أو المساوية للإصدار 1.1.0 والأدنى من الإصدار 1.2.0.

الملف package-lock.json ودوره في إدارة الإصدارات

يُنشَأ الملف package-lock.json تلقائيًا عند تثبيت حزم نود، حيث قدَّم npm ملف package-lock.json في الإصدار رقم 5، والهدف من هذا الملف هو تتبّع الإصدار الدقيق لكل حزمة مثبَّتة، وبالتالي فإن المنتج قابل لإعادة الإنتاج بنسبة 100% بالطريقة نفسها حتى إذا حدّث القائمون على الصيانة الحزم، كما يحل ذلك مشكلةً تركَها ملف package.json دون حل، إذ يمكنك في ملف package.json ضبط الإصدارات التي تريد الترقية إليها -أي إصدار حزمة التصحيح أو الإصدار الثانوي- باستخدام صيغة semver كما يلي:

  • إذا كتبت ‎~0.13.0، فهذا يعني أنك تريد فقط تحديث إصدار حزمة التصحيح، أي أن الإصدار 0.13.1 مقبول، ولكن الإصدار 0.14.0 ليس كذلك.
  • إذا كتبت ‎^0.13.0، فهذا يعني أنك تريد تحديث إصدار حزمة التصحيح والإصدار الثانوي، أي الإصدارات 0.13.1 و0.14.0 وهكذا.
  • إذا كتبت 0.13.0، فهذا يعني الإصدار الدقيق الذي سيُستخدَم.

لستَ ملزَمًا بتوزيع مجلد node_modules الضخم باستخدام برنامج جت Git، وإذا حاولتَ نسخ المشروع على جهاز آخر باستخدام الأمر npm install -إذا حدّدتَ الصيغة ~ مع إصدار حزمة التصحيح الخاص بالحزمة- فسيثبَّت هذا الإصدار، كما يحدث الأمر ذاته مع الصيغة ^ والإصدارات الثانوية.

اقتباس

توضيح: إذا حدّدتَ إصدارات معينة مثل الإصدار 0.13.0، فلن تتأثر بهذه المشكلة.

قد تحاول أنت أو أي شخص آخر تهيئة المشروع على الجانب الآخر من العالم عن طريق تشغيل الأمر npm install، لذلك فإن مشروعك الأصلي والمشروع المُهيَّأ حديثًا مختلفان فعليًا، إذ يجب ألّا يدخِل إصدار حزمة التصحيح أو الإصدار الثانوي تغييرات معطِّلة، ولكننا نعلم أن الأخطاء ممكنة الحدوث وستحدث بالفعل.

يضبط ملف package-lock.json الإصدار المثبَّت حاليًا من كل حزمة باستخدام رمز stone، وسيستخدِم npm هذه الإصدارات المحدَّدة عند تشغيل الأمر npm install، كما أنّ هذا المفهوم ليس بجديد، إذ يستخدِم مديرو حزم لغات البرمجة الأخرى -مثل مكتبات Composer في لغة PHP- نظامًا مشابهًا منذ سنوات.

يجب أن يكون ملف package-lock.json ملتزمًا بمستودع Git الخاص بك حتى يجلبه أشخاص آخرون إذا كان المشروع عامًا أو لديك متعاونون أو إذا استخدمت Git على أساس مصدر لعمليات النشر، كما ستُحدَّث إصدارات الاعتماديات في ملف package-lock.json عند تشغيل الأمر npm update.

يوضِّح المثال التالي معمارية ملف package-lock.json التي نحصل عليها عند تشغيل الأمر npm install cowsay في مجلد فارغ:

{
  "requires": true,
  "lockfileVersion": 1,
  "dependencies": {
     "ansi-regex": {
        "version": "3.0.0",
        "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
        "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
  },
  "cowsay": {
     "version": "1.3.1",
     "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz",
     "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==",
     "requires": {
        "get-stdin": "^5.0.1",
        "optimist": "~0.6.1",
        "string-width": "~2.1.1",
        "strip-eof": "^1.0.0"
     }
  },
  "get-stdin": {
     "version": "5.0.1",
     "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
     "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="
  },
  "is-fullwidth-code-point": {
     "version": "2.0.0",
     "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
     "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
  },
  "minimist": {
     "version": "0.0.10",
     "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
     "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
  },
  "optimist": {
     "version": "0.6.1",
     "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
     "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",

     "requires": {
        "minimist": "~0.0.1",
        "wordwrap": "~0.0.2"
     }
  },
  "string-width": {
     "version": "2.1.1",
     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
     "requires": {
        "is-fullwidth-code-point": "^2.0.0",
        "strip-ansi": "^4.0.0"
     }
  },
  "strip-ansi": {
     "version": "4.0.0",
     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
     "requires": {
        "ansi-regex": "^3.0.0"
     }
  },
  "strip-eof": {
     "version": "1.0.0",
     "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
     "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
  },
  "wordwrap": {
     "version": "0.0.3",
     "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
     "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
     }
  }
}

ثبّتنا حزمة cowsay التي تعتمد على الحزم التالية:

  • get-stdin.
  • optimist.
  • string-width.
  • strip-eof.

تتطلب هذه الحزم حزمًا أخرى مثل الحزم الموجودة في الخاصية requires كما يلي:

  • ansi-regex.
  • is-fullwidth-code-point.
  • minimist.
  • wordwrap.
  • strip-eof.

تُضاف هذه الحزم إلى الملف بالترتيب الأبجدي، ولكل منها حقل version، وحقل resolved يؤشّر إلى موقع الحزمة، وسلسلة نصية integrity يمكننا استخدامها للتحقق من الحزمة.

قواعد الإدارة الدلالية لنسخ الاعتماديات

تُعَدّ الإدارة الدلالية لنسخ الاعتماديات Semantic Versioning اصطلاحًا يُستخدَم لتوفير معنى للإصدارات، فإذا كان هناك شيء رائع في حزم Node.js، فهو اتفاق الجميع على استخدام هذا المفهوم لترقيم إصداراتهم، كما يُعَدّ مفهوم الإدارة الدلالية للنسخ بسيطًا للغاية، فلكل الإصدارات 3 خانات عددية x.y.z:

  • العدد الأول هو الإصدار الرئيسي.
  • العدد الثاني هو الإصدار الثانوي.
  • العدد الثالث هو إصدار التصحيح.

إذا أردت إنشاء إصدار جديد، فلن تزيد عددًا كما يحلو لك، بل لديك قواعد يجب الالتزام بها وهي:

  • يُحدَّث الإصدار الرئيسي عند إجراء تغييرات غير متوافقة مع واجهة برمجة التطبيقات API.
  • يُحدَّث الإصدار الثانوي عند إضافة عمليات بطريقة متوافقة مع الإصدارات السابقة.
  • يُحدَّث إصدار تصحيح عند إجراء إصلاحات أخطاء متوافقة مع الإصدارات السابقة.

اُعتمِد هذا المفهوم في جميع لغات البرمجة ومن المهم أن تلتزم بها كل حزمة npm لأن النظام بأكمله يعتمد على ذلك، إذ وضَع npm بعض القواعد التي يمكننا استخدامها في ملف package.json لاختيار الإصدارات التي يمكن تحديث حزمنا إليها عند تشغيل الأمر npm update، وتستخدِم هذه القواعد الرموز التالية:

  • ^: إذا كتبت ‎^0.13.0 عند تشغيل الأمر npm update، فهذا يؤدي إلى تحديث إصدار حزمة التصحيح والإصدار الثانوي، أي الإصدارات 0.13.1 و0.14.0 وهكذا.
  • ~: إذا كتبت ‎~0.13.0 عند تشغيل الأمر npm update، فهذا يؤدي إلى تحديث إصدارات حزمة التصحيح، أي أن الإصدار 0.13.1 مقبول، ولكن الإصدار 0.14.0 ليس كذلك.
  • <: أي أنك تقبل أي إصدار أعلى من الإصدار الذي تحدده.
  • =‎<: أي أنك تقبل أي إصدار مساوي أو أعلى من الإصدار الذي تحدّده.
  • =>: أي أنك تقبل أي إصدار مساوي أو أدنى من الإصدار الذي تحدّده.
  • >: أي أنك تقبل أي إصدار أدنى من الإصدار الذي تحدّده.
  • =: أي أنك تقبل الإصدار المحدَّد.
  • -: أي أنك تقبل مجالًا من الإصدارات مثل المجال مثل: 2.1.0‎ - 2.6.2.
  • ||: يُستخدَم لدمج مجموعات من الإصدارات مثل: ‎< 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 install <package-name>‎، وتوضَع في مجلد node_modules ضمن هذا المجلد أو المسار.
  • توضَع جميع الحزم العامة في مكان واحد في نظامك بالاعتماد على إعدادك الخاص بغض النظر عن مكان تشغيل الأمر npm install -g <package-name>‎.

وكلاهما مطلوب بالطريقة نفسها في شيفرتك الخاصة كما يلي:

require('package-name')

يجب تثبيت جميع الحزم محليًا، إذ يضمن ذلك أنه يمكنك الحصول على عشرات التطبيقات على حاسوبك، وتشغِّل جميعها إصدارًا مختلفًا من كل حزمة إذ لزم الأمر، بينما سيجعل تحديث حزمة عامة جميع مشاريعك تستخدِم الإصدار الجديد، مما قد يسبّب مشاكلًا ضخمةً في عملية الصيانة، حيث قد تخرِّب بعض الحزم التوافق بمزيد من الاعتماديات وما إلى ذلك.

تحتوي جميع المشاريع على نسختها المحلية الخاصة من الحزمة، فقد يبدو ذلك ضياعًا للموارد، ولكنه ضياع ضئيل بالموازنة مع العواقب السلبية المحتمَلة، كما يجب تثبيت الحزمة العامة عندما توفِّر هذه الحزمة أمرًا قابلًا للتنفيذ بحيث تشغّله من الصدفة shell أي واجهة سطر الأوامر CLI، ويُعاد استخدام هذه الحزمة عبر المشاريع، كما يمكنك أيضًا تثبيت الأوامر القابلة للتنفيذ محليًا وتشغيلها باستخدام npx، ولكن تثبيت الحزم العامة أفضل بالنسبة لبعض الحزم.

فيما يلي أمثلة رائعة عن الحزم العامة الشائعة التي قد تعرفها:

  • npm.
  • create-react-app.
  • vue-cli.
  • grunt-cli.
  • mocha.
  • react-native-cli.
  • gatsby-cli.
  • forever.
  • nodemon.

يُحتمَل أن تكون لديك بعض الحزم العامة المثبَّتة على نظامك التي يمكنك رؤيتها عن طريق تشغيل الأمر التالي في سطر الأوامر الخاص بك:

npm list -g --depth 0

الاعتماديات الأساسية واعتماديات التطوير

إذا ثبَّتَ حزمة npm باستخدام الأمر npm install <package-name>‎، فهذا يعني أنك ثبّتها على أساس اعتمادية dependency، حيث تُدرَج الحزمة تلقائيًا في ملف package.json ضمن قائمة dependencies بدءًا من الإصدار npm 5، إذ احتجنا سابقًا إلى تحديد الراية ‎--save يدويًا، فإذا أضفتَ الراية ‎-D أو الراية ‎--save-dev، فهذا يعني أنك تثبّتها على أساس اعتمادية تطوير، وبالتالي ستُضاف إلى قائمة devDependencies.

يُقصَد باعتماديات التطوير أنها حزم للتطوير فقط، وهي غير ضرورية في عملية الإنتاج مثل حزم الاختبار أو حزم webpack أو Babel، فإذا كتبت الأمر npm install واحتوى المجلد على ملف package.json في عملية الإنتاج، فستُثبَّت اعتماديات التطوير، حيث يفترض npm أنّ هذه عملية نشر تطوير، كما يجب ضبط الراية ‎--production من خلال الأمر npm install --production لتجنب تثبيت اعتماديات التطوير.

npx

يُعَدّ npx طريقةً رائعةً جدًا لتشغيل شيفرة نود، كما يوفِّر ميزات مفيدةً متعددةً، إذ كان متاحًا في npm بدءًا من الإصدار 5.2، الذي صدر في شهر 7 من عام 2017.

اقتباس

توضيح: إذا لم ترغب في تثبيت npm، فيمكنك تثبيت npx على أساس حزمة قائمة بذاتها.

يتيح لك npx تشغيل الشيفرة المُنشَأة باستخدام نود والمنشورة من خلال سجل npm، كما يتميز npx بالميزات التالية:

تشغيل الأوامر المحلية بسهولة

اعتاد مطورو نود على نشر معظم الأوامر القابلة للتنفيذ على أساس حزم عامة لتكون هذه الأوامر في المسار الصحيح وقابلةً للتنفيذ مباشرةً، إذ كان هذا أمرًا صعبًا جدًا، لأن تثبيت إصدارات مختلفة من الأمر نفسه غير ممكن، كما يؤدي تشغيل الأمر npx commandname تلقائيًا إلى العثور على مرجع الأمر الصحيح ضمن مجلد node_modules الخاص بالمشروع دون الحاجة إلى معرفة المسار الدقيق، ودون الحاجة إلى تثبيت الحزمة على أنها حزمة عامة وفي مسار المستخدِم.

تنفيذ الأوامر دون تثبيتها

هناك ميزة أخرى رائعة في npm تسمح بتشغيل الأوامر دون تثبيتها أولًا، حيث يُعَدّ ذلك مفيدًا جدًا للأسباب التالية:

  1. لا تحتاج إلى تثبيت أي شيء.
  2. يمكنك تشغيل إصدارات مختلفة من الأمر نفسه باستخدام صيغة ‎.@version

يمكن توضيح استخدام npx من خلال الأمر cowsay الذي سيطبع بقرةً تقول ما تكتبه ضمن الأمر، حيث سيطبع الأمر cowsay "Hello"‎ ما يلي على سبيل المثال:

_______
< Hello >
-------
        \ ^__^
        \ (oo)\_______
          (__)\       )\/\
              ||----w |
              ||     ||

يحدث ذلك إذا كان الأمر cowsay مثبَّتًا تثبيتًا عامًا من npm سابقًا، وإلا فستحصل على خطأ عند محاولة تشغيل الأمر، كما يسمح لك npx بتشغيل الأمر npm السابق دون تثبيته محليًا كما يلي:

npx cowsay "Hello"

يُعَدّ الأمر السابق للتسلية فقط ودون فائدة، ولكن يمكنك استخدام npx في حالات مهمة أخرى مثل:

  • تشغيل أداة واجهة سطر الأوامر vue لإنشاء تطبيقات جديدة وتشغيلها باستخدام الأمر npx vue create myvue-app
  • إنشاء تطبيق React جديد باستخدام الأمر npx create-react-app my-react-app.

و حالات أخرى أيضًا، كما ستُمسَح الشيفرة المُنزَّلة لهذه الأوامر بمجرد تنزيلها.

تشغيل شيفرة باستخدام إصدار نود Node مختلف

استخدم الرمز @ لتحديد الإصدار، وادمج ذلك مع حزمة npm التي هي node:

npx node@6 -v #v6.14.3
npx node@8 -v #v8.11.3

يساعد ذلك في تجنب استخدام أدوات مثل أداة nvm أو أدوات إدارة إصدارات نود الأخرى.

تشغيل أجزاء شيفرة عشوائية مباشرة من عنوان URL

لا يقيّدك npx بالحزم المنشورة في سجل npm، إذ يمكنك تشغيل الشيفرة الموجودة في GitHub gist مثل المثال التالي:

npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32

يجب أن تكون حذرًا عند تشغيل شيفرة لا تتحكم بها، فالقوة العظمى تستوجب مسؤولية عظمى أيضًا.

ترجمة -وبتصرّف- للفصل Node modules and npm من كتاب The Node.js handbook لصاحبه Flavio Copes.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...