node.jsで .env と direnv を並行運用するには?

疑問: .env と direnv はどうやって並行運用するのだろうか?

Node.jsアプリケーションを開発していると、環境変数の管理方法として .env ファイルを使う方法と、 direnv のような環境変数管理ツールを使う方法があります。
両者を併用する場合、どのように動作するのか、優先順位はどうなるのかという疑問が生じます。

.env とはどのようなものなのか?

.env ファイルは、Node.jsアプリケーションで環境変数を管理するための単純なテキストファイルです。各行に=KEY=VALUE=の形式で変数を定義します。

例えば:

DB_HOST=localhost
DB_USER=admin
DB_PASS=password
API_KEY=1234567890

これらの変数を読み込むには、一般的に dotenv というパッケージを使用します:

require('dotenv').config();

// 環境変数にアクセス
console.log(process.env.DB_HOST); // "localhost"

dotenv.config() を実行すると、 .env ファイルの内容が読み込まれ、 process.env オブジェクトに追加されます。

そもそも process.env はどのように環境変数を読み込むのか?

Node.jsでは、 process.env オブジェクトを通じてシステムの環境変数にアクセスできます。プロセス起動時に、Node.jsはオペレーティングシステムの環境変数を自動的に process.env オブジェクトに読み込みます。

例えば、シェルで NODE_ENV=production node app.js と実行すると、アプリケーション内では process.env.NODE_ENV=に“production”= という値が設定されています。

console.log(process.env.NODE_ENV); // "production"

process.env は通常のJavaScriptオブジェクトなので、後から値を変更することも可能です:

process.env.MY_VARIABLE = "some value";
console.log(process.env.MY_VARIABLE); // "some value"

ただし、この変更はNode.jsプロセス内でのみ有効で、親プロセスや他のプロセスには影響しません。

process.env は環境変数と .env で定義された内容をどのように読み込むのだろうか?

環境変数の読み込み順序は次のようになります:

  1. Node.jsはまず、システムの環境変数を process.env に読み込みます
  2. .env=ファイルを使用している場合、=dotenv=などのライブラリが =.env ファイルを読み込み、その内容を=process.env=に追加します

重要なのは、 既に存在する環境変数は .env ファイルによって上書きされない という点です( dotenv のデフォルト動作)。つまり、システム環境変数(=direnv=で設定されたものを含む)が優先されます。

例えば、システム環境変数で API_KEY=system_key が設定されており、 .env ファイルに API_KEY=env_file_key と記述されている場合:

require('dotenv').config();
console.log(process.env.API_KEY); // "system_key"(システム環境変数が優先)

ただし、 dotenv の設定を変更することで、この挙動を変更することも可能です:

require('dotenv').config({ override: true });

override: true オプションを使用すると、 .env ファイルの値がシステム環境変数よりも優先されるようになります。

まとめ: 多くの場合では .env と direnv は平行運用する必要はない

Node.jsでの環境変数の扱いについてまとめると:

  1. process.env はシステムの環境変数を起動時に読み込みます
  2. direnv などのツールで設定した環境変数は、Node.jsプロセス起動前に設定されるため、 process.env に自動的に含まれます
  3. .env ファイルの変数は dotenv などのライブラリを使って process.env に追加されますが、デフォルトではシステム環境変数を上書きしません
  4. 必要に応じて dotenv の設定を変更し、 .env ファイルの優先度を上げることも可能です

したがって、 .env と direnv を並行して使用する場合、デフォルトでは direnv で設定した環境変数が優先されます。これにより、開発環境固有の設定を direnv で管理し、アプリケーション共通の設定を .env ファイルで管理するという使い分けが可能になります。

しかし、多くの場合では .env と direnv は平行運用する必要はないでしょう。