Как использовать пакет, установленный локально в node_modules? - PullRequest
415 голосов
/ 13 марта 2012

Как использовать локальную версию модуля в node.js. Например, в моем приложении я установил coffee-script:

npm install coffee-script

Это устанавливает его в ./node_modules, а команда coffee находится в ./node_modules/.bin/coffee. Есть ли способ выполнить эту команду, когда я нахожусь в главной папке моего проекта? Я думаю, я ищу что-то похожее на bundle exec в bundler. По сути, я бы хотел указать версию кофе-скрипта, которую должны использовать все участники проекта.

Я знаю, что могу добавить флаг -g, чтобы установить его глобально, чтобы кофе работал везде, но что, если бы я хотел иметь разные версии кофе для проекта?

Ответы [ 22 ]

5 голосов
/ 31 августа 2018

Я всегда использовал тот же подход, что и @guneysus, чтобы решить эту проблему: создать скрипт в файле package.json и использовать его, запустив npm run script-name.

Однако вВ последние месяцы я использовал npx , и мне это нравится.

Например, я скачал проект Angular и не хотел устанавливать Angular CLI глобально.Итак, с установленным npx вместо использования глобальной угловой команды cli (если я ее установил), например:

ng serve

Я могу сделать это из консоли:

npx ng serve

Вот статья Я написал о NPX, и это еще глубже.

2 голосов
/ 19 января 2016

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
2 голосов
/ 08 сентября 2015

То же самое принятое решение @regular, но вкус рыбных раковин

if not contains (npm bin) $PATH
    set PATH (npm bin) $PATH
end
2 голосов
/ 04 августа 2016

обновление: если вы используете npm (версия> 5.2)

Вы можете использовать:

npx <command>

npx ищет команду в каталоге .bin, если вашnode_modules

старый ответ:

Для 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,do:

npm-exec wdio wdio.conf.js

т.е. он будет работать .\node_modules\.bin\wdio wdio.conf.js

1 голос
/ 15 июля 2016

Я бы хотел знать, является ли это небезопасной / плохой идеей, но, подумав немного, я не вижу здесь проблемы:

Изменение небезопасного решения Линуса, чтобы добавить его в конециспользуя 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"
1 голос
/ 31 декабря 2014

Я столкнулся с той же проблемой, и мне не очень нравится использовать псевдонимы (как рекомендовано normal ), и если они вам не нравятся, то вот еще один обходной путь, который я использую, сначала вы нужно создать крошечный исполняемый скрипт 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>'
}
1 голос
/ 16 ноября 2016

Вы также можете использовать direnv и изменять переменную $ PATH только в вашей рабочей папке.

$ cat .envrc
> export PATH=$(npm bin):$PATH
1 голос
/ 19 мая 2017

Если вы используете 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.

1 голос
/ 02 февраля 2017

Для Windows используйте это:

/* cmd into "node_modules" folder */
"%CD%\.bin\grunt" --version
1 голос
/ 26 января 2017

Я 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

Удачи.

...