Deno Deployとローカル開発環境でdotenvを使う
2022年 Deno Advent Calendar 13日目の記事です。(しまった日付を間違えていた...)
Deno Deployとローカル開発環境で併せてdotenvを使う方法をご紹介します。🦕
モチベーション
1. ローカル開発環境では、.envから参照したい
- 実行コマンドの先頭に環境変数を列挙したり、velociraptorなどのツールは使わずに済ませる。
- ローカル開発環境での環境変数は
.gitignore
された.envファイルから参照する。
2. Deno Deploy上では、GUI上で設定した環境変数を参照したい
From here, you can navigate to the "Settings" -> "Environment Variable" tab via the left navigation menu. Enter "DATABASE_URL" into the "Key" field, and paste your connection string into the "Value" field. Now, press "Add". Your environment variables is now set.
の手順で設定したものを参照する。
3. ローカル開発環境とDenoDeploy上でソースコード上の条件分岐を発生させない
ローカルではdotenvを使って、Deno DeployではDeno.env.get
をそのまま使うなど、環境によって開発したソースコード上の条件分岐させない。
先に結論
export * as dotenv from "https://deno.land/std@0.167.0/dotenv/mod.ts";
await dotenv.config({
export: true,
// .env.exampleと、.env+通常の環境変数を比較して不足がないかチェック
safe: true,
example: "./path/to/.env.example",
path: "./path/to/.env",
});
const config = Deno.env.toObject();
export const ENV = {
DATABASE_URL: config["DATABASE_URL"],
};
ハマったこと
標準ライブラリになる前はDeno Deployでエラーが発生していた
結論の項でimportしているdotenvは標準ライブラリですが、こちらは2022.2.24に標準ライブラリになったものです。
それ以前はこちらのライブラリを使っていました。
こちらのconfig
関数を使ってDeno Deployにデプロイし、アクセスログを見ると以下のエラーが出ていました。
TypeError: Deno.readFileSync is not a function
at parseFile (https://deno.land/x/dotenv@v3.2.0/mod.ts:100:59)
at Module.config (https://deno.land/x/dotenv@v3.2.0/mod.ts:41:18)
at file:///src/server/src/config/environment.ts:2:23
こちらのライブラリのdotenv.config
は、同期関数であり内部的にはreadFileSync
を使用しており、https://deno.com/deploy/docs/runtime-api#deno-apis によるとDeno DeployはreadFileSync
をサポートしていないことが原因でした。
同ライブラリには、configAsync
という関数があり、これを使うことで、内部的にはreadFileSync
を避け、readFile
を使うので、エラーを解消できました。
逆に標準化されたライブラリでは、
configAsync
は廃止され、configSync
メソッドが導入されたようです。
つまりは命名の変化がありました。
configAsync
→ config
config
→ configSync
ですので、標準ライブラリでconfig
を使っておけば、特に問題なくDeno Deployを使えるということでした!
dotenvのconfig関数では、通常の環境変数を参照できない
前項で、config
関数の変化を把握したものの、config
関数では、通常の環境変数を参照できないようでした。
そこで、config
使って環境変数の定数を作り出すことは断念し、.envを読み込みだけをさせました。
https://deno.land/std@0.167.0/dotenv/mod.ts のAuto Loadingを参考に
await dotenv.config({
export: true
});
const config = Deno.env.toObject()
としました。
.envをexportし、参照はDeno.env.toObject()
に任せています。
最後に
dotenvでは、.env.exampleを配置することで、環境変数の不足時にクラッシュさせることができたり、デフォルト値を設定できたりするので、とても便利でした。
Discussion