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

npm install coffee-script

这会将其安装在。/node_modules中,而coffee命令则安装在。/node_modules/.bin/coffee中。当我在项目的主文件夹中时,是否有一种方法可以运行此命令?我想我在寻找类似于捆绑执行者的东西。基本上,我想指定一个参与项目的每个人都应该使用的coffee-script版本。

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


当前回答

TL;DR:使用npm exec与npm@>=7。


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

一个不同之处在于,当一个依赖项还没有安装时,它总是交互式地询问是否应该下载它(也可以用参数——yes或——no来覆盖)。

这里有一个npm exec的例子。双破折号(——)将npm exec参数与实际的命令参数分开:

npm exec --no -- jest --coverage

请参见更新后的npm exec官方文档。

其他回答

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

向包的脚本部分添加简单的一行。Json,你可以运行本地NPM命令像

pm网络包装

package.json

{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "webpack": "webpack"
  },
  "devDependencies": {
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.11"
  }
}

使用npm bin命令获取项目的节点模块/bin目录

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

e.g.

$ $(npm bin)/bower install

如果你想让你的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相同的方法来解决这个问题,即在包中创建一个脚本。Json文件,并使用它运行NPM run script-name。

然而,最近几个月我一直在使用npx,我很喜欢它。

例如,我下载了一个Angular项目,但我不想全局安装Angular CLI。所以,在安装了npx之后,不用使用angular cli的全局命令(如果我已经安装了它),就像这样:

ng serve

我可以从控制台这样做:

npx ng serve

这是我写的一篇关于NPX的文章,更深入地讨论了它。

我很想知道这是否是一个不安全的/坏主意,但在思考了一会儿之后,我不认为这是一个问题:

修改Linus的不安全解决方案,将其添加到末尾,使用npm bin查找目录,并使脚本只在包时调用npm bin。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"