概要
Reactでは環境変数がビルド時に固定化されます。そのためテスト環境と本番環境で異なる環境変数を設定するには、通常はそれぞれ異なるビルドを出力する必要があります。
そこで今回は、同じビルドを出力してテスト環境と本番環境にデプロイしたのち、それぞれの実行環境で異なる環境変数を設定する特殊な方法を紹介します。
準備
Reactプロジェクトを新規作成します。(Viteを使います。)
npm create vite@latest react-app -- --template react-swc-ts
cd react-app
npm install
環境変数を.env.development.local
ファイルに設定します。
VITE_TITLE="Reactアプリ(開発環境)"
VITE_API_BASEURL="http://localhost:8000"
VITE_MSAL_CLIENT_ID="00000000-0000-0000-0000-000000000000"
VITE_MSAL_AUTHORITY="https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000"
VITE_MSAL_REDIRECT_URL="http://localhost:5173"
設定した環境変数を使います。
まずsrc/vite-env.d.ts
を編集して、型を定義します。
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_TITLE: string;
readonly VITE_API_BASEURL: string;
readonly VITE_MSAL_CLIENT_ID: string;
readonly VITE_MSAL_AUTHORITY: string;
readonly VITE_MSAL_REDIRECT_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
次にsrc/App.tsx
を編集して、環境変数を使います。
import "./App.css";
const App = () => {
return (
<>
<h1>{import.meta.env.VITE_TITLE}</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>TITLE</td>
<td>{import.meta.env.VITE_TITLE}</td>
</tr>
<tr>
<td>API_BASEURL</td>
<td>{import.meta.env.VITE_API_BASEURL}</td>
</tr>
<tr>
<td>MSAL_CLIENT_ID</td>
<td>{import.meta.env.VITE_MSAL_CLIENT_ID}</td>
</tr>
<tr>
<td>MSAL_AUTHORITY</td>
<td>{import.meta.env.VITE_MSAL_AUTHORITY}</td>
</tr>
<tr>
<td>MSAL_REDIRECT_URL</td>
<td>{import.meta.env.VITE_MSAL_REDIRECT_URL}</td>
</tr>
</tbody>
</table>
</>
);
};
export default App;
さらにindex.html
を編集して、ここでも環境変数を使います。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>%VITE_TITLE%</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
開発モードで実行します。
npm run dev
環境変数が反映されることを確認します。
ビルドした後に環境変数を設定する
.env.production
ファイルを下記のように作成し、ビルド時に環境変数をいったんMYAPP_***
という値で固定化します。
VITE_TITLE=MYAPP_TITLE
VITE_API_BASEURL=MYAPP_API_BASEURL
VITE_MSAL_CLIENT_ID=MYAPP_MSAL_CLIENT_ID
VITE_MSAL_AUTHORITY=MYAPP_MSAL_AUTHORITY
VITE_MSAL_REDIRECT_URL=MYAPP_MSAL_REDIRECT_URL
ビルドで固定化されたMYAPP_***
という値を、実行環境の環境変数値に置換するシェルスクリプトreplace-react-env.sh
を作成します。
#!/bin/sh
# ビルド出力先を指定します。
outDir="dist"
# ビルド出力ファイルの一覧を取得します。
files=$(find "$outDir" -type f)
# 実行環境の環境変数のうち`MYAPP_`から始まる環境変数名の一覧を取得します。
vars=$(printenv | grep '^MYAPP_' | awk -F= '{print $1}')
for file in $files; do
for var in $vars; do
# 実行環境での環境変数`MYAPP_***`の値を取得します。
value=$(printenv "$var")
# ファイルの中にある`MYAPP_***`という文字列を実行環境の環境変数値に置換します。
sed -i "s#$var#$value#g" "$file"
done
done
これにより、Reactをビルドして実行環境にデプロイしたのちreplace-react-env.sh
を実行すると、環境変数はビルド時に固定化された値ではなく、実行環境の環境変数値が反映されるようになります。
段階 | 環境変数の状態 |
---|---|
開発中 |
import.meta.env.VITE_*** (もしくは%VITE_***% )という式 |
ビルド後 |
MYAPP_*** という文字列 |
実行環境にデプロイ&replace-react-env.sh 実行後 |
実行環境での環境変数MYAPP_*** の値 |
動作確認
Reactをビルドします。
npm run build
いったんプレビュー確認します。
npm run preview
この時点では.env.production
で設定したMYAPP_***
という値が反映されます。
実行環境の環境変数を設定します。
export MYAPP_TITLE="Reactアプリ(本番環境)"
export MYAPP_API_BASEURL="https://prod-sample.com/api"
export MYAPP_MSAL_CLIENT_ID="11111111-1111-1111-1111-11111111"
export MYAPP_MSAL_AUTHORITY="https://login.microsoftonline.com/11111111-1111-1111-1111-11111111"
export MYAPP_MSAL_REDIRECT_URL="https://prod-sample.com"
replace-react-env.sh
を実行します。(chmod u+x replace-react-env.sh
で実行権限を付与しておきます。)
./replace-react-env.sh
再びプレビュー確認します。
npm run preview
実行環境の環境変数値が反映されることを確認します。