package.json の scripts プロパティでスクリプトを定義しておくと、任意のコマンドを npm run コマンド経由で実行できるようになります(以降 NPM スクリプトと呼びます)。
しかし、デフォルトでは、複数の NPM スクリプトを連続して実行する方法(Linux の cmd1 && cmd1)や、並列に実行する方法(Linux の cmd1 & cmd2)は提供されていません。
強引に各 OS のシェルの && や & を組み合わせることでできないことはありませんが、Windows と Linux で記述方法が異なるので、OS に依存した package.json になってしまいます。
このような場合に、npm-run-all という NPM パッケージを使用すると、複数の NPM スクリプトを逐次/並列実行するスクリプトを、OS に依存しない形で記述できるようになります。
npm-run-all は下記のようにインストールします。
$ npm install --save-dev npm-run-all
npm-run-all コマンドは、package.json の scripts 定義の中から呼び出して使用するので、上記のように --save-dev オプションを指定して、devDependencies の依存情報に追加するようにしましょう。
run-s (npm-run-all のショートカット)というコマンドを使用すると、指定した NPM スクリプトをシーケンシャルに(ひとつずつ順番に)実行していくことができます。
"scripts": {
"hello": "run-s hello:foo hello:bar",
"hello:foo": "echo FOO",
"hello:bar": "echo BAR"
},
上記の hello スクリプトを実行すると、hello:foo と hello:bar のスクリプトが順番に実行されます。
$ npm run -s hello
FOO
BAR
ちなみに、上記のように : を使ってスクリプト名を細分化しておくと、グロブでスクリプトをまとめて指定することができます。
"scripts": {
"hello": "run-p hello:*",
run-p (npm-run-all --parallel のショートカット)というコマンドを使用すると、指定した NPM スクリプトを並列に実行することができます。
"scripts": {
"hello": "run-p hello:*",
"hello:foo": "timeout /t 3 > nul & echo FOO",
"hello:bar": "timeout /t 3 > nul & echo BAR"
},
このサンプルは、Windows の timeout コマンド(指定した秒数だけスリープ)を使用しているのであまりよくない例ですが、run-p の効果を確かめるにはこのようなスリープ&エコーが手っ取り早いです。
下記のように実行すると、hello:foo と hello:bar スクリプトのスリープが同時に開始されるので、FOO と BAR の出力がほぼ同時に行われます。
$ npm run -s hello
FOO
BAR
hello スクリプトの中の run-p という部分を run-s に変更すると、FOO が出力された後 3 秒待ってから BAR と表示されるはずです。