Node.js の --env-file で .env を読み込む方法と注意点
環境変数を .env ファイルに書いておき、Node.js の起動時に読み込ませる方法を整理します。追加のパッケージは不要で、node コマンドのオプションだけで使えます。ここでは Node.js 22 を対象にし、公式ドキュメントの記述と、手元で実行した結果を分けて書きます。
基本の使い方
.env を次のように用意します。
# コメント
PORT=3000 # 行末のコメント
USERNAME="nodejs"
export GREETING='hello'
MULTI_LINE="THIS IS
A MULTILINE"
読み込んだ値を表示するスクリプトを index.js として用意します。
console.log(process.env.PORT)
console.log(process.env.USERNAME)
console.log(JSON.stringify(process.env.MULTI_LINE))
--env-file にファイルを渡して実行します。
node --env-file=.env index.js
実行すると、3000、nodejs、"THIS IS\nA MULTILINE" が表示されました。公式ドキュメントによると、ファイルはカレントディレクトリからの相対パスで探されます。値は引用符 (`、"、') で囲め、囲んだ引用符は値に含まれません。export が先頭にあっても無視され、複数行の値も書けます。# 以降はコメントです。
つまずきやすい点
値は常に文字列になる
PORT=3000 を読み込んでも、process.env.PORT は数値ではなく文字列 "3000" です。実際に typeof で確かめると string でした。数値として使うなら Number(process.env.PORT) のように変換します。
すでにある環境変数が優先される
同じ名前の変数がシェルの環境とファイルの両方にあると、環境側の値が使われます (公式ドキュメントの記述)。PORT=9999 node --env-file=.env index.js を実行したところ、.env に PORT=3000 があっても 9999 が表示されました。
複数ファイルは後のものが優先される
--env-file は複数回指定できます。公式ドキュメントでは、後ろのファイルが前のファイルの変数を上書きすると説明されています。.env の PORT=3000 と .development.env の PORT=4000 を次の順で渡すと、4000 になりました。
node --env-file=.env --env-file=.development.env index.js
ファイルがないとエラーになる
存在しないファイルを指定すると、エラーで終了します。手元では node: nope.env: not found と表示され、終了コードは 9 でした。ファイルがなくてもよいときは --env-file-if-exists を使います。ファイルがなければ読み込みを飛ばして続行します。手元では nope.env not found. Continuing without it. と表示され、終了コードは 0 でした。
node --env-file-if-exists=.env.local index.js
バージョンについて
公式ドキュメントの変更履歴では、--env-file は v20.6.0 で追加され、v21.7.0 と v20.12.0 で複数行の値に対応し、v22.21.0 で実験的機能ではなくなりました。--env-file-if-exists は v22.9.0 で追加され、同じく v22.21.0 で実験的機能ではなくなっています。このため、この記事では v22.21.0 以降を対象にしています。それ以前のバージョンでは、動作が異なる可能性があります。
なお、ここで確かめたのは上のコマンドの動作だけです。.env には秘密情報を書くことが多いので、Git に含めないよう .gitignore に追加することをおすすめします。