如何在node_modules中使用本地安装的软件包?

时间:2012-03-13 07:31:06

标签: node.js coffeescript npm node-modules

如何在node.js中使用本地版本的模块。例如,在我的应用程序中,我安装了coffee-script:

npm install coffee-script

将其安装在./node_modules中,咖啡命令位于./node_modules/.bin/coffee。当我在项目的主文件夹中时,有没有办法运行此命令?我想我在捆绑器中寻找类似于bundle exec的东西。基本上,我想指定一个咖啡脚本版本,每个参与项目的人都应该使用。

我知道我可以添加-g标志来全局安装它,这样咖啡在任何地方都可以正常工作,但如果我想在每个项目中使用不同版本的咖啡呢?

24 个答案:

答案 0 :(得分:490)

更新:正如Seyeong Jeong在下面的回答中指出的那样,自从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

答案 1 :(得分:316)

Nice example

你不必再操纵$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

答案 2 :(得分:86)

使用npm bin命令获取项目的node modules / bin目录

$ $(npm bin)/<binary-name> [args]

e.g。

$ $(npm bin)/bower install

答案 3 :(得分:73)

使用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 install有一个--add-script选项,或者如果npm run可以在不添加脚本块的情况下运行,那就太好了。

答案 4 :(得分:42)

使用npm-run

自述文件:

NPM-运行

查找&amp;从node_modules

运行本地可执行文件

npm-run可以使用npm生命周期脚本可用的任何可执行文件。

用法

$ npm install mocha # mocha installed in ./node_modules
$ npm-run mocha test/* # uses locally installed mocha executable 

安装

$ npm install -g npm-run

答案 5 :(得分:40)

更新:我不再推荐这种方法,既出于上述安全原因,也不再推荐使用较新的npm bin命令。原答案如下:

如您所知,任何本地安装的二进制文件都在./node_modules/.bin中。为了始终在此目录中运行二进制文件而不是全局可用的二进制文件(如果存在),我建议您先将./node_modules/.bin放在路径中:

export PATH="./node_modules/.bin:$PATH"

如果您将其放在~/.profile中,coffee将始终为./node_modules/.bin/coffee(如果可用),否则为/usr/local/bin/coffee(或者您正在安装节点模块的任何前缀)。< / p>

答案 6 :(得分:22)

PATH解决方案存在的问题是,如果将$(npm bin)放在.profile / .bashrc / etc中,它将被评估一次并永远设置为首先评估路径的目录。如果相反,则修改当前路径然后每次运行脚本时,您的路径都会增长。

为了解决这些问题,我创建了一个函数并使用了它。它不会修改您的环境并且易于使用:

function npm-exec {
   $(npm bin)/$@  
}

然后可以像这样使用它而不对您的环境进行任何更改:

npm-exec r.js <args>

答案 7 :(得分:18)

如果你想保持npm,那么npx应该做你需要的。

如果转换为纱线(由facebook替换为npm)是您的选择,那么您可以致电:

 yarn yourCmd
package.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 tscnpm run tsc

 yarn tsc
 yarn tsc v0.27.5
 $ tsc

答案 8 :(得分:5)

如果您希望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-modenode-mode-off,在终端内启用和停用它。

答案 9 :(得分:5)

我一直使用与@guneysus相同的方法来解决此问题,该方法是在package.json文件中创建一个脚本,并使用它运行npm run script-name。

但是,最近几个月我一直在使用npx,我喜欢它。

例如,我下载了一个Angular项目,但不想在全球安装Angular CLI。因此,在安装了npx的情况下,不要像这样使用全局的角度cli命令(如果已安装):

ng serve

我可以从控制台执行此操作:

npx ng serve

Here's an article我写了关于NPX的文章,并且内容更深。

答案 10 :(得分:5)

我更喜欢不依赖shell别名或其他包。

df1.a.map(df2.groupby('b').c.apply(list)) Out[205]: 0 [5, 6] 1 NaN 2 NaN Name: a, dtype: object 的{​​{1}}部分添加一个简单的行,您可以运行本地npm命令,如

scripts

<强>的package.json

package.json

答案 11 :(得分:3)

TL;DR:将 npm execnpm@>=7 一起使用。


在其他答案中提到的 npx 命令已在 npm@7 中完全重写,它默认随 node@15 一起提供并且可以安装在 node@>=10 上。该实现现在等同于新引入的 npm exec 命令,它与之前的 npx 命令实现类似但不等于。

一个区别是例如它总是以交互方式询问是否应在尚未安装的情况下下载依赖项(也可以使用参数 --yes--no 覆盖)。

这是 npm exec 的示例。双破折号 (--) 将 npm exec 参数与实际命令参数分开:

npm exec --no -- jest --coverage

另见updated, official documentation to npm exec

答案 12 :(得分:2)

相同的@regular已接受的解决方案,但鱼壳味道

if not contains (npm bin) $PATH
    set PATH (npm bin) $PATH
end

答案 13 :(得分:2)

zxc就像nodejs的“bundle exec”。它类似于使用PATH=$(npm bin):$PATH

$ npm install -g zxc
$ npm install gulp
$ zxc which gulp
/home/nathan/code/project1/node_modules/.bin/gulp

答案 14 :(得分:2)

对于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> ...

例如

要执行安装在本地node_modules目录中的wdio,请执行:

npm-exec wdio wdio.conf.js

即。它将运行.\node_modules\.bin\wdio wdio.conf.js

答案 15 :(得分:1)

我是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

祝你好运。

答案 16 :(得分:1)

如果您使用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用户,则可以通过利用bash&#39; $@来获取@ Bob9630答案,这在fishshell中不可用。

答案 17 :(得分:1)

对于Windows,请使用:

/* cmd into "node_modules" folder */
"%CD%\.bin\grunt" --version

答案 18 :(得分:1)

我遇到了同样的问题而且我并不特别喜欢使用别名(如regular建议的那样),如果你也不喜欢它们,那么这是我使用的另一种解决方法,你首先必须创建一个微小的可执行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

如果你在package.json中使用scripts,那么:

...,
scripts: {
    'start': './setenv.sh <command>'
}

答案 19 :(得分:1)

将此脚本添加到.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;

note :此脚本生成cd命令的别名,每次调用cd后,它会检查node_modules/.bin并将其添加到$PATH }。

note2 :您可以将第三行更改为NODE_MODULES=$(npm bin);。但这会使cd命令太慢。

答案 20 :(得分:1)

您也可以使用direnv并仅在工作文件夹中更改$ PATH变量。

$ cat .envrc
> export PATH=$(npm bin):$PATH

答案 21 :(得分:1)

我很想知道这是不是一个不安全/坏主意,但在考虑一下之后我不会在这里看到问题:

修改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"

答案 22 :(得分:0)

我提出了一个我开发的新解决方案 (05/2021)

您可以使用 lpx https://www.npmjs.com/package/lpx

  • 运行在本地 node_modules/.bin 文件夹中找到的二进制文件
  • 从工作区中的任何位置运行在工作区根目录的 node_modules/.bin 中找到的二进制文件

如果在本地找不到二进制文件(即不像 npx),lpx 不会下载任何包

示例: lpx tsc -b -w 将使用本地打字稿包运行 tsc -b -w

答案 23 :(得分:-9)

在package.json中包含coffee-script以及每个项目所需的特定版本,通常如下:

"dependencies":{
  "coffee-script": ">= 1.2.0"

然后运行npm install以在每个项目中安装依赖项。这将安装指定版本的coffee-script,该脚本可在本地访问每个项目。