Viteのenv変数が更新されない時はdev server再起動とcacheを確認する
Viteは import.meta.env でenv変数を便利に扱えます。しかしその便利さには罠があります。.env を編集して保存すれば、hot module replacementで実行中のappも更新されると思いがちです。
通常そうはなりません。Viteはdev server起動時に .env filesを読みます。source filesはhot reloadされますが、env filesはstartup inputです。
症状: import.meta.envがundefinedまたは古い
よくある失敗です。
console.log(import.meta.env.VITE_API_BASE_URL);
値が undefined、または .env を編集しても古いURLのままです。
まず名前を確認します。
VITE_API_BASE_URL=https://api.example.test
client codeへ公開されるのは、defaultでは VITE_ prefixを持つ変数だけです。API_BASE_URL はprocess environmentに存在しても import.meta.env には出ません。
.env変更後は再起動する
.env を変えたらdev serverを止めて再起動します。
Ctrl+C
npm run dev
application codeを変える前にこれを試します。Vite docsでも .env filesはstartup時にloadされるため、編集後のstale valueは自動的にcode bugとは限りません。
productionとdevelopmentのenv fileを分ける
production buildに入れてはいけない値はmode-specific fileに分けます。
.env
.env.development
.env.production
例です。
# .env.development
VITE_DEBUG_TRIAL_STATE=active 5
VITE_FORCE_ONBOARDING=true
# .env.production
VITE_PUBLIC_SITE_URL=https://example.com
build modeがどのfileを読むかを決めるため、productionからdev-only値を消す防御codeを減らせます。
TypeScriptにcustom envを宣言する
TypeScriptに変数名を認識させます。
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_BASE_URL: string;
readonly VITE_DEBUG_TRIAL_STATE?: string;
readonly VITE_FORCE_ONBOARDING?: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
VITE_API_BASEURL のようなtypoを早く見つけられます。
import.meta.env.DEVだけに頼らない
import.meta.env.DEV は便利ですが、危険なdebug pathをproductionから守る唯一の条件にしないほうが安全です。
明示的なdebug variableを使います。
const debugTrialState = import.meta.env.VITE_DEBUG_TRIAL_STATE ?? "";
if (debugTrialState) {
// dev-only simulation path
}
production buildではstripまたはrejectします。
export default defineConfig(({ mode }) => ({
define:
mode === "production"
? { "import.meta.env.VITE_DEBUG_TRIAL_STATE": JSON.stringify("") }
: {},
}));
licensing、payment、auth、customer dataに関わるdebug flagなら、productionで設定されていたらbuild failにします。
どうしても変ならVite cacheを消す
まれにVite cacheでdev sessionが違うmodeのように振る舞います。stale envより強い症状、つまりdev-only codeがdev commandでも動かない場合です。
cacheを消します。
rm -rf node_modules/.vite .vite
npm run dev
PowerShellでは:
Remove-Item -Recurse node_modules\.vite, .vite -ErrorAction SilentlyContinue
npm run dev
prefix、server restart、mode-specific filesを見た後に試します。
build後のHTML placeholderも確認する
ViteはHTML内の %VITE_*% placeholderを置換できます。
<a href="%VITE_CHECKOUT_URL%">Buy now</a>
build outputを確認します。
npm run build
grep -R "%VITE_" dist
dist にplaceholderが残っているなら、build時に変数がありません。
チェック順
- 変数名が
VITE_で始まるか .env編集後にdev serverを再起動したか.env.development/.env.productionに分けるべき値かvite-env.d.tsに宣言したか- build後の
distに未解決placeholderがないか - それでもだめなら
.vitecacheを消す