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 の体裁でくるんでいるだけ。おこなっていることも単純で、
process.env
からnpm_package_
を接頭語とするプロパティを列挙process.argv
の index = 1 以降を抽出、argv
とするargv
から 1 のプロパティ名を含む値を検索- もし含むならその部分を
process.env
の当該プロパティの値に置換 argv
先頭をコマンド、以降を引数として子プロセス起動
という感じ。
より実践的な利用方法
akabekobeko/examples-electron の各プロジェクトにある package.json
を参照のこと。
これらは npm-scripts を共通にしつつ実行ファイル名やパッケージ化に使用する Electron のバージョンを config に切り出している。そのため流用が容易になった。設定を変えたい場合も長大な script
を慎重に直すのではなく config
を書き換えるだけで済む。
環境変数の解決により npm-scripts からハードコード部分を減らせる。これを前提にするとタスクランナーとしての実用性がグッと増すはず。