本記事には、更新版の記事がありますので、併せてご参照ください。
Vue.js アプリケーション を開発するにあたり、 パスワード や API Key といった 慎重に取り扱うべき データ を用いる局面が多々あります。 本記事では Vue3 + TypeScript + Vite 環境 で 環境変数 を用いることで この問題に対処する方法を紹介していきます。 また、用途別に環境を分けている場合にも有効な方法でもあります。
macOS: 12.3 vue: 3.2.31 typescript: 4.5.5 vue3 API: Composition API
Vite 環境変数定義用 ファイル の作成
最初に Vite 環境変数 定義用の ファイル を作成していきます。 環境変数 を定義するための ファイル は vite.config.ts に記載することで、任意の場所に配置できますが、ここでは デフォルト の Path である プロジェクト の ルート ディレクトリ 直下 に作成していきます。
.env.[mode].local ファイル
開発環境 や 本番環境 といった環境別 ( Vite では Mode と読んでいます) に 環境変数 を使い分ける ニーズ に応えるため Vite では 環境変数 を格納する ファイル 名 を使い分ける ソリューション を提供しています。本記事では 開発環境 (development mode) を例に取り上げ進めていきます。
開発環境 でのみ有効な 環境変数 定義用 ファイル を作成するには .env
の後に Mode 名 を追加することで実現可能です。 さて Mode 名は何を指定すれば良いでしょうか?
Default:
https://vitejs.dev/config/#mode'development'
for serve,'production'
for build
上記の通り、 npm run dev
によって serve される 場合は デフォルト では ‘development’ という名称になっています。 つまり、 開発環境 の場合、 環境変数 定義用 ファイル は以下のファイル名とする必要があります。
.env.development
ただし、このままでは誤って リポジトリ に コミット してしまう可能性があります。 今回は 公開したくない値を 環境変数 に指定する ケース を想定していますので、 ファイル名の末尾に .local
を付与していきます。
.env.development.local
vue-create
で作成した プロジェクト で生成された .gitignore
には 以下が記載されているため、 .local
を付与することで GitHub などに誤って コミット してしまうことを防げるということになります。
node_modules .DS_Store dist dist-ssr coverage *.local
なお Visual Studio Code であれば、以下のように グレーアウト され、git 管理対象外となっていることが分かります。
Vite 環境変数の定義の記載
それでは 作成した .env.development.local
ファイル に 環境変数 を定義していきます。今回は Vite 公式 サイト のサンプル と同じ内容で、以下のように記載します。
DB_PASSWORD=foobar VITE_SOME_KEY=123
コード 補完機能 有効化: env.d.ts に interface 定義追加
このままでも、 環境変数 から値を取得することが可能です。 ただし、 Visual Studio Code などで利用可能な コード 補完機能 (インテリセンス) を活用したい場面があるかもしれません。 Vite では env.d.ts
ファイル で、 Interface 定義を記載することで、これを実現することができます。
/// <reference types="vite/client" />
プロジェクト 作成の初期状態では 上記のような内容になっていますので 2行目 以降に 先ほど .env
に記載した 2つ の 環境変数 を それぞれの 型 と共に定義していきます。
/// <reference types="vite/client" /> interface ImportMetaEnv { readonly DB_PASSWORD: string readonly VITE_SOME_KEY: string } interface ImportMeta { readonly env: ImportMetaEnv }
Vite 環境変数 を Vue3 アプリで読み込んでみる
import { createApp } from 'vue' import App from './App.vue' const pass = import.meta.env.DB_PASSWORD const key = import.meta.env.VITE_SOME_KEY console.log("pass", pass, typeof (pass)) console.log("key", key, typeof (key)) createApp(App).mount('#app')
Vue3 アプリ を実行してみる
それでは npm run dev
コマンド で アプリ を実行してみます。 ブラウザ の コンソール に以下のような形で出力がされます。
ここで pass について undefined となって .env
ファイル からの 読込み に失敗しているように見えますが、 これは Vite 環境変数読込み の デフォルト 仕様に起因しています。
- クライアント(ブラウザ)に表示させて良いもの:VITE_ から始まる パラメータ名
- クライアント(ブラウザ)に表示させて良いもの:VITE_ 以外から始まる パラメータ名
今回の例の様に DB の パスワード など 環境変数 の中には ユーザ に見せたくない データ もあり、 環境変数 のパラメータ名を気をつけるだけで セキュリティインシデント を防げるということです。
環境変数 の 名称を変更して アプリ 再実行
試しに、先ほどの .env
と main.ts
を以下の様に変更してみます。
VITE_DB_PASSWORD=foobar VITE_SOME_KEY=123
import { createApp } from 'vue' import App from './App.vue' const pass = import.meta.env.VITE_DB_PASSWORD const key = import.meta.env.VITE_SOME_KEY console.log("pass", pass, typeof (pass)) console.log("key", key, typeof (key)) createApp(App).mount('#app')
環境変数名 をいずれも VITE_
で始まる形にしましたので、以下の様に pass の値も出力されるようになりました。
検証:Vite 環境変数 定義用 ファイル 名 を変えてみて Vue3 アプリ の振る舞いを確認してみる
ここで、 試しに 環境変数 定義用 ファイル 名 を変更してみて、挙動に変化があるか試してみます。 .env.development.local
ファイル を、 内容はそのままに 以下のファイル名に変更してみます。
.env.dev.local
次に .env.dev.local
に リネーム し アプリ を実行してみます。 すると、 以下のように 環境変数 が読み込まれず undefined という結果になってしまいます。
.env.local
今度は .env
という名称に変更してみます。 development という モード名が入っていませんが、以下の通り 環境変数 を読み込むことができています。 これは .env
という 環境変数 定義用 ファイル 名は全ての モード で読み込むことができるためです。
.env.local
と .env.development.local
の併用
最後に .env.local
と .env.development.local
の 2 つを プロジェクト の ルート ディレクトリ に配置した場合の動作をみていきます。
VITE_DB_PASSWORD=env.local VITE_SOME_KEY=123
VITE_DB_PASSWORD=env.development.local
上述の 2 ファイル を プロジェクト の ルート ディレクトリ に配置して アプリ を実行してみます。
すると、.env
のみに記載された 環境変数 の内 .env.development.local
と重複したものは .env.development.local
に記載した内容が 環境変数 として採用されています。 このように 共通となる .env.local
に記載した内容より モード を指定した .env.development.local
の方が 優先度が高いということが分かります。 詳細は こちら を参照してください。
全環境共通のものは .env.local
に定義しておき、 環境ごとに異なる値は .env.development.local
などの個別の ファイル に定義するといった使い分けが有効になるかと思います。
検証:Vite 環境変数 を string 以外で読み込めるか?
上述した通り、 env.d.ts
に 環境変数 を その型と共に定義しましたが、 例えば 今回でいうと VITE_SOME_KEY
は number 型として読み込めると便利そうです。それでは、実際に number 型 で読み込めるか試してみます。
/// <reference types="vite/client" /> interface ImportMetaEnv { readonly DB_PASSWORD: string readonly VITE_SOME_KEY: number } interface ImportMeta { readonly env: ImportMetaEnv }
実際に実行してみると、以下の様に結果は変わらず、string として扱われています。
ですので、 env.d.ts
の Interface に型を定義する際は 常に string としておき、 取得できる値は string であることを意識するのが良さそうです。number 型として 活用する場合は、別途 変換 ロジック が必要になりそうです。参考
まとめ
- Vue3 + TypeScript + Vite 環境 で 環境変数 を用いるためには以下を考慮
- プロジェクト の ルート ディレクトリ に
.env
ファイル を作成し Vite 環境変数 を定義 env.d.ts
に 定義した Vite 環境変数の型を Interface を用いて定義import.meta.env.環境変数名
で Vite 環境変数 を利用可能- Vite 環境変数名 が
VITE_
から始まるものは ブラウザ に読み込まれてしまうので 公開したくない値は格納しない
- プロジェクト の ルート ディレクトリ に