web-dev-qa-db-ja.com

Node_modulesにローカルにインストールされたパッケージの使い方

node.jsでモジュールのローカルバージョンを使用するにはどうすればいいですか。例えば、私のアプリでは、私はcoffee-scriptをインストールしました:

npm install coffee-script

これはそれを./node_modulesにインストールし、coffeeコマンドは./node_modules/.bin/coffeeにあります。プロジェクトのメインフォルダにいるときにこのコマンドを実行する方法はありますか?私はbundlerでbundle execに似たものを探していると思います。基本的に、私はプロジェクトに関わるすべての人が使うべきコーヒースクリプトのバージョンを指定したいと思います。

-gフラグを追加して世界中にインストールできるので、どこでも問題なく動作しますが、プロジェクトごとに異なるバージョンのコーヒーを使用する場合はどうすればよいですか。

402
typeoneerror

_ update _ :Seyeong Jeongが以下の答えで指摘しているように、npm 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
488
regular

Nice example

もう$PATHを操作する必要はありません。

[email protected] npm には、ローカルのnode_modules/.binまたは中央キャッシュからコマンドを実行できるnpxパッケージが同梱されています。

単に実行します。

$ 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
311
Seyeong Jeong

プロジェクトのnode modules/binディレクトリを取得するには、npm binコマンドを使用します。

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

例えば.

$ $(npm bin)/bower install
86
jassa

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が機能するのであれば、いいでしょう。

74
jla

npm-run を使用してください。

Readmeから:

npm実行

Node_modulesからローカル実行ファイルを検索して実行する

Npmライフサイクルスクリプトで利用可能なすべての実行可能ファイルはnpm-runで利用可能です。

使用法

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

Installation

$ npm install -g npm-run
43
mightyiam

更新: /上記のセキュリティ上の理由から、このメソッドは推奨されなくなりました。少なくとも新しいnpm binコマンドは対象外です。下のオリジナルの答え:

ご存じのとおり、ローカルにインストールされたバイナリは./node_modules/.binにあります。グローバルに利用可能なバイナリではなく、常にこのディレクトリでバイナリを実行するために、私はあなたのパスの最初に./node_modules/.binを置くことを勧めます:

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

これをあなたの~/.profileに入れると、利用可能ならばcoffeeは常に./node_modules/.bin/coffeeになります。そうでなければ/usr/local/bin/coffee(またはノードモジュールをインストールするプレフィックス)になります。

PATHソリューションでは、$(npm bin)が.profile/.bashrc/etcに配置されている場合は1回評価され、パスが最初に評価されたディレクトリに永久に設定されるという問題があります。あなたがスクリプトを実行するたびにあなたの道は伸びるでしょう。

これらの問題を回避するために、関数を作成してそれを使用しました。それはあなたの環境を変更することはなく、使い方も簡単です。

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

これはあなたの環境に何の変更も加えることなくこのように使うことができます。

npm-exec r.js <args>
23
Bob9630

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 tscyarn run tscまたはnpm run tscと同等です。

 yarn tsc
 yarn tsc v0.27.5
 $ tsc
19
k0pernikus

現在の作業ディレクトリに基づいて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 Promptがレンダリングされるたびに(プロジェクトのサイズによりますが)ほとんどの場合、少しの遅れがあるため、デフォルトでは無効になっています。

あなたはnode-modenode-mode-offをそれぞれ実行することによってあなたの端末内でそれを有効にしたり無効にしたりすることができます。

6
namuol

私はシェルエイリアスや他のパッケージに頼らないことを好みます。

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" } }

6
guneysus

私はいつも@guneysusと同じアプローチを使ってこの問題を解決しました。それはpackage.jsonファイルにスクリプトを作成し、それをnpm run script-nameを実行して使用することです。

しかし、ここ数カ月の間に npx を使っていて、それが大好きです。

たとえば、Angularプロジェクトをダウンロードしましたが、Angular CLIをグローバルにインストールしたくありませんでした。だから、次のように(私がインストールしていれば)global angular cliコマンドを使う代わりに、npxをインストールした状態で、

ng serve

私はコンソールからこれを行うことができます:

npx ng serve

ここに記事があります 私はNPXについて書いた、そしてそれはそれにもっと深く入ります。

5
Jair Reina

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
3
Nathan

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を実行します

3
Dheeraj Bhaskar

同じ@標準の解決策が、フィッシュシェルの風味

if not contains (npm bin) $PATH
    set PATH (npm bin) $PATH
end
3
Pioneer Skies

このスクリプトをあなたの.bashrcに追加してください。それからあなたはcoffeeまたはanyhtingをローカルで呼び出すことができます。これはあなたのラップトップには便利ですが、あなたのサーバーには使わないでください。

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 :3行目をNODE_MODULES=$(npm bin);に変更できます。しかし、それはcdコマンドを遅くしすぎます。

2

Windowsの場合はこれを使用します。

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

Direnvを使用して作業フォルダ内の$ PATH変数のみを変更することもできます。

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

これが安全でない/悪い考えであるかどうかを知りたいのですが、それについて少し考えた後、私はここで問題を見ません:

npm binを使用してディレクトリを検索し、親にnpm binが存在する場合にのみpackage.jsonを呼び出すスクリプトを作成するように、Linusの安全でないソリューションを変更して最後に追加します。これは私が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
osdiab

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
Leon li

私は同じ問題に遭遇し、私は特に( 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>'
}
1
nkh

私は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

がんばろう。

1
Akash