كيفية استخدام الحزمة المثبتة محليًا في Node_modules؟
-
13-12-2019 - |
سؤال
كيف يمكنني استخدام الإصدار المحلي من الوحدة النمطية في node.js
.على سبيل المثال، في تطبيقي، قمت بتثبيت Coffee-script:
npm install coffee-script
هذا تثبيته في ./node_modules
وأمر القهوة موجود ./node_modules/.bin/coffee
.هل هناك طريقة لتشغيل هذا الأمر عندما أكون في المجلد الرئيسي لمشروعي؟أعتقد أنني أبحث عن شيء مماثل ل bundle exec
في المجمع.في الأساس، أود تحديد نسخة من نص القهوة الذي يجب على جميع المشاركين في المشروع استخدامه.
أعلم أنه يمكنني إضافة -g
علم بتثبيته عالميًا حتى تعمل القهوة بشكل جيد في أي مكان، ولكن ماذا لو أردت الحصول على إصدارات مختلفة من القهوة لكل مشروع؟
المحلول
تحديث:كما يشير Seyeong Jeong في إجابته أدناه، منذ npm 5.2.0 يمكنك استخدامه npx [command]
, ، وهو أكثر ملاءمة.
الإجابة القديمة للإصدارات قبل 5.2.0:
المشكلة مع وضع
./node_modules/.bin
في PATH الخاص بك هو أنه يعمل فقط عندما يكون دليل العمل الحالي الخاص بك هو جذر بنية دليل المشروع الخاص بك (أي.موقع node_modules
)
بغض النظر عن دليل العمل الخاص بك، يمكنك الحصول على مسار الثنائيات المثبتة محليًا باستخدام
npm bin
لتنفيذ تثبيت محليا coffee
ثنائي مستقل عن مكان وجودك في التسلسل الهرمي لدليل المشروع، يمكنك استخدام بنية bash هذه
PATH=$(npm bin):$PATH coffee
لقد قمت باستبدال هذا بـ npm-exec
alias npm-exec='PATH=$(npm bin):$PATH'
لذا، الآن أستطيع
npm-exec coffee
لتشغيل النسخة الصحيحة من القهوة بغض النظر عن مكان وجودي
$ pwd
/Users/regular/project1
$ npm-exec which coffee
/Users/regular/project1/node_modules/.bin/coffee
$ cd lib/
$ npm-exec which coffee
/Users/regular/project1/node_modules/.bin/coffee
$ cd ~/project2
$ npm-exec which coffee
/Users/regular/project2/node_modules/.bin/coffee
نصائح أخرى
ليس عليك التلاعب $PATH
أي أكثر من ذلك!
من npm@5.2.0, npm السفن مع npx
الحزمة التي تتيح لك تشغيل الأوامر من ملف محلي node_modules/.bin
أو من ذاكرة التخزين المؤقت المركزية.
ببساطة قم بتشغيل:
$ npx [options] <command>[@version] [command-arg]...
بشكل افتراضي، npx
سوف تحقق ما إذا كان <command>
موجود في $PATH
, ، أو في ثنائيات المشروع المحلي، وقم بتنفيذ ذلك.
الاتصال npx <command>
متى <command>
ليس بالفعل في الخاص بك $PATH
سيقوم تلقائيًا بتثبيت حزمة بهذا الاسم من سجل NPM لك، واستدعاءها.عند الانتهاء من ذلك، لن تكون الحزمة المثبتة في أي مكان في عوالمك، لذلك لن تضطر إلى القلق بشأن التلوث على المدى الطويل.يمكنك منع هذا السلوك من خلال توفير --no-install
خيار.
ل npm < 5.2.0
, ، يمكنك التثبيت npx
الحزمة يدويًا عن طريق تشغيل الأمر التالي:
$ npm install -g npx
استخدم ال npm bin
للحصول على دليل العقدة /bin لمشروعك
$ $(npm bin)/<binary-name> [args]
على سبيل المثال
$ $(npm bin)/bower install
يستخدم npm run[-script] <script name>
بعد استخدام npm لتثبيت حزمة bin على ملفك المحلي ./node_modules
الدليل، تعديل package.json
لإضافة <script name>
مثله:
$ npm install --save learnyounode
$ edit packages.json
>>> in packages.json
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"learnyounode": "learnyounode"
},
...
$ npm run learnyounode
سيكون من الرائع أن يكون تثبيت npm يحتوي على خيار --add-script أو شيء من هذا القبيل أو إذا كان تشغيل npm سيعمل دون إضافة إلى كتلة البرامج النصية.
يستخدم npm-run
.
من التمهيدي:
تشغيل npm
ابحث عن الملفات التنفيذية المحلية وقم بتشغيلها منNode_modules
أي ملف قابل للتنفيذ متاح لبرنامج نصي لدورة حياة npm متاح لـ npm-run
.
الاستخدام
$ npm install mocha # mocha installed in ./node_modules
$ npm-run mocha test/* # uses locally installed mocha executable
تثبيت
$ npm install -g npm-run
تحديث: لم أعد أوصي بهذه الطريقة، لأسباب أمنية مذكورة وليس الأحدث npm bin
يأمر.الإجابة الأصلية أدناه:
كما اكتشفت، توجد أي ثنائيات مثبتة محليًا ./node_modules/.bin
.من أجل تشغيل الثنائيات دائمًا في هذا الدليل بدلاً من الثنائيات المتاحة عالميًا، إذا كانت موجودة، أقترح عليك وضعها ./node_modules/.bin
الأول في طريقك:
export PATH="./node_modules/.bin:$PATH"
إذا وضعت هذا في الخاص بك ~/.profile
, coffee
سوف يكون دائما ./node_modules/.bin/coffee
إذا كان متاحا، وإلا /usr/local/bin/coffee
(أو أي بادئة تقوم بتثبيت وحدات العقدة تحتها).
يواجه حل PATH مشكلة تتمثل في أنه إذا تم وضع $(npm bin) في .profile/.bashrc/etc، فسيتم تقييمه مرة واحدة ويتم تعيينه إلى الأبد على أي دليل تم تقييم المسار فيه لأول مرة.إذا قمت بدلاً من ذلك بتعديل المسار الحالي، ففي كل مرة تقوم فيها بتشغيل البرنامج النصي، سينمو المسار الخاص بك.
للتغلب على هذه المشكلات، قمت بإنشاء وظيفة واستخدمتها.لا يعدل بيئتك وهو سهل الاستخدام:
function npm-exec {
$(npm bin)/$@
}
يمكن بعد ذلك استخدام هذا على النحو التالي دون إجراء أي تغييرات على بيئتك:
npm-exec r.js <args>
إذا كنت تريد الاحتفاظ بـ npm، إذن npx يجب أن تفعل ما تحتاجه.
إذا كان التبديل إلى الغزل (استبدال npm بواسطة facebook) خيارًا متاحًا لك، فيمكنك الاتصال بـ:
yarn yourCmd
ستحظى البرامج النصية الموجودة داخل الحزمة.json بالأولوية، وإذا لم يتم العثور على أي منها، فسيتم البحث داخل الملف ./node_modules/.bin/
مجلد.
كما أنه يخرج ما تم تشغيله:
$ yarn tsc
yarn tsc v0.27.5
$ "/home/philipp/rate-pipeline/node_modules/.bin/tsc"
لذلك ليس عليك إعداد البرامج النصية لكل أمر في ملفك package.json
.
إذا كان لديك برنامج نصي محدد في .scripts
داخل الخاص بك package.json
:
"tsc": "tsc" // each command defined in the scripts will be executed from `./node_modules/.bin/` first
yarn tsc
سيكون معادلاً ل yarn run tsc
أو npm run tsc
:
yarn tsc
yarn tsc v0.27.5
$ tsc
تحديث:إذا كنت تستخدم npm الأخير (الإصدار> 5.2)
يمكنك استخدام:
npx <command>
npx
يبحث عن الأمر في .bin
الدليل إذا كان لديك node_modules
الجواب القديم:
للنوافذ
قم بتخزين ما يلي في ملف يسمى npm-exec.bat
وإضافته إلى الخاص بك %PATH%
@echo off
set cmd="npm bin"
FOR /F "tokens=*" %%i IN (' %cmd% ') DO SET modules=%%i
"%modules%"\%*
الاستخدام
ثم يمكنك استخدامه مثلnpm-exec <command> <arg0> <arg1> ...
على سبيل المثال
ينفذ wdio
المثبتة في دليل العقدة المحلية، قم بما يلي:
npm-exec wdio wdio.conf.js
أي.سيتم تشغيله .\node_modules\.bin\wdio wdio.conf.js
أفضل عدم الاعتماد على الأسماء المستعارة لـ Shell أو أي حزمة أخرى.
إضافة خط بسيط إلى scripts
قسم الخاص بك package.json
, يمكنك تشغيل أوامر npm المحلية مثل
npm run webpack
package.json
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"webpack": "webpack"
},
"devDependencies": {
"webpack": "^4.1.1",
"webpack-cli": "^2.0.11"
}
}
إذا كنت تريد تحديث متغير PATH بشكل صحيح بناءً على دليل العمل الحالي لديك، فأضف هذا إلى نهاية ملفك .bashrc
- ما يعادل (أو بعد أي شيء يحدد PATH
):
__OLD_PATH=$PATH
function updatePATHForNPM() {
export PATH=$(npm bin):$__OLD_PATH
}
function node-mode() {
PROMPT_COMMAND=updatePATHForNPM
}
function node-mode-off() {
unset PROMPT_COMMAND
PATH=$__OLD_PATH
}
# Uncomment to enable node-mode by default:
# node-mode
قد يؤدي هذا إلى إضافة تأخير قصير في كل مرة يتم فيها عرض موجه bash (حسب حجم مشروعك، على الأرجح)، لذلك يتم تعطيله افتراضيًا.
يمكنك تمكينه وتعطيله داخل جهازك عن طريق التشغيل node-mode
و node-mode-off
, ، على التوالى.
لقد استخدمت دائمًا نفس الأسلوب الذي اتبعه @guneysus لحل هذه المشكلة، وهو إنشاء برنامج نصي في ملف package.json واستخدامه في تشغيل npm run script-name.
ومع ذلك، في الأشهر الأخيرة كنت أستخدمه npx و أنا أحبه.
على سبيل المثال، قمت بتنزيل مشروع Angular ولم أرغب في تثبيت Angular CLI عالميًا.لذلك، مع تثبيت npx، بدلاً من استخدام الأمر global angular cli (إذا كنت قد قمت بتثبيته) مثل هذا:
ng serve
يمكنني القيام بذلك من وحدة التحكم:
npx ng serve
وهنا مقال لقد كتبت عن NPX وهذا يتعمق أكثر في الأمر.
zxc يشبه "حزمة exec" لـnodejs.إنه مشابه للاستخدام PATH=$(npm bin):$PATH
:
$ npm install -g zxc
$ npm install gulp
$ zxc which gulp
/home/nathan/code/project1/node_modules/.bin/gulp
نفس الحل المقبول @regular، لكن نكهة قشر السمك
if not contains (npm bin) $PATH
set PATH (npm bin) $PATH
end
يمكنك أيضًا استخدام direnv وتغيير متغير PATH $ فقط في مجلد العمل الخاص بك.
$ cat .envrc
> export PATH=$(npm bin):$PATH
أضف هذا البرنامج النصي إلى .bashrc
.ثم يمكنك الاتصال coffee
أو أي شيء محليا.وهذا مفيد لجهاز الكمبيوتر المحمول الخاص بك، ولكن لا تستخدمه على الخادم الخاص بك.
DEFAULT_PATH=$PATH;
add_local_node_modules_to_path(){
NODE_MODULES='./node_modules/.bin';
if [ -d $NODE_MODULES ]; then
PATH=$DEFAULT_PATH:$NODE_MODULES;
else
PATH=$DEFAULT_PATH;
fi
}
cd () {
builtin cd "$@";
add_local_node_modules_to_path;
}
add_local_node_modules_to_path;
ملحوظة:هذا البرنامج النصي يصنع اسمًا مستعارًا لـ cd
الأمر، وبعد كل مكالمة cd
فإنه يتحقق node_modules/.bin
وإضافته إلى الخاص بك $PATH
.
ملاحظة 2:يمكنك تغيير السطر الثالث إلى NODE_MODULES=$(npm bin);
.ولكن هذا من شأنه أن يجعل cd
الأمر بطيء جدًا.
بالنسبة لنظام التشغيل Windows استخدم هذا:
/* cmd into "node_modules" folder */
"%CD%\.bin\grunt" --version
لقد واجهت نفس المشكلة ولا أحب بشكل خاص استخدام الأسماء المستعارة (مثل عادي's المقترحة)، وإذا لم تعجبك أيضًا، فإليك حل بديل آخر أستخدمه، عليك أولاً إنشاء نص bash صغير قابل للتنفيذ، على سبيل المثال setenv.sh:
#!/bin/sh
# Add your local node_modules bin to the path
export PATH="$(npm bin):$PATH"
# execute the rest of the command
exec "$@"
وبعد ذلك يمكنك استخدام أي ملفات تنفيذية في ملفك المحلي /bin
باستخدام هذا الأمر:
./setenv.sh <command>
./setenv.sh 6to5-node server.js
./setenv.sh grunt
إذا كنت تستخدم scripts
في package.json ثم:
...,
scripts: {
'start': './setenv.sh <command>'
}
أود أن أعرف ما إذا كانت هذه فكرة سيئة/غير آمنة، ولكن بعد التفكير فيها قليلاً، لا أرى مشكلة هنا:
تعديل حل Linus غير الآمن لإضافته إلى النهاية باستخدام npm bin
للعثور على الدليل، وجعل البرنامج النصي يدعو فقط npm bin
عندما package.json
موجود في أحد الوالدين (للسرعة)، وهذا ما توصلت إليه zsh
:
find-up () {
path=$(pwd)
while [[ "$path" != "" && ! -e "$path/$1" ]]; do
path=${path%/*}
done
echo "$path"
}
precmd() {
if [ "$(find-up package.json)" != "" ]; then
new_bin=$(npm bin)
if [ "$NODE_MODULES_PATH" != "$new_bin" ]; then
export PATH=${PATH%:$NODE_MODULES_PATH}:$new_bin
export NODE_MODULES_PATH=$new_bin
fi
else
if [ "$NODE_MODULES_PATH" != "" ]; then
export PATH=${PATH%:$NODE_MODULES_PATH}
export NODE_MODULES_PATH=""
fi
fi
}
ل bash
, ، بدلاً من استخدام precmd
هوك، يمكنك استخدام $PROMPT_COMMAND
متغير (لم أختبر هذا ولكنك حصلت على الفكرة):
__add-node-to-path() {
if [ "$(find-up package.json)" != "" ]; then
new_bin=$(npm bin)
if [ "$NODE_MODULES_PATH" != "$new_bin" ]; then
export PATH=${PATH%:$NODE_MODULES_PATH}:$new_bin
export NODE_MODULES_PATH=$new_bin
fi
else
if [ "$NODE_MODULES_PATH" != "" ]; then
export PATH=${PATH%:$NODE_MODULES_PATH}
export NODE_MODULES_PATH=""
fi
fi
}
export PROMPT_COMMAND="__add-node-to-path"
أنا Windows
المستخدم وهذا ما نجح بالنسبة لي:
// First set some variable - i.e. replace is with "xo"
D:\project\root> set xo="./node_modules/.bin/"
// Next, work with it
D:\project\root> %xo%/bower install
حظ سعيد.
في حال كنت تستخدم fish shell
ولا تريد أن تضيف إلى $path
لأسباب أمنية.يمكننا إضافة الوظيفة أدناه لتشغيل الملفات التنفيذية للعقدة المحلية.
### run executables in node_module/.bin directory
function n
set -l npmbin (npm bin)
set -l argvCount (count $argv)
switch $argvCount
case 0
echo please specify the local node executable as 1st argument
case 1
# for one argument, we can eval directly
eval $npmbin/$argv
case '*'
set --local executable $argv[1]
# for 2 or more arguments we cannot append directly after the $npmbin/ since the fish will apply each array element after the the start string: $npmbin/arg1 $npmbin/arg2...
# This is just how fish interoperate array.
set --erase argv[1]
eval $npmbin/$executable $argv
end
end
الآن يمكنك تشغيل شيء مثل:
n coffee
أو المزيد من الحجج مثل:
n browser-sync --version
ملاحظة، إذا كنت bash
المستخدم ، فإن إجابات @ Bob9630 هي الطريقة التي يجب اتباعها من خلال الاستفادة من bash $@
, ، وهو غير متوفر في fishshell
.
قم بتضمين Coffee-script في package.json مع الإصدار المحدد المطلوب في كل مشروع، وعادةً ما يكون كالتالي:
"dependencies":{
"coffee-script": ">= 1.2.0"
ثم قم بتشغيل npm install لتثبيت التبعيات في كل مشروع.سيؤدي هذا إلى تثبيت الإصدار المحدد من برنامج Coffee-Script والذي سيكون متاحًا محليًا لكل مشروع.