開発ツール

package.jsonのscriptsでよく使う小技

読了 5分
開発ツール

package.jsonのscriptsでよく使う小技

package.jsonscripts、普段は devbuild を呼ぶだけだったのですが、調べてみると専用のタスクランナーを入れなくても意外といろいろできるようです。知っておくと便利だった小技のメモです。

前後に自動で走る pre / post フック

スクリプト名の前に pre、後ろに post を付けた同名スクリプトを定義すると、本体の前後で自動実行されます。ビルド前のクリーンアップや、テスト前のlintなどに便利です。

{
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "tsc",
    "postbuild": "echo 'ビルド完了'"
  }
}

npm run build を実行すると、prebuildbuildpostbuild の順に走ります。呼び出し側は build を意識するだけでよいのがポイントです。これは便利。

スクリプトからスクリプトを呼ぶ

複数の処理をまとめた「入口」スクリプトを作ると、コマンドを覚える負担が減ります。他のスクリプトは npm run <名前> で呼び出せます。

{
  "scripts": {
    "lint": "eslint .",
    "typecheck": "tsc --noEmit",
    "check": "npm run lint && npm run typecheck"
  }
}

npm run check だけで、lintと型チェックを順番に実行できます。&& は前のコマンドが成功したときだけ次に進むので、途中で失敗すればそこで止まります。

並列で実行する

開発時にサーバーとビルド監視を同時に動かしたい、といった場合は並列実行が便利です。シェルの & でも書けますが、OS差や終了処理を考えると専用ツールのほうが扱いやすいようです。

{
  "scripts": {
    "dev:server": "node server.js",
    "dev:css": "tailwindcss -w -o public/app.css",
    "dev": "npm-run-all --parallel dev:server dev:css"
  }
}

npm-run-all(または concurrently)を使うと、dev:* のようにまとめて指定したり、片方が落ちたら全体を止めたりといった制御がしやすくなります。

追加の引数を渡す

スクリプトに引数を渡したいときは -- で区切ります。-- 以降は、スクリプトの実体コマンドにそのまま引き渡されます。

# eslint に --fix を渡す
npm run lint -- --fix

# 特定のファイルだけテストする
npm run test -- src/utils.test.ts

この -- を忘れると引数が npm 側に食われてしまうので、ここは注意してください。毎回フラグを変えて使うスクリプトは、本体を素直に書いておいて、呼び出し時に -- で足すと柔軟です。

環境変数を読む

スクリプト内では、package.json の値や独自の設定を環境変数として参照できます。たとえばパッケージのバージョンは npm_package_version で取れます。

{
  "scripts": {
    "release": "echo \"publishing v$npm_package_version\""
  }
}

OSをまたいで環境変数を設定したい場合は、cross-env を挟むとWindowsでも同じ書き方で動きます。Windowsだけ動かない…で困ったときの定番のようです。

{
  "scripts": {
    "build": "cross-env NODE_ENV=production next build"
  }
}

スクリプトの一覧を確認する

定義済みのスクリプトが思い出せないときは、引数なしで npm run を実行すると一覧が表示されます。

npm run

チームに新しく入った人が「どんなコマンドがあるのか」を把握するのにも役立ちます。地味ですがよく使います。

まとめ

  • pre / post フックで前後処理を自動化する
  • 入口スクリプトから npm run で他のスクリプトを呼んで、&& で連結する
  • 並列実行は npm-run-all などのツールが扱いやすい
  • 追加引数は -- で渡し、環境変数は npm_package_* で読む

特別なツールを導入する前に、まずはnpm scriptsで足りないかを検討してみるとよさそうです。仕様の詳細はnpm公式ドキュメント(scripts)にまとまっています。以上です。