SvelteKit での環境変数の使い方
SvelteKit で $env
モジュールを使って環境変数をハンドリングする方法について解説しています。
やりたいこと
SvelteKit の環境変数を扱う $env
モジュールが便利だったので詳しく紹介します。
Vite の環境変数
SvelteKit は Vite のプロジェクトなので、Vite の環境変数の仕組みを使用することが可能です。Vite の環境変数については こちらの記事 で詳しく解説していますのでよかったらご覧ください。基本的に SvelteKit の環境変数の仕組みのほうが高機能なので、Vite の環境変数ではなく、SvelteKit の環境変数を使うことをお勧めします。なお、SvelteKit ではなく、Svelte だけで SPA を作っている場合は、Vite の環境変数を使うしかないので、繰り返しになりますが こちらの記事 をご参照ください。
SvelteKit の $env
モジュール
SvelteKit では Vite の環境変数をラップして以下 4 種類のモジュールとして提供されています。
$env/dynamic/private
$env/dynamic/public
$env/static/private
$env/static/public
違いは dynamic
or static
と private
or public
とです。まずは private
と public
の違いから見ていきます。
private
or public
公式ドキュメントでは private
は
変数名が
config.kit.env.publicPrefix
で始まらない、かつ、config.kit.env.privatePrefix
で始まる変数のみを含んでいます (設定されている場合に限る)。
このモジュールをクライアントサイドコードにインポートすることはできません。
とあり、public
は
config.kit.env.publicPrefix (デフォルトは
PUBLIC_
) で始まる変数のみを含んでおり、クライアントサイドのコードに安全に公開することができます。
と記載されています。
まずわかる違いはクライアントサイドに公開されるかどうかです。そしてそれをコントロールするのが config.kit.env.privatePrefix
と config.kit.env.publicPrefix
のようです。
DEFAULT
"PUBLIC_"
クライアントサイドコードに公開されても安全な環境変数に付与される接頭辞です。Vite の環境変数ハンドリングを使用する場合は、別途 Vite のenvPrefix
を設定する必要があることにご注意ください - ただし、通常この機能を使う必要はありません。
デフォルトでは PUBLIC_
プレフィクスが付いている環境変数が public
として扱えるようです。
また Vite の環境変数ハンドリングについて触れられていますが、SvelteKit の $env
モジュールと Vite の環境変数ハンドリング (import.meta.env
) を併用する場合はプレフィクスの設定方法がそれぞれ異なる注意です。ただ公式ドキュメントに記載の通り両方使う必要があるユースケースはあまり思い浮かびません。最初 Svelte のみで SPA を作っていて、Vite の環境変数を使っていて、その後 SvelteKit に移行したけどフロント部分手を入れたくないのでそのまま Vite の環境変数使っているみたいなケースぐらいでしょうか…。
DEFAULT
""
A prefix that signals that an environment variable is unsafe to expose to client-side code. Environment variables matching neither the public nor the private prefix will be discarded completely.
- Configuration • Docs • SvelteKit デフォルトでプレフィクス無しの環境変数が
private
として扱えます。Vite は SPA のようなフロントエンドの開発・ビルドを前提としているのでクライアントに公開する環境変数にのみプレフィクスがありましたが、SvelteKit は SSR でサーバーサイドもあるので明示的にプレフィクスを付けるオプションを用意しているのかもしれません。(ただしデフォルトはプレフィクス無し)
dynamic
or static
dynamic
は
このモジュールは、実行中のプラットフォームで定義された、実行時の環境変数へのアクセスを提供します。例えば、
adapter-node
を使用している場合 (またはvite preview
を実行中の場合)、これはprocess.env
と同じです。
- Modules • Docs • SvelteKit とある通り、基本的にプラットフォームの環境変数 (Windows であれば Windows の環境変数) を提供するモジュールです。
試しに以下のようなサーバー処理を用意し、$env/dynamic/private
から env
をインポートし、console.log()
で出力してみます。
ターミナルで npm run dev
を実行し、開発サーバーを起動します。ブラウザでアクセス後にサーバー側のターミナルを見てみると、OS の環境変数が出力されていると思います。
実行中のプラットフォームの環境変数が注入されるので、試せていませんが例えば AWS Lambda で動かす場合、AWS Lambda の環境変数を注入したりすることが可能だと思われます。
開発サーバーやデフォルトのビルドでは node サーバーを使用しているので、プラットフォームの環境変数以外に、.env
ファイルから独自の環境変数を定義する場合は、static
を使う方が良さそうです。
開発中(In dev)は、$env/dynamic には常に .env からの環境変数が含まれます。本番(In prod)では、この動作は使用する adapter に依存します。
static
は
.env
ファイルやprocess.env
から Vite が読み込む 環境変数です。(中略) このモジュールからエクスポートされた値はビルド時に静的に注入され、デッドコードの排除などの最適化が可能になります。
- Modules • Docs • SvelteKit とあり、Vite の環境変数と同様
.env
ファイルで定義する環境変数です。
あとコーディングレベルでの大きな違いとして、static
はモジュール $env/static/private
と $env/static/public
以下の直接プロパティとして各環境変数が定義されますが、dynamic
はモジュール $env/dynamic/private
と $env/dynamic/public
以下に env
というプロパティがあり、その env
以下に各環境変数が定義されています。
static
の場合、
のように直接環境変数毎に分割代入してインポートできますが、dynamic
の場合、
のように env
を分割代入でインポートした上で、env
のプロパティとして各環境変数にアクセスします。
.env
ファイルの場所
SvelteKit の $env
モジュールに読み込む .env
ファイルの場所は Vite の設定とは別に設定する必要があります。また、 Vite の環境変数ハンドリングを使用しない場合は Vite の設定は必要ありません。
SvelteKit の .env
ファイルの場所の指定は svelte.config.js
で行います。
DEFAULT
"."
.env
ファイルを探すディレクトリです。
以下のようにプロジェクトルート直下の env
ディレクトリに変更してみます。また private
or public
で紹介した環境変数のプレフィクスもここで設定することができます。ここでは試しにクライアントに公開可能な環境変数には DANGER_
とプレフィクスを付けてみます。これで DB のパスワードを公開してしまうような事故は無くなるでしょう。
環境変数の TypeScript 型補完
SvelteKit で TypeScript で開発するなら Vite の環境変数ハンドリングではなく SvelteKit の $env
モジュールを使用したほうがよい最大の理由は TypeScript の型補完です。Vite の環境変数では独自の環境変数については自分で型定義をする必要がありました。SvelteKit はこれも自動でやってくれます。
試しに以下のような .env
を用意します。.env
ファイルのロケーションや環境変数のプレフィクスは前節での変更を行った前提です。デフォルトの場合は .env
ファイルはプロジェクトルートに配置し、環境変数のプレフィクスも PUBLIC_
にしてください。
一度ターミナルで npm run dev
を実行した上で、./svelte-kit/ambient.d.ts
ファイルを見てみてください。$env/dynamic/public
と $env/static/public
内にしっかり DANGER_TEXT: string
という型定義がされていることがわかると思います。また $env/dynamic/private
内には OS の環境変数の型も定義されています。
このように全て自動で型定義をしてくれるのでかなり便利です。SvelteKit は以前紹介した Generated Type 始め、TypeScript 対応がしっかりされていて使いやすいです。
モードの切り替え
Vite の環境変数の仕組みで、独自モードの追加やモードによる環境変数の切り替えがそのまま使えます。詳しくは こちらの記事 をご参照ください。
あとがき
SvelteKit の $env
モジュールを使って環境変数を扱う方法を紹介しました。Svelte は全般的に TypeScript サポートが手厚く便利だなと思いました。