Open5

Cloudflare Workers x Hono メモ

yuheitomiyuheitomi

Cloudflare Workers では環境変数は wrangler.toml に記載。コンフィデンシャルな環境変数はローカルでの開発では .dev.vars ファイルを利用することも可能。その際、デプロイの際にはクラウド環境に反映されないので、別途、プロジェクト設定にて変数を設定する必要がある。

yuheitomiyuheitomi

Hono 側での環境変数へのアクセスは以下の通り。

import { Hono } from 'hono'

interface Env {
  API_KEY: string
}

const app = new Hono<{ Bindings: Env }>()

app.get('/', (c) => {
  const apiKey = c.env.API_KEY
  return c.text(`API key is: ${apiKey}`)
})

インターフェース Env を利用は必須ではないが、設定しておくと型として認識されるので推奨。

yuheitomiyuheitomi

Wrangler.toml (Wrangler.json) や .dev.vars で定義した環境変数は wrangler types コマンドで自動生成されるみたい。

bunx wrangler types
yuheitomiyuheitomi

WIP 後でかく。Unit Test のやりかた。

Cloudflare のテスト環境として、以下を参考にセットアップ。

vitest@cloudflare/vitest-pool-workers をインストール。vitest は現時点では v3.0 には未対応。

npm install vitest@2.1.8 --save-dev --save-exact
npm install @cloudflare/vitest-pool-workers --save-dev

vitest.config.ts

import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config"

export default defineWorkersConfig({
  test: {
    poolOptions: {
      workers: {
        wrangler: { configPath: "./wrangler.json" },
      },
    },
  },
})

tsconfig.json に追加。

上記オフィシャルの Define Types では test ディレクトリの中にファイルと追加することにしているが、ここでは Hono のサンプルの様に、テスト対象コードと同じディレクトリにテスト用のファイルを配置したいのでグローバル(ルート)の tsconfig.json に追記した。

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "skipLibCheck": true,
    "lib": ["ESNext"],
    "types": [
      "@cloudflare/workers-types/2023-07-01",
      "@cloudflare/workers-types/experimental",
      "@cloudflare/vitest-pool-workers"
    ],
    "jsxImportSource": "hono/jsx"
  }
}

最後に環境変数などの型を参照できるように、以下のファイルを ./types/cloud-test.d.ts として追加。既に Wrangler.json や .dev.vars などでの定義が worker-configuration.d.ts に出力されている前提。

declare module "cloudflare:test" {
  // If you already have an existing Env interface, extend it
  interface ProvidedEnv extends Env {}
}

あとは、テストコードで参照すれば良い。

import { env } from "cloudflare:test"
import { describe, expect, test } from "vitest"

describe("test env", () => {
  test("has Api key", () => {
    const apiKey = env.GOOGLE_GENERATIVE_AI_API_KEY
    expect(apiKey).toBeDefined()
  })
})