npm_package_config と npm_config
npm-run-all の Support npm config params という issue から npm_config
の存在を知った。以前 npm-scripts 内で変数を展開したくなって cross-conf-env を開発した時に npm_package_config
は調べたが、この npm_config
も外部から npm-scripts にパラメータを渡す仕組みのようである。
これらの性質や用途について簡単にまとめてみる。
npm_package_config
package.json の config
欄に解説されている。
A "config" object can be used to set configuration parameters used in package scripts that persist across upgrades. For instance, if a package had the following:
{ "name" : "foo" , "config" : { "port" : "8080" } }
and then had a "start" command that then referenced the npm_package_config_port environment variable, then the user could override that by doing npm config set foo:port 8001.
package.json
の config
プロパティに key/value を定義することで npm-scripts 内へ npm_package_config_key
と展開する機能。
公式資料では言及されていないのだが npm-scripts は Shell になるため macOS などの bash 系は $npm_package_config_key
、Windows のコマンドプロンプトや PowerShell では %npm_package_config_key%
のように定義する。Node プログラム上からは process.env.npm_package_config_key
として参照可能。
私の作成した cross-conf-env ではこれらと修飾文字なしの npm_package_config
をサポート。混在させても展開するところが特徴。つまり Shell を問わず好きな書式で記述できるようにしてある。
この機能を利用すると npm-scripts 内のパラメータを直値から変数にできる。npm-scripts 間で重複する値があるとか、頻繁に更新される値があるなら変数化して config
プロパティ側の編集だけで済ませられるようにしておくと便利だ。
実例は akabekobeko/examples-electron を参照のこと。このリポジトリは複数の Electron プロジェクトを管理しているが、これらの npm-scripts は共通化され config
プロパティでアプリ名などを分岐している。
npm_config
config に解説されている。この資料は npm_package_config
に対しても言及あり。npm_package_config
と異なり、こちらは npm run
される時の引数として渡されたパラメータを展開する。例えば
{
"scripts": {
"task": "echo npm_config_foo npm_config_bar"
}
}
のように npm-scripts を定義して以下のようにパラメータを渡す。
$ npm run task --foo=Foo --bar=Bar
Foo Bar
npm run
されるスクリプトのオプションに --key=value
を指定するとスクリプト内の npm_config_key
へ展開される。Node プログラム上からは process.env.npm_config_key
として参照可能。
package.json
外からパラメータを渡すとか npm-scripts を多段実行する時に npm_package_config
代わりにするとかで役立つのかもしれない。本記事のきっかけとなった npm-run-all は npm-scripts を同期・非同期で多段実行するための npm なので、これに対応する必要があったのだろう。
npm_config
が展開される側は Shell なので前述のとおりプラットフォームごとの修飾文字が必要。cross-conf-env は v1.0.6 で対応した。
まとめ
私はプロジェクトに関する情報をなるべく package.json
へ静的に定義したいので npm_package_config
のほうが好みだ。しかしこちらは config
の定義が必要なうえ記述も長い。よって npm-scripts の多段実行は必要になるけれど、より短い npm_config
も便利な場面があるかもしれない。
package.json
で確定不能な設定については npm_config
へ頼らざるを得ない。npm_scripts を実行するのは主に開発者なので、このようなケースはあまり考えられないのだが npm から取得できない環境情報なんかを渡すときによいのだろうか。
ほぼ共通の設定で一部だけ異なる npm-scripts があるときに便利かもしれない。そういえば Browserify の require オプションでモジュールを外部公開するを書いた後に業務で
- 共通処理を定義した
main.js
- サブフォルダ単位で個別のデータを定義した
data.js
- HTML 上で
main.js
と組み合わせるdata.js
を変更することでページ内容が切り替えられる
という感じの Web サイトをビルドする機会があって、サブ フォルダが増えるたびにその名前だけ変更した npm-scripts を追加する運用を考えていた。しかしこれは面倒だから npm_config
によりフォルダ名を部分展開するほうがスマートな気がする。複数同時に生成するとしても npm-scripts の多段実行を前提とすれば package.json
で完結できる。
記事のまとめに軽く考察でも、と雑に書いていたら業務の問題がひとつ解決してしまった。
Comments from WordPress
- mysticatea 2016-09-14T23:59:12Z
ちなみにですが、
npm_package_config
の方も CLI オプションから指定できます。記法は
--パッケージ名:変数名=値
です。冒頭の
{"name": "foo", "config": {"port": "8080"}}
の場合は、npm run task --foo:port=8000
。 - アカベコ 2016-09-15T12:00:56Z
情報提供ありがとうございます。npm_package_config の場合はハイフンがひとつなのですね。