Node.jsのnpmパッケージにはコマンドが入ってるものが数多くあります。
webpack, yarn, nodemon ...。あまりにも多いのでこの辺で割愛。
ただこれらは環境変数など使って工夫しないとコマンド入力はフルパスが必要。
それを解消するのがnpx。ただ npm run に代わって使うものじゃない。
script実行コマンド、npm run とnpx のちがい
Node.jsは、パッケージコマンドのほかにオリジナルのコマンドが作れます。スクリプトといいます。
定義はpackage.jsonで行い、パッケージコマンドや既存のスクリプトを一気に複数実行する、まとめスクリプトを作ることも可能。
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"external-css": "python css-minify-v2-honban.py",
"cleanup": "python cleanup.py",
"build": "webpack --mode=production --profile --progress=profile & yarn external-css & yarn cleanup",
"dev": "webpack --mode=development & yarn external-css & yarn cleanup",
"watch": "npx nodemon --ext scss,js,html --watch src --exec yarn build"
},
}
スクリプトの中身はコマンド実行なので、pythonやbashなどnpm以外のコマンドでもOK。
そのスクリプトを実行するコマンドが npm run です。
npm run build
そしてこの処理は、npxを使ってもできる。
npx yarn build
'yarn' コマンドが付いているのが気になるますね?
ここがnpxコマンドの本質です。npxの説明を抜粋します。
Run a command from a local or remote npm package
(ローカルまたはリモートのnpmパッケージからコマンドを実行する)
筆者和訳
(この説明は npx --help で見れる)
npxは npm run の代替として語られますが、説明を見れば全くの別物だと言えます。
ローカルパッケージのコマンドを実行する
npxコマンドは説明の通り、ローカルのnpmパッケージにあるコマンドを実行するためのものです。
npx yarn build
もしnpxを使わないければ、このようにしないといけません。
./node_modules/yarn/bin/yarn build
コマンドは 'yarn build' のように使いたいですよね?
それをするためには、OSの環境変数で yarnコマンドのPATHを通すか、yarnパッケージをNode.jsのグローバル環境でインストールしなければなりません。
ただ、npmパッケージのグローバルインストール先は、npmのインストール場所(/usr/local/lib。Windowsならユーザ\AppData\Roaming\npm)になるし、その作業は意外と面倒。
最初に言ったように、npmパッケージにはコマンドが内包されてるものがいくらでもあるから。
globalにインストールしたnpmパッケージのコマンドは、package.jsonがあってnpmコマンドが使える場所では、コマンドのフルパスが不要になる。
まるでOSの環境変数のPATHを通したかのように。
(npmコマンドはローカルインストールでも可。)
ただ、ソースプロジェクトの外にインストールしGitHubなどリポジトリへ登録できないので、環境をすべて共有できない。
ローカルに置いたままコマンドを実行するニーズは高い
環境変数に追加するとかディレクトリがソースのプロジェクト以外にあるのは不便です。
今のプログラムはGitHubなどのリポジトリへ、ソースだけでなく付随する開発ツールなども置くから。
npmパッケージのwebpackコマンドなんかは代表的な例。
ローカルのpackage.jsonにはグローバルインストール設定はないので、別途インストールするの面倒だし、環境が分散されて移行しにくくなるのもいただけない。
環境変数に登録する必要もなく、コマンドをフルパスで入力しなくても済むように用意されたのがnpxコマンドです。
安易に環境変数に追加とか愚の骨頂。
それはOSの環境であってNode.jsを使った環境ではない。
リモートで実行できるということ?
Run a command from a local or remote npm package
(ローカルまたはリモートのnpmパッケージからコマンドを実行する)
筆者和訳
改めて説明を見て気づいたのが、別サーバーにあるものをリモートで実行できるらしいです。
ただこの使い方はあまりしないので説明は割愛。
セキュリティ的にも問題あるし。
使うことはないとは思いません。きちんとセキュリティに配慮して使う場面はあります。
その機会は稀というだけで。