npm scripts で環境変数が設定できない(Windows で動かない)
"FOO=bar node app.js" の前置記法は POSIX シェル専用で、Windows 既定の cmd.exe では環境変数として解釈されない。
cross-env で OS 差を吸収するか、script-shell の変更や Node.js の --env-file で対処する。
#npm#scripts#env#windows#cross-env
公開:
要約
"build": "NODE_ENV=production node build.js" のような npm scripts が Windows で「'NODE_ENV' は、内部コマンドまたは外部コマンド…として認識されていません」と失敗するのは、FOO=bar command という環境変数の前置が POSIX シェルの構文だからです。
npm scripts は POSIX 環境では sh、Windows では cmd.exe で実行されます(npm config の script-shell)。
cmd.exe はこの記法を解釈できないため、環境変数が設定できないどころかコマンド自体が失敗します。
よくある原因
- 前置記法は sh 専用:
FOO=bar node app.jsは sh が「この 1 コマンドの間だけ FOO を設定する」と解釈する構文。
cmd.exe では FOO=bar を実行ファイル名として探しに行く。 - set の空白混入: cmd.exe 流に
set FOO=bar && node app.jsと書くと、barと&&の間の半角スペースが値の末尾に入り、比較が一致しなくなる。 - .env の自動読み込みは無い: npm scripts は
.envを読まない。
dotenv や--env-fileなどの明示的な仕組みが必要。 - 参照記法の違い: スクリプト内の
$FOOは cmd.exe では展開されず、%FOO%は sh では展開されない。
解決策
1. cross-env で OS 差を吸収する
npm install --save-dev cross-env{
"scripts": {
"build": "cross-env NODE_ENV=production node build.js"
}
}cross-env が変数設定を OS ごとの正しい方法に変換するため、同じ script が Windows / macOS / Linux で動きます。
2. script-shell を POSIX シェルに変更する
npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"Git Bash を npm scripts の実行シェルにすると、前置記法や $FOO がそのまま動きます。
ただしチーム全員の環境設定が前提になる点に注意してください。
3. --env-file で .env を読み込む
node --env-file=.env app.jsNode.js 20.6 以降は --env-file フラグで .env ファイルを process.env に読み込めます。
シェル非依存なので npm scripts に書いても OS を問わず動作します。