👨‍⚕️

【Vue3】Vite の環境変数に型定義していたけど効かなくなったので別の方法で効くようにした

に公開

🙋‍♀️はじめに

以前、Vite の環境変数で boolean 型を使う記事を書きました。
https://zenn.dev/tamura_h_d/articles/7031c3699afa57

ただ、筆者の環境でこの機能が使えなくなっていたので、別の方法に変えた事を共有しようと思います。
先に結論だけ簡単にお伝えすると、Zod を使いました。詳しくは後で解説します。

🧐経緯と調べたこと

2024.12 頃に Vue3 のプロジェクトを作成し、env.d.ts で型定義を運用していました。しばらくはよかったんですが、少し間が空いて最近開発を再開したんですが、型定義しているのに文字型のままになっている事に気づきました。
Vue.js 公式サイトで env.d.ts で検索すると、TypeScript 統合 の記載がありました。ただ、この内容が Reactivity Transform にあり、env.d.ts の型定義機能も Vue.js から削除されたんじゃないかと思いました。
Reactivity Transform の機能の削除は、GitHub の履歴では 2023.12.29 となっていました。いやいや。Vue プロジェクト作成のだいぶ前だけど💧 Vue.js のバージョンは 3.4系で、プロジェクト作成当初から変えてないので余計に謎が深まりました。TypeScript なので型定義で実装したいなぁと色々試してもだめでした。これ以上は考えても無駄な気がしたので、調べるのはここまでにしました。

💪どうやったか

AI に相談しながら Zod で対応することにしました。Zod は今も使っているのですんなりいけそうと思ったので。
https://zod.dev/

src 配下に env.ts ファイルを作成して、このように実装しました。(Zod のインストールは割愛してます)

env.ts
import { z } from 'zod'

const envSchema = z.object({
  VITE_APP_DEBUG: z.union(
    [z.literal('true'), z.literal('false')]).transform((t) => t === 'true'
  ),
  VITE_APP_TITLE: z.string(),
  VITE_APP_API_BASE_URL: z.string().url(),
}).readonly()

export const env = envSchema.parse(import.meta.env)

Zod オブジェクトに .env で定義した環境変数を定義します。
import.meta.env を使っているので フロントエンド専用 の機能です。(src 配下に env.ts ファイルを配置して、フロントエンド用とわかるように)
後は、定数にしたかったので読み取り専用にしました。

使う時は、

import { env } from './env'

// 途中省略
if (env.VITE_APP_DEBUG)
// env.VITE_APP_DEBUG === true としなくてもよくなった!

といった感じです。
env.d.ts は、型定義を削除しました。

env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
- readonly VITE_APP_DEBUG: boolean
- readonly VITE_APP_TITLE: string
- readonly VITE_APP_API_BASE_URL: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

🐶まとめ

他にも色々試したりして結構時間使ってしまいました。
TypeScript 統合 の記載のところで、vue/macros の事が書いてあったので入れてみたり。でもこれは今回の事とは関係なさそうでした。
ただ、Zod を使ってコードがスッキリしたので結果的に良かったんじゃないかと思います 🎉
もしも参考になったら、👍🩷 やコメント頂けると執筆の励みになります。🙇‍♀️🙏

Discussion