Next.jsの.envファイルはどうやって選ばれるのか? .env.development / .env.production / .env.testの判定ロジック

Next.jsでは、環境に応じて読み込む.envファイルが変わります。
たとえば、
next dev→.env.developmentnext build/next start→.env.production- テスト実行時 →
.env.test
というように、実行環境によって読み込まれるファイルが変わります。
この記事では、Next.jsがどのように環境を判定して、どの.envファイルを読み込むのかを整理します。
まず結論
Next.jsでは、.envファイルを選択するときに、まずNODE_ENVを確認します。
基本的な考え方は次のとおりです。
NODE_ENV === "test"ならtest- それ以外の場合は、
devがtrueならdevelopment devがfalseならproduction
つまり、判定を単純化すると次のようになります。
NODE_ENV === "test" ?
↓ Yes
test
↓ No
dev === true ?
↓ Yes
development
↓ No
production
その結果、対応する.envファイルが決まります。
| mode | 主に使用される.env |
|---|---|
development | .env.development |
production | .env.production |
test | .env.test |
next devの場合
通常、開発サーバーを
next dev
で起動すると、Next.js内部ではdev: trueとして処理されます。
また、NODE_ENVが未設定の場合はdevelopmentになります。
そのため、
next dev
↓
dev = true
NODE_ENV = development
↓
mode = development
となります。
この場合、.env.developmentなどのdevelopment用の環境変数が使用されます。
next build / next startの場合
本番環境では、
next build
next start
のように実行します。
この場合は、
dev = false
NODE_ENV = production
↓
mode = production
となります。
したがって、.env.productionが対象になります。
NODE_ENV=testの場合は少し特殊
注意が必要なのがテスト環境です。
NODE_ENV=test
が設定されている場合、devの値よりもNODE_ENV=testが優先されます。
つまり、仮にnext devのようにdev=trueになっていたとしても、
NODE_ENV === "test"
ならmodeはtestになります。
NODE_ENV = test
dev = true
↓
mode = test
そのため、テスト時には.env.testが使用されます。
なぜNODE_ENV=testが優先されるのか
これは.env.localをテスト時に読み込まないようにするためです。
.env.localには、開発者個人の環境に依存する設定を入れることがあります。
たとえば、
DATABASE_URL=localhost
API_KEY=xxxxx
のような値です。
もしテスト実行時にも.env.localが強く影響すると、開発者のローカル環境によってテスト結果が変わってしまう可能性があります。
そのため、Next.jsではNODE_ENV=testの場合、.env.localを意図的に除外する設計になっています。
devとNODE_ENVの関係
ここまでを表にすると次のようになります。
| 実行方法 | dev | NODE_ENV | mode |
|---|---|---|---|
next dev | true | development | development |
next build | false | production | production |
next start | false | production | production |
| テスト | 任意 | test | test |
重要なのは、NODE_ENV=testの場合だけ特別扱いされるという点です。
通常はdevの値によってdevelopmentとproductionが決まりますが、NODE_ENV=testの場合はtestが優先されます。
Next.js内部の判定ロジック
Next.js内部の処理を簡略化すると、次のようなロジックになります。
let mode;
if (process.env.NODE_ENV === "test") {
mode = "test";
} else if (dev) {
mode = "development";
} else {
mode = "production";
}
つまり、
1. NODE_ENVがtestか?
↓
Yes → test
2. devがtrueか?
↓
Yes → development
3. それ以外
↓
production
という非常にシンプルな判定です。
Next.jsの.envファイルの選択で重要なのは、devとNODE_ENVの2つです。
特に覚えておきたいのは次の3点です。
dev=true→developmentdev=false→productionNODE_ENV=test→testが最優先
したがって、
next dev
↓
development
next build / next start
↓
production
NODE_ENV=test
↓
test
と考えると分かりやすいです。
また、テスト時に.env.localが除外されるのも、テスト環境を開発者個人のローカル設定から切り離すためです。