恐竜本舗

エンジニアをしている恐竜の徒然日記です。

Viteにおける環境変数の持ち方

Viteを使って個人開発してる中で地味に詰まったのでメモ。

Summary

  1. Vite の環境変数vite.config.tsにおける envDir で指定したディレクトリパスにある .env を参照する
  2. .env の情報は import.meta.env 内に保持される
  3. VITE_ prefix がつく環境変数のみを .env ファイルから取得し、それ以外は undefined となる
  4. TS 用の型補完は vite/client.d.ts で型定義を提供しており、自前型定義は ImportMetaEnv を補う形で追加する

ref: Env Variables and Modes | Vite

Contents

① Vite の環境変数vite.config.tsにおける envDir で指定したディレクトリパスにある .env を参照する

ディレクト

- public/
- src/
   └ main.ts
   └ index.html
- .env
- package.json
- yarn.lock
- vite.config.ts

vite.config.ts

import { defineConfig } from "vite";

export default defineConfig({
  root: "src", // src 配下を root としたい
  envDir: "../", // src がroot のため、envDir は1つ戻す
  publicDir: "../public",
  build: {
    outDir: "../dist",
  },
  server: {
    port: 9000,
  },
});

うっかりで地味に気づくのに時間かかった。。

.env の情報は import.meta.env 内に保持される

Vite でビルドした結果において、環境変数import.meta.env に保持される。

標準で下記のような情報を保持している。

  • import.meta.env.BASE_URL ... アプリのベースURL。
  • import.meta.env.DEV ... 開発環境で動作しているかどうか
  • import.meta.env.PROD ... 本番環境で動作しているかどうか
  • import.meta.env.MODE ... アプリのモード。 yarn build --mode {mode} のように文字列指定できる。 yarn devdevelopment モード、 buildproduction モードとして動作する
  • import.meta.env.SSR ... SSR での動作かどうか

VITE_ prefix がつく環境変数のみを .env ファイルから取得し、それ以外は undefined となる

Vite は標準で dotenvを内包している。

現在のモードに合わせて、下記のように読み込む条件が変わる。

- .env                # 全ての場合に読み込まれる
- .env.local          # 全ての場合に読み込まれ、gitには無視される
- .env.[mode]         # 指定されたモードでのみ読み込まれる
- .env.[mode].local   # 指定されたモードでのみ読み込まれ、gitには無視される

少し変わった特徴として、Viteでは環境変数が誤ってクライアントサイドに漏れないように、 VITE_ prefix がつく変数のみをViteで処理されたコードに公開する。

sample

VITE_HOGE=aaa
HOGE=bbb

これに対し、 クライアントサイドで取得を試みると下記のようになる。

  • import.meta.env.VITE_HOGE ... aaa
  • import.meta.env.HOGE ... undefined

デフォルトは VITE_ という指定だが、この prefix は enxPrefixvite.config.ts に指定して変更可能。

Viteのコードを追ってみると、シンプルに .env で読み取った情報の中から prefix が一致するものだけを吸っているっぽい。

github.com

④ TS 用の型補完は vite/client.d.ts で型定義を提供しており、自前型定義は ImportMetaEnv を補う形で追加する

Viteの import.meta.env の型定義は vite/client.d.ts で提供されている。 しかし、自前の環境変数には自動補完が効かないので、下記のような env.d.ts を作成する。

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string;
  readonly VITE_HOGE: string;
  readonly VITE_FUGA: string;
  /// etc...
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}