TechVue.jsJapanese

Vue3 + TypeScript 開発環境で 環境変数 を利用する方法 (.env ファイル)

eye-catch image Tech

Vue.js アプリケーション を開発するにあたり、 パスワード や API Key といった 慎重に取り扱うべき データ を用いる局面が多々あります。 本記事では Vue3 + TypeScript + Vite 環境 で 環境変数 を用いることで この問題に対処する方法を紹介していきます。 また、用途別に環境を分けている場合にも有効な方法でもあります。

macOS: 12.3
vue: 3.2.31
typescript: 4.5.5
vue3 API: Composition API

Vite 環境変数定義用 ファイル の作成

[ads]

最初に Vite 環境変数 定義用の ファイル を作成していきます。 環境変数 を定義するための ファイル は vite.config.ts に記載することで、任意の場所に配置できますが、ここでは デフォルト の Path である プロジェクト の ルート ディレクトリ 直下 に作成していきます。

.env.[mode].local ファイル

開発環境 や 本番環境 といった環境別 ( Vite では Mode と読んでいます) に 環境変数 を使い分ける ニーズ に応えるため Vite では 環境変数 を格納する ファイル 名 を使い分ける ソリューション を提供しています。本記事では 開発環境 (development mode) を例に取り上げ進めていきます。

開発環境 でのみ有効な 環境変数 定義用 ファイル を作成するには .env の後に Mode 名 を追加することで実現可能です。 さて Mode 名は何を指定すれば良いでしょうか?

Default: 'development' for serve, 'production' for build

https://vitejs.dev/config/#mode

上記の通り、 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 定義追加

[ads]

このままでも、 環境変数 から値を取得することが可能です。 ただし、 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 アプリで読み込んでみる

[ads]
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 の パスワード など 環境変数 の中には ユーザ に見せたくない データ もあり、 環境変数 のパラメータ名を気をつけるだけで セキュリティインシデント を防げるということです。

環境変数 の 名称を変更して アプリ 再実行

試しに、先ほどの .envmain.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 型として 活用する場合は、別途 変換 ロジック が必要になりそうです。参考


まとめ

[ads]
  • Vue3 + TypeScript + Vite 環境 で 環境変数 を用いるためには以下を考慮
    • プロジェクト の ルート ディレクトリ に .env ファイル を作成し Vite 環境変数 を定義
    • env.d.ts に 定義した Vite 環境変数の型を Interface を用いて定義
    • import.meta.env.環境変数名 で Vite 環境変数 を利用可能
    • Vite 環境変数名 が VITE_ から始まるものは ブラウザ に読み込まれてしまうので 公開したくない値は格納しない

関連記事

Ads
Rambling and Delving