Next.jsで環境ファイル(env)別ビルドを行う


Next.jsを仕事で利用しようとすると大きな問題がある。
仕事で開発するプロダクトには、本番環境、検証環境、開発環境といった具合に複数の環境が必要です。

APIのエンドポイントなど、環境別に切り替えて利用をしたい場合は、環境変数を設定して環境別にビルドを行ったりします。

Next.jsは上記を実現しようとしたときにひとつ難を持っています。

環境ファイルについて

まずは、Next.jsの環境ファイルについてです。

公式ドキュメントを確認すると、環境ファイルにはそれぞれ役割を持っているようです。
メインの環境ファイルは、.env.local.env.development.env.productionなどがあります。

環境ファイル 役割
.env.local ローカル開発(next dev)?
.env.development ローカル開発(next dev
.env.production ビルド(next build/next start)

.env.local.env.developmentはほぼ同じ?

このように既に用意されている環境ファイルには適応コマンドが割り当てられているような感じです。

https://nextjs.org/docs/basic-features/environment-variables

今回やりたいこと

本番環境、検証環境、ローカル開発環境の3つの環境で、異なるAPIエンドポイントを利用するようにします。

以下のように環境別に環境ファイルを用意して、ローカル開発するときは、next devコマンドを実行するとローカル用の環境ファイルが利用され、next build:stgコマンドを実行すると、ステージング用の環境ファイルが利用されるようにしていきます。

# .env.production
NEXT_PUBLIC_API_HOST=https://api.sampleapis.com
# .env.staging
NEXT_PUBLIC_API_HOST=https://stg.api.sampleapis.com
# .env.local
NEXT_PUBLIC_API_HOST=https://localhost:8888/api

記載しているURIはサンプルです。

あとは、実行コマンドです。Gatsby.jsでは、GATSBY_ENV=developなどで環境ファイルを指定することができます。
こうしたNext.jsのパターンを調べていたのですが、これが見つからず、、、

Next.jsは、環境ファイル別のビルドに対応していない

ビルドコマンドは決まって、.env.productionが利用されるようです。調べていくと以下のissueが見つかりました。

https://github.com/vercel/next.js/issues/12772

どうやら、環境ファイルを識別してビルドを実行することはできないようです。

env-cmdで解決

Next.js単体で、今回やりたいことは実現できなそうだったので、issueの中でも登場しているenv-cmdを導入します。

yarn add env-cmd

環境ファイル名の変更

環境ファイル名には注意が必要です。.env.productionになっていると、自動で読み込まれてしまうため、この先のコマンド設定がうまく動作しませんでした。

https://github.com/vercel/next.js/discussions/25764#discussioncomment-2260194

環境ファイル名をそれぞれ以下のような形に変更しました。
.env.production.env.prod
.env.staging.env.stg
.env.localは今回そのままにしました。

コマンド設定の変更

env-cmdを利用したコマンド設定を行います。

"build": "env-cmd -f .env.prod next build && next export",
"build:stg": "env-cmd -f .env.stg next build && next export",

これで、コマンド一つで、環境変数の切り替えが可能になりました!