Как использовать пакет, установленный локально в узловых модулях?
как использовать локальную версию модуля в node.js. Например, в моем приложении я установил coffee-script:
npm install coffee-script
это устанавливает его в ./node_modules и команда кофе находится в ./node_modules/.bin/coffee. Есть ли способ запустить эту команду, когда я нахожусь в главной папке моего проекта? Я думаю, что я ищу что-то похожее на bundle exec в упаковщик. В принципе, я хотел бы указать версию coffee-script, которую должны использовать все участники проекта.
Я знаю, что могу добавить -g флаг, чтобы установить его глобально, так что кофе отлично работает в любом месте, но что делать, если я хотел бы иметь разные версии кофе для каждого проекта?
22 ответа:
проблема с вводом
./node_modules/.binв ваш путь входит то, что он работает только тогда, когда ваш текущий рабочий каталог является корнем вашей структуры каталогов проекта (т. е. расположение
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, или в локальных двоичных файлах проекта, и выполните это.вызов
npx <command>, когда<command>уже нет$PATHавтоматически установит пакет с этим именем из реестра NPM для вас и вызовет его. Когда это будет сделано, установленный пакет не будет нигде в ваших глобалах, поэтому вам не придется беспокоиться о загрязнении в долгосрочной перспективе. Вы можете предотвратить такое поведение, предоставив .на
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 на локальный
использовать
npm-run.из readme:
npm-run
найти и запустить локальные исполняемые файлы из папки 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) помещается в ваш .профиль./bashrc / etc он оценивается один раз и навсегда устанавливается в любой каталог, в котором был впервые оценен путь. Если вместо этого вы измените текущий путь, то каждый раз, когда вы запускаете скрипт, ваш путь будет расти.
чтобы обойти эти проблемы, я создаю функцию и использовал это. Он не изменяет вашу среду и прост в использовании:
function npm-exec { $(npm bin)/$@ }Это может быть использовано, как это без внесение любых изменений в вашу среду:
npm-exec r.js <args>
если вы хотите сохранить НПМ, затем npx должны делать то, что вам нужно.
если переключение на yarn (замена npm на facebook) является вариантом для вас, то вы можете позвонить:
yarn yourCmdскрипты внутри упаковки.json будет иметь приоритет, если он не найден, он будет искать внутри .
он также выводит то, что он побежал:
$ 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
если вы хотите, чтобы ваша переменная пути правильно обновлялась на основе вашего текущего рабочего каталога, добавьте это в конец вашего
.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, соответственно.
Я предпочитаю не полагаться на псевдонимы оболочки или другой пакет.
добавление простой строки в вашего
package.json, вы можете запускать локальные команды npm, такие как
npm run webpack.json
{ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack" }, "devDependencies": { "webpack": "^4.1.1", "webpack-cli": "^2.0.11" } }
zxc похоже на" bundle exec " для nodejs. Это похоже на использование
PATH=$(npm bin):$PATH:$ npm install -g zxc $ npm install gulp $ zxc which gulp /home/nathan/code/project1/node_modules/.bin/gulp
такое же @регулярн принятое решение, но вкус раковины Рыб
if not contains (npm bin) $PATH set PATH (npm bin) $PATH end
Для Windows
хранить в файле с именем
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установленный в локальном каталоге node_modules, выполните:npm-exec wdio wdio.conf.jsт. е. он будет работать
.\node_modules\.bin\wdio wdio.conf.js
вы также можете использовать 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он проверяетnode_modules/.binи добавить его в свой$PATH.примечание2: вы можете изменить третью строку с
NODE_MODULES=$(npm bin);. Но что бы сделатьcdкоманда слишком медленная.
я столкнулся с той же проблемой и мне не особо нравится использовать псевдонимы (как обычныйпредлагается), и если вам они тоже не нравятся, то вот еще один обходной путь, который я использую, вам сначала нужно создать крошечный исполняемый скрипт 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в пакет.json тогда:..., scripts: { 'start': './setenv.sh <command>' }
Я хотел бы знать, если это небезопасно/плохая идея, но подумав немного, я не вижу здесь проблемы:
изменение небезопасного решения Линуса, чтобы добавить его в конец, используя
npm binчтобы найти каталог, и сделать скрипт только вызовnpm binкогда apackage.jsonприсутствует в родительской (для скорости), это то, что я придумал дляzsh:find-up () { path=$(pwd) while [[ "$path" != "" && ! -e "$path/" ]]; 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's$@, который не доступен вfishshell.
Я всегда использовал тот же подход, что и @guneysus для решения этой проблемы, которая заключается в создании скрипта в пакете.JSON-файл и использовать его под управлением npm run script-name.
однако, в последние месяцы я использую npx и мне это нравится.
например, я загрузил угловой проект, и я не хотел устанавливать угловой CLI глобально. Итак, с установленным npx вместо использования команды global angular cli (если бы я ее установил), например это:
ng serveЯ могу сделать это из консоли:
npx ng serve
включить кофе-скрипт в пакет.json с конкретной версией, необходимой в каждом проекте, как правило, так:
"dependencies":{ "coffee-script": ">= 1.2.0"затем запустите npm install для установки зависимостей в каждом проекте. Это позволит установить указанную версию coffee-script, которая будет доступна локально для каждого проекта.
