首页 文章

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

提问于
浏览
364

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

npm install coffee-script

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

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

22 回答

  • 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的 $@ 来获取@ Bob9630的答案,这在 fishshell 中不可用 .

  • 72

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

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

    例如,我下载了一个Angular项目,我不想全局安装Angular CLI . 因此,安装了npx,而不是使用全局角度cli命令(如果我已安装它),如下所示:

    ng serve
    

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

    npx ng serve
    
  • 258

    对于Windows使用此:

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

    如果您希望PATH变量根据当前工作目录正确更新,请将其添加到 .bashrc -equivalent的末尾(或者在定义 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 在终端中启用和禁用它 .

  • -8

    适用于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> ... 一样使用它

    For example

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

    npm-exec wdio wdio.conf.js
    

    即它会运行 .\node_modules\.bin\wdio wdio.conf.js

  • 3

    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
    
  • 461

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

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

    将此脚本添加到 .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 命令太慢 .

  • 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
    

    祝好运 .

  • 2

    UPDATE :正如Seyeong Jeong在下面的回答中指出的那样,从5.2pm开始,你可以使用 npx [command] ,这样更方便 .

    OLD ANSWER for versions before 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
    
  • 2

    我遇到了同样的问题而且我并不特别喜欢使用别名(因为regular 's suggested), and if you don't也喜欢它们,然后这是我使用的另一种解决方法,你首先必须创建一个微小的可执行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>'
    }
    
  • 6

    使用npm-run .

    从自述文件:

    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
    
  • 4

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

    package.jsonscripts 部分添加一个简单的行,您可以运行本地的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" } }

  • 39

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

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

    你不必再操纵 $PATH 了!

    npm@5.2.0npm 附带 npx 程序包,它允许您从本地 node_modules/.bin 或中央缓存运行命令 .

    只需运行:

    $ npx [options] <command>[@version] [command-arg]...
    

    通过默认情况下, npx 将检查 $PATH 中是否存在 <command> ,或者是否存在于本地项目二进制文件中,并执行该操作 .

    $PATH 中的 <command> 尚未在您的 $PATH 中时调用 npx <command> 将自动从NPM注册表中为您安装具有该名称的包,并调用它 . 完成后,安装的软件包将不会出现在全局文件中的任何位置,因此您不必长期担心污染问题 . 您可以通过提供 --no-install 选项来阻止此行为 .

    对于 npm < 5.2.0 ,您可以通过运行以下命令手动安装 npx 包:

    $ npm install -g npx
    
  • 23

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

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

    例如

    $ $(npm bin)/bower install
    
  • 18

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

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

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

  • 1

    如果你想保持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 中的每个命令设置脚本 .


    如果您在 package.json 内的 .scripts 处定义了脚本:

    "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
    
  • 84

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

    修改Linus的不安全解决方案将其添加到最后,使用 npm bin 查找目录,并使脚本仅在父级中存在 package.json 时调用 npm bin (速度),这就是我为 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"
    
  • 3

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

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

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

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

    npm-exec r.js <args>
    
  • 2

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

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

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

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

  • 6

    使用 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可以在不添加脚本块的情况下工作,那就太好了 .

相关问题