🧷
Hono on Cloudflare Workersではprocess.envの代わりにc.envを使う
個人開発でHono on Cloudflare Workersな構成でAPIを開発しています。
問題
.dev.vars
に環境変数を書き、wrangler dev
で開発サーバーを起動すると、DBへの接続ができずエラーが発生してしまいました。
import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";
export const env = createEnv({
server: {
...
DATABASE_URL: z.string().url(),
},
runtimeEnv: process.env,
});
調査すると環境変数がundefined
のままになっていることが原因でした。
環境変数は渡しているはずだし、作業用のスクリプトには環境変数が設定されておりうまく動いています。
※t3-envを使っているのは環境変数にも型をつけるためです。
t3-envを使わずprocess.env
に直接アクセスしようとしても同じ問題がおきます。
解決方法
公式ドキュメントにCloudflare Workersでは、環境変数はprocess.env
ではなくc
(コンテキスト)経由で取得する必要がる旨が書かれていました。
For Cloudflare Workers, environment variables must be obtained via c, not via process.env.
次のように、Bindingsに環境変数の型を設定し、c.env.XXX
のように環境変数にアクセスできます。
Cloudflare WorkersがEdge環境で動き、リクエストごとに異なるマシンで動くための制約でしょうか
type Bindings = {
SECRET_KEY: string
}
const app = new Hono<{ Bindings: Bindings }>()
app.get('/env', (c) => {
const SECRET_KEY = c.env.SECRET_KEY
return c.text(SECRET_KEY)
})
ちなみにwrangler types
コマンドを使うと、.dev.varsを読み取って型定義ファイル(worker-configuration.d.ts
)を生成してくれるので、Bindings型を定義する必要もありません。
ドキュメントの手順に従い、tsconfig.jsonを設定した上で次のように書くことができます。
// tsconfig.json
...
"types": ["./worker-configuration.d.ts"],
...
import { Hono } from "hono";
const app = new Hono<{ Bindings: Env }>() // Envがworker-configuration.d.tsに宣言されている
app.get('/env', (c) => {
const SECRET_KEY = c.env.SECRET_KEY
return c.text(SECRET_KEY)
})
Discussion