環境ごとに環境変数を管理したく、
色々調べた結果、なんとなく方向性が決まったのでメモ。
やりたいこと
- 少なくとも、開発用、ステージング用、本番用で環境変数を変えたい
- 人為的エラーは少なくしたい
- 各サーバーでの作業を減らしたい
環境
- Next.js 15.0.2
.env
Next.js では、
環境変数は .env のようなファイルを用意して扱うらしい。
置く場所
Note: If you are using a /src folder, please note that Next.js will load the .env files only from the parent folder and not from the /src folder. This loads process.env.DB_HOST, process.env.DB_USER, and process.env.DB_PASS into the Node.js environment automatically allowing you to use them in Route Handlers.
/path/to/your/project/app に .next やら package.json やらが詰まった Next.js のプロジェクトがあれば、
/path/to/your/project/app に .env などのファイルを置くらしい。
/path/to/your/project/app/src に置くと読み込まれない。
とのこと。
ファイル名
Environment variables are looked up in the following places, in order, stopping once the variable is found.
- process.env
- .env.$(NODE_ENV).local
- .env.local (Not checked when NODE_ENV is test.)
- .env.$(NODE_ENV)
- .env
- 上記のファイル名パターンが対象。とのこと。
- 各ファイル間で変数名が重複したら上のパターンから優先される。
- .env.local は test には含まれない
- process.env はファイル名ではない。けど何を指しているのか分からない。
Good to know: The allowed values for NODE_ENV are production, development and test.
NODE_ENV は「production」「development」「test」の3種類のみ。
とのこと。
使い方
# .env
TEST=test
NEXT_PUBLIC_TEST=next public test
サーバーサイドレンダリング環境下では意識しなくていいけど、
"use client" で使う時は、頭文字に「NEXT_PUBLIC_」をつける。
取得できない変数は undefined になる。
// /src/app/page.tsx
export default function Home() {
console.log(process.env.TEST)// test
console.log(process.env.NEXT_PUBLIC_TEST)// next public test
return (
<>
{ process.env.TEST }<br/>
{ process.env.NEXT_PUBLIC_TEST }<br/>
</>
)
}
"use client" の場合。
// /src/features/something/index.tsx
"use client"
export default function Something() {
console.log(process.env.TEST)// undefined
console.log(process.env.NEXT_PUBLIC_TEST)// next public test
return (
<>
{ process.env.TEST }<br/>
{ process.env.NEXT_PUBLIC_TEST }<br/>
</>
)
}
方向性
- gitignore で .env* と記述されていたけど git で .env ファイルを管理する
- 迷ったけど、一旦、一部 .env ファイルは管理する方向で。
- NODE_ENV は意識させない
- これに依存させると、かゆい所に手が届かなくなる
- APP_ENV などの独自の環境変数は使わない
- こういうの導入すると地獄を見る気がする
- next.config.ts には記述しない
- dotenv 系は使わない
ファイルを用意する
$ touch .env.test
$ touch .env.dev
$ touch .env.stg
$ touch .env.prod
# .env.test
NEXT_PUBLIC_TEST=test
# .env.dev
NEXT_PUBLIC_TEST=development
# .env.stg
NEXT_PUBLIC_TEST=staging
# .env.prod
NEXT_PUBLIC_TEST=production
.gitignore
プロダクトの内容によっては .env.sample のようなファイルを用意して、
中身をダミーデータにする。その場合 .gitignore に追加するのはダミーデータのファイルのみ。
# env files (can opt-in for commiting if needed)
.env*
# 追加
!.env.test
!.env.dev
!.env.stg
!.env.prod
packege.json
コマンドで読み込む .env.local ファイルの内容を変える。
これのデメリットはホットリロードに対応していないので、
環境変数を変えたらコマンドを打ち直す必要があること。
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}
↓
{
"scripts": {
"dev": "rm -f .env.local && cp .env.dev .env.local && next dev --turbopack",
"dev:stg": "rm -f .env.local && cp .env.stg .env.local && next dev --turbopack",
"build": "rm -f .env.local && cp .env.dev .env.local && next build",
"build:stg": "rm -f .env.local && cp .env.stg .env.local && next build",
"build:prod": "rm -f .env.local && cp .env.prod .env.local && next build",
"start": "next start",
"lint": "next lint"
}
}
ex)
$ npm run build:stg
$ npm run start