npm link
: 未公開パッケージのグローバルインストールnpm link
: グローバルにリンクされたパッケージのローカルインストールnpm link
: リンクの解除npx
: npmパッケージのbinスクリプトをインストールせずに実行package.json
のプロパティ"bin"
を使用すると、npmパッケージが提供するシェルスクリプトを指定できます(詳細については、§14「クロスプラットフォームのシェルスクリプトの作成」を参照してください)。このようなパッケージをインストールすると、Node.jsは、コマンドラインからこれらのシェルスクリプト(いわゆるbinスクリプト)にアクセスできるようにします。この章では、binスクリプトを含むパッケージをインストールする2つの方法を探ります。
binスクリプトを含むパッケージをローカルにインストールするとは、パッケージ内の依存関係としてインストールすることを意味します。スクリプトは、そのパッケージ内でのみアクセスできます。
binスクリプトを含むパッケージをグローバルにインストールするとは、スクリプトがどこからでもアクセスできるように、「グローバルな場所」にインストールすることを意味します。現在のユーザーまたはシステムのすべてのユーザーのいずれか(npmの設定方法によって異なります)。
これらのすべてが何を意味するのか、インストール後にbinスクリプトを実行する方法を探ります。
パッケージcowsay
には、次のpackage.json
プロパティがあります。
"bin": {
"cowsay": "./cli.js",
"cowthink": "./cli.js"
},
このパッケージをグローバルにインストールするには、npm install -g
を使用します。
npm install -g cowsay
注意:Unixでは、sudo
を使用する必要がある場合があります(これについてはすぐに学習します)。
sudo npm install -g cowsay
その後、コマンドラインでcowsay
とcowthink
コマンドを使用できます。
binスクリプトのみがグローバルに利用可能であることに注意してください。Node.jsがnode_modules
ディレクトリでベアモジュール指定子を検索する場合、パッケージは無視されます。
npm ls -g
グローバルにインストールされているパッケージとその場所を確認できます。
% npm ls -g
/usr/local/lib
├── corepack@0.12.1
├── cowsay@1.5.0
└── npm@8.15.0
Windowsでは、インストールパスは%AppData%\npm
です。例:
>echo %AppData%\npm
C:\Users\jane\AppData\Roaming\npm
npm root -g
macOSでの結果
% npm root -g
/usr/local/lib/node_modules
Windowsでの結果
>npm root -g
C:\Users\jane\AppData\Roaming\npm\node_modules
npm bin -g
npm bin -g
は、npmがシェルスクリプトをグローバルにインストールする場所を教えてくれます。また、そのディレクトリがシェルPATHで使用可能であることを保証します。
macOSでの結果
% npm bin -g
/usr/local/bin
% which cowsay
/usr/local/bin/cowsay
Windowsコマンドシェルでの結果
>npm bin -g
C:\Users\jane\AppData\Roaming\npm
>where cowsay
C:\Users\jane\AppData\Roaming\npm\cowsay
C:\Users\jane\AppData\Roaming\npm\cowsay.cmd
ファイル名拡張子のない実行可能ファイルcowsay
は、Cygwin、MinGW、MSYSなどのUnixベースのWindows環境用です。
Windows PowerShellは、gcm cowsay
に対してこのパスを返します。
C:\Users\jane\AppData\Roaming\npm\cowsay.ps1
npmのインストールプレフィックスは、パッケージとbinスクリプトがグローバルにインストールされる場所を決定します。
これはmacOSでのインストールプレフィックスです。
% npm config get prefix
/usr/local
したがって
/usr/local/lib/node_modules
にインストールされます。/usr/local/bin
にインストールされます。これはWindowsでのインストールプレフィックスです。
>npm config get prefix
C:\Users\jane\AppData\Roaming\npm
したがって
C:\Users\jane\AppData\Roaming\npm\node_modules
にインストールされます。C:\Users\jane\AppData\Roaming\npm
にインストールされます。このセクションでは、パッケージがグローバルにインストールされる場所を変更する2つの方法を検討します。
パッケージがグローバルにインストールされる場所を変更する1つの方法は、npmインストールプレフィックスを変更することです。
Unix
mkdir ~/npm-global
npm config set prefix '~/npm-global'
Windowsコマンドシェル
mkdir "%UserProfile%\npm-global"
npm config set prefix "%UserProfile%\npm-global"
Windows PowerShell
mkdir "$env:UserProfile\npm-global"
npm config set prefix "$env:UserProfile\npm-global"
構成データは、ホームディレクトリの.npmrc
ファイルに保存されます。
今後、グローバルインストールは、指定したディレクトリに追加されます。
その後、グローバルにインストールしたbinスクリプトがシェルで見つかるように、npm bin -g
ディレクトリをシェルのPATHに追加する必要があります。
npmプレフィックスを変更するデメリット:npm自体をアップグレードするように指示すると、npmも新しい場所にインストールされるようになります。
Node.jsバージョンマネージャーを使用すると、複数のバージョンのNode.jsを同時にインストールして、切り替えることができます。一般的なものには以下が含まれます。
cowsay
のようなnpmレジストリパッケージをローカル(パッケージ内)にインストールするには、次の手順を実行します。
cd my-package/
npm install cowsay
これにより、次のデータがpackage.json
に追加されます。
"dependencies": {
"cowsay": "^1.5.0",
···
}
さらに、パッケージは次のディレクトリにダウンロードされます。
my-package/node_modules/cowsay/
Unixでは、npmはbinスクリプト用に次のシンボリックリンクを追加します。
my-package/node_modules/.bin/cowsay -> ../cowsay/cli.js
my-package/node_modules/.bin/cowthink -> ../cowsay/cli.js
Windowsでは、npmはこれらのファイルをmy-package\node_modules\.bin\
に追加します。
cowsay
cowsay.cmd
cowsay.ps1
cowthink
cowthink.cmd
cowthink.ps1
拡張子のないファイルは、Cygwin、MinGW、MSYSなどのUnixベースのWindows環境用のスクリプトです。
npm bin
は、ローカルにインストールされたbinスクリプトがある場所を教えてくれます。たとえば、
% npm bin
/Users/john/my-package/node_modules/.bin
注意:ローカルでは、パッケージは常にpackage.json
ファイルの隣のnode_modules
ディレクトリにインストールされます。後者が現在のディレクトリに存在しない場合、npmは先祖ディレクトリでそれを検索し、そこにパッケージをインストールします。npmがパッケージをローカルにインストールする場所を確認するには、npm root
コマンドを使用できます。たとえば(Unix)
% cd $HOME
% npm root
/Users/john/node_modules
ジョンのホームディレクトリにはpackage.json
はありませんが、npmは先祖ディレクトリに何もインストールできないため、npm root
はこのディレクトリを表示します。現在の場所にパッケージをローカルにインストールすると、package.json
が作成され、インストールが通常どおりに進行します。
(このサブセクションのすべてのコマンドは、ディレクトリmy-package
内で実行されます。)
シェルから次のようにcowsay
を実行できます。
./node_modules/.bin/cowsay Hello
Unixでは、ヘルパーを設定できます。
alias npm-exec='PATH=$(npm bin):$PATH'
次に、次のコマンドが機能します。
npm-exec cowsay Hello
package.json
にパッケージスクリプトを追加することもできます。
{
···
"scripts": {
"cowsay": "cowsay"
},
···
}
次に、シェルでこのコマンドを実行できます。
npm run cowsay Hello
これは、npmが一時的に次のエントリをUnixの$PATH
に追加するためです。
/Users/john/my-package/node_modules/.bin
/Users/john/node_modules/.bin
/Users/node_modules/.bin
/node_modules/.bin
Windowsでは、同様のエントリが%Path%
または$env:Path
に追加されます。
C:\Users\jane\my-package\node_modules\.bin
C:\Users\jane\node_modules\.bin
C:\Users\node_modules\.bin
C:\node_modules\.bin
次のコマンドは、パッケージスクリプトの実行中に存在する環境変数とその値を一覧表示します。
npm run env
パッケージ内で、npxを使用してbinスクリプトにアクセスできます。
npx cowsay Hello
npx cowthink Hello
npxの詳細については後述します。
まだ公開していない、または公開しないパッケージがあり、それをインストールしたい場合があります。
npm link
: 未公開パッケージのグローバルインストール/tmp/unpublished-package/
ディレクトリに保存されている、名前が@my-scope/unpublished-package
の未公開パッケージがあると仮定しましょう。次のようにして、グローバルで利用可能にすることができます。
cd /tmp/unpublished-package/
npm link
これを行うと
npmはグローバルなnode_modules
(npm root -g
によって返される)へのシンボリックリンクを追加します。たとえば、
/usr/local/lib/node_modules/@my-scope/unpublished-package
-> ../../../../../tmp/unpublished-package
Unixでは、npmはグローバルbinディレクトリ(npm bin -g
によって返される)から各binスクリプトへの1つのシンボリックリンクも追加します。そのリンクは直接的ではなく、グローバルなnode_modules
ディレクトリを経由します。
/usr/local/bin/my-command
-> ../lib/node_modules/@my-scope/unpublished-package/src/my-command.js
Windowsでは、通常の3つのスクリプト(グローバルなnode_modules
への相対パスを介してリンクされたパッケージを参照)を追加します。
C:\Users\jane\AppData\Roaming\npm\my-command
C:\Users\jane\AppData\Roaming\npm\my-command.cmd
C:\Users\jane\AppData\Roaming\npm\my-command.ps1
リンクされたパッケージが参照される方法により、変更はすぐに有効になります。変更時に再度リンクする必要はありません。
グローバルインストールが機能したかどうかを確認するには、npm ls -g
を使用して、グローバルにインストールされたすべてのパッケージを一覧表示できます。
npm link
: グローバルにリンクされたパッケージのローカルインストール未公開のパッケージをグローバルにインストールした後(前のサブセクションを参照)、パッケージ(公開または未公開のいずれでも可能)の1つにローカルにインストールするオプションがあります。
cd /tmp/other-package/
npm link @my-scope/unpublished-package
これにより、次のリンクが作成されます。
/tmp/other-package/node_modules/@my-scope/unpublished-package
-> ../../../unpublished-package
デフォルトでは、未公開パッケージはpackage.json
の依存関係として追加されません。その背後にある理由は、npm link
がレジストリパッケージの未公開バージョンを一時的に操作するために使用されることが多く、依存関係に表示されるべきではないということです。
npm link
: リンクの解除ローカルリンクの解除
cd /tmp/other-package/
npm uninstall @my-scope/unpublished-package
グローバルリンクの解除
cd /tmp/unpublished-package/
npm uninstall -g
未公開パッケージをローカルにインストールする別の方法は、npm install
を使用し、パッケージ名ではなくローカルパスを介して参照することです。
cd /tmp/other-package/
npm install ../unpublished-package
これには2つの効果があります。
まず、次のシンボリックリンクが作成されます。
/tmp/other-package/node_modules/@my-scope/unpublished-package
-> ../../../unpublished-package
次に、依存関係がpackage.json
に追加されます。
"dependencies": {
"@my-scope/unpublished-package": "file:../unpublished-package",
···
}
この未公開パッケージのインストール方法は、グローバルでも機能します。
cd /tmp/unpublished-package/
npm install -g .
my-package/
の依存関係としてパッケージをインストールできます。それらはディレクトリmy-package/.yalc
にコピーされ、file:
またはlink:
の依存関係がpackage.json
に追加されます。relative-deps
は、package.json
の"relativeDependencies"
をサポートします。これにより(存在する場合)、通常の依存関係がオーバーライドされます。npm link
およびローカルパスインストールとは対照的です
relative-deps
は、ローカルにインストールされた相対的な依存関係と、それらのオリジナルとの同期を保つのにも役立ちます。
npx link
は、npm link
のより安全なバージョンであり、他の利点の中でも特にグローバルインストールを必要としません。npx
:npmパッケージ内のbinスクリプトをインストールせずに実行するnpxは、npmにバンドルされているbinスクリプトを実行するためのシェルコマンドです。
最も一般的な使い方は次のとおりです。
npx <package-name> arg1 arg2 ...
このコマンドは、package-name
という名前のパッケージをnpxキャッシュにインストールし、パッケージと同じ名前のbinスクリプトを実行します。例えば、
npx cowsay Hello
つまり、最初にインストールしなくてもbinスクリプトを実行できます。npxは、binスクリプトの単発の呼び出しに最も役立ちます。たとえば、多くのフレームワークは新しいプロジェクトをセットアップするためのbinスクリプトを提供しており、これらはしばしばnpxを介して実行されます。
npxがパッケージを初めて使用した後、そのパッケージはキャッシュで使用できるようになり、後続の呼び出しははるかに高速になります。ただし、パッケージがキャッシュにどれくらいの期間残るかはわかりません。したがって、npxはbinスクリプトをグローバルまたはローカルにインストールする代替手段にはなりません。
パッケージに、パッケージ名とは異なる名前のbinスクリプトが付属している場合は、次のようにアクセスできます。
npx --package=<package-name> <bin-script> arg1 arg2 ...
例えば
npx --package=cowsay cowthink Hello
npxのキャッシュはどこにありますか?
Unixでは、次のコマンドで確認できます。
npx --package=cowsay node -p \
"process.env.PATH.split(':').find(p => p.includes('_npx'))"
これにより、次のようなパスが返されます。
/Users/john/.npm/_npx/8f497369b2d6166e/node_modules/.bin
Windowsでは、次を使用できます(1行が2つに分割されています)。
npx --package=cowsay node -p
"process.env.Path.split(';').find(p => p.includes('_npx'))"
これにより、次のようなパスが返されます(単一のパスが2行に分割されています)。
C:\Users\jane\AppData\Local\npm-cache\_npx\
8f497369b2d6166e\node_modules\.bin
npxのキャッシュは、npmがインストールするモジュールに使用するキャッシュとは異なることに注意してください。
$HOME/.npm/_cacache/
$HOME/.npm/_npx/
$env:UserProfile\AppData\Local\npm-cache\_npx\
$env:UserProfile\AppData\Local\npm-cache\_cacache\
両方のキャッシュの親ディレクトリは、以下で確認できます。
npm config get cache
npmキャッシュの詳細については、npmドキュメントを参照してください。
npxキャッシュとは対照的に、データはnpmキャッシュから削除されることはなく、追加されるだけです。Unixでは、次のようにサイズを確認できます。
du -sh $(npm config get cache)/_cacache/
Windows PowerShellでは、次のようになります。
DiskUsage /d:0 "$(npm config get cache)\_cacache"