備忘録:既存プロジェクトの環境変数まわりの動き
関わっているプロジェクトにて、開発環境と本番環境で読み込む環境変数を切り替えるようにしたい、という要望が挙がった。
環境変数周りの動きについて、そのプロジェクトでどうなっているかを久しぶりに振り返ってみると、ふわっとした理解だったので細かなところでよく分からんとなってしまい、改めて理解してまとめておこうと思った。
環境変数の読み込み方はローカルと本番環境で異なるので、それぞれの違いを見ていく。
尚、ざっくりとした全体像としては以下の通り。
vite + react router v7
amplify + ビルドもamplify
RR7であることはあまり関係なく、「viteのプロジェクトをamplify上で動かしていて、ビルドもamplify上で行っている」ということが重要かと。
------
# 開発環境=ローカルPC上
ローカルでは.envファイルを読み込むことで、環境変数がimport.meta.envとして展開される。
既存環境では、vite.config内の下記の記述で.envが読み込まれている模様。
code:typescript
import { defineConfig, loadEnv } from "vite"
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "")
loadEnvは引数にmodeを受け取っており、\`.env.${mode}\` の形で自動で読み込み先を振り分けてくれる模様
https://scrapbox.io/files/67ed1d170dccfc0957f2de9d.png
実際に試してみたところ、npm run buildやnpm run dev時に
* --mode developmentとすると.env.developmentが
* --mode productionとすると.env.productionが
読み込まれた。
なので例えば、ローカル環境の環境変数に対してはnpmスクリプトでdev/prodの環境変数差し替えが可能そうということが分かった。
(例:npm run build:dev時には--mode developmentを渡し、npm run build:prod時には--mode productionを渡す)
------
# 本番環境=amplify上
一方の本番環境については、.envの読み込みは既存プロジェクトでは行っていないようだった(別プロジェクトでは行っている...)。
ではどうしているかというと、amplifyにはGUI/CLIで環境変数を設定する機能があり(こういったホスティング系のサービスでは、最近は大体環境変数の設定機能がある)、これを使うことになる。
ここで疑問に思った/思ってしまったのが、「どうやってamplifyに設定した環境変数が、import.meta.envとして読み取れるようになっているのか」という点。
調べてもこれといった答えは見つからなかったが、恐らくvite側に「環境=OS上の環境変数を読み取りimport.meta.envとして公開する」という機能を持っており、一方のamplify側は「環境=OS上に、amplifyに設定した環境変数を公開する」という機能を持っているのだと推測される。
※コンテナはOSじゃない、とかは突っ込まないでほしい
尚、viteはビルド時の静的解析でimport.meta.env.VITE_HOGEという文字列を、対応する環境変数の値に置き換える、ということをしているようだが、amplifyのデプロイ済みアーティファクト=ビルド成果物をダウンロードして中身を確認したところ、こちらも置き換わっていた(ローカルでのビルド時と同様に)。
つまりimport.meta.env.VITE_という文字列は、ビルド成果物のコード中には一切存在しない(コメント等を除き)、ということなので、amplify上でもビルド開始までにはviteが環境変数にアクセスできているのは間違いなさそう。
---
本題に戻って「devとprodで環境変数を差し替える」で言うと、amplifyにはブランチ毎に環境変数を差し替える機能があるが、amplify上でまで差し替えると管理が大変になるのと、「デプロイ後の環境で開発系のAPI叩く」などといった要件は発生しなさそうなので、本番環境/amplify環境については特に対策・変更は行わなくて良いかな、という状況。