npm-run-allのもっと便利な使い方

UI開発者 古川

npm-run-allは複数のnpm-scriptsを実行できるコマンドラインツールです。npm-run-allを導入することで、OS環境にかかわらずシンプルな記述でnpm-scriptsを順次・並列実行できます。

# npm-run-scripts 導入前
npm run clean && npm run js && npm run babel && npm run minify

# npm-run-scripts 導入後
npm-run-all --sequential clean js babel minify

複数のnpm-scriptsを実行するには欠かせないnpn-run-allですが、「Globライクな指定で複数のタスクを実行」したり、「プレースホルダーを使用して引数をタスクに渡す」機能を用いることによってさらに便利に利用できます。

Globライクな指定で複数のタスクを実行する

npm-scriptsのみで開発環境を構築する場合、package.jsonが煩雑になることが懸念されます。

{
    "scripts": {
        "clean": "...",
        "sass": "...",
        "cssnano": "...",
        "babel": "...",
        "ts": "..."
    }
}

上記のようなタスクをnpm-run-allで順次実行する場合、以下のコードのように記述する必要があります。

{
    "scripts": {
        "build": "npm-run-all -p clean sass cssnano babel ts",
        "clean": "...",
        "sass": "...",
        "cssnano": "...",
        "babel": "...",
        "ts": "..."
    }
}

これでは可読性が損なわれるうえ、例えばcssnanoのタスクをなくす、というような変更を行う場合、上記のコマンドの記述も同時に修正する必要があります。

そこで以下のscriptsのようにタスク名を:で区切ると、npm-run-allで実行する場合にGlobパターンのようにタスク名を一括で指定できます。

{
    "scripts": {
        "build": "npm-run-all -p build:*",
        "build:clean": "...",
        "build:cssnano": "...",
        "build:babel": "...",
        "build:ts": "..."
    }
}

記述の方法はアスタリスクを1つつける場合と2つつける場合の2種類あります。build:*のようにアスタリスク1つをつけた場合は、watch:html:indexのように:を2つつけたタスク名のタスクまでは実行されません。これらを実行する場合はbuild:**のように2つ記述します。

プレースホルダーを使用して引数をタスクに渡す

npm-run-allでは、--で始まる引数を実行するタスクに渡すことが可能です。

{
    "scripts": {
        "server": "npm-run-all -p \"server:* -- {1} --port {2}\" --",
        "server:start": "http-server",
        "server:log": "echo \"Server successfully started on port:\""
    }
}

上記のようなnpm-scriptsを記述したうえで、次のコマンドを実行すると、下のキャプチャのような結果になります。

npm run server dist 3000
「npm run server dist 3000」を実行したときのキャプチャ

http-server dist --port "3000"が実行されているのとともに、server:logで出力される文言にport番号などが表示されているのがわかります。

プレースホルダーは{}の中に何番目かの数字を指定するほかに、以下のものがあります。

  • {@}:すべての引数を個別に列挙して渡す
  • {*}:引数をすべてつなげたものを渡す

タスクに渡される引数は必ずダブルクオーテーションで囲われることに注意してください。

上記のような機能を利用すれば、Gulpなどのタスクランナーを利用しなくても充分開発環境を構築できます。ちょっとした開発にはどんどんnpm-run-allを活用したいです。