アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

npm-scripts でクロスプラットフォームに環境変数を参照するための npm を作成してみた

以下の記事で npm-scripts から環境変数を参照する方法と問題点について書いた。

課題として npm run するプラットフォームによって変数の参照記法が異なるため、それらを統一できない問題がある。npm-scripts でタスク管理したい派としては、どうしても解決したい。そこで対策用 npm を作成してみた。

以下に npm の設計などをまとめる。

npm-scripts における環境変数の参照記法

冒頭のリンク先でも解説してあるが、改めて。package.json に定義された値を npm-scripts から環境変数として参照する場合の記法は以下となる。

Platform Format
OS X, Linux $npm_package_NAME or $npm_package_config_NAME
Windows %npm_package_NAME% or %npm_package_config_NAME%

今のところ標準の npm run でこれを統一する方法はないらしい。よってプラットフォーム毎に script を分けるか cross-env のような npm により scripts を wrap して参照を解決しなくてはならない。

cross-conf-env

というわけで npm-scripts 内の環境変数に対する参照記法をクロスプラットフォームに解決する npm を開発。名づけて cross-conf-env。cross-env のアイディアと設計を参考にしたので、それに準じた命名にしてある。

まずはインストール。package.json が既に定義されている状態としてコマンドを実行。

$ npm i -D cross-conf-env

cross-conf-env では以下の参照記法をサポートしている。

Platform Format
OS X, Linux $npm_package_NAME or $npm_package_config_NAME
Windows %npm_package_NAME% or %npm_package_config_NAME%
独自 npm_package_NAME or npm_package_config_NAME

これらのどれを採用してもよいし混在も許可している。独自を選ぶと記法が統一できる。それ以外を選んだ場合は「プラットフォーム固有」→「cross-conf-env」の順に記法が解決される。

package.json での利用例。

{
  "name": "sample",
  "version": "1.0.0",
  "config": {
    "app": "MyApp"
  },
  "scripts": {
    "var": "cross-conf-env echo npm_package_config_app npm_package_version",
    "var:bash": "cross-conf-env echo $npm_package_config_app $npm_package_version",
    "var:win": "cross-conf-env echo %npm_package_config_app% %npm_package_version%"
  },
  "devDependencies": {
    "cross-conf-env": "^1.0.0"
  }
}

script の先頭に cross-conf-env を宣言、その後に実行したいコマンドを続ける。cross-conf-env はそれらを引数として扱い、環境変数の参照を検出したら解決してから子プロセスとしてコマンドを実行。

設計について。npm-cross-conf-env/cross-conf-env.js のみで完結する小さな実装。これを npm の体裁でくるんでいるだけ。おこなっていることも単純で、

  1. process.env から npm_package_ を接頭語とするプロパティを列挙
  2. process.argv の index = 1 以降を抽出、argv とする
  3. argv から 1 のプロパティ名を含む値を検索
  4. もし含むならその部分を process.env の当該プロパティの値に置換
  5. argv 先頭をコマンド、以降を引数として子プロセス起動

という感じ。

より実践的な利用方法

akabekobeko/examples-electron の各プロジェクトにある package.json を参照のこと。

これらは npm-scripts を共通にしつつ実行ファイル名やパッケージ化に使用する Electron のバージョンを config に切り出している。そのため流用が容易になった。設定を変えたい場合も長大な script を慎重に直すのではなく config を書き換えるだけで済む。

環境変数の解決により npm-scripts からハードコード部分を減らせる。これを前提にするとタスクランナーとしての実用性がグッと増すはず。

Copyright © 2009 - 2023 akabeko.me All Rights Reserved.