ゆずめも

メモ的なブログです。主に勉強した事について書いてます。

cloudflare workerを始める

cloudflare workerずっと気になってたのでhelloworldとそのテストを触ってみたメモ

事前にアカウントは作っておいたのでプロジェクト作る所から。

プロジェクトを作る

pnpm create cloudflare@latest

これを実行するとcliでログインしていなければブラウザが起動して、cloudflareにログインする

コード

hello worldのテンプレートを選択して、生成されたsrc/index.tsを確認すると以下のコードが生成されていた

export interface Env {
}

export default {
    async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
        return new Response('Hello World!');
    },
};

Responseをnewしてreturnするとレスポンスを返せるのがわかる

メモ

トリガー

実行方法としては他にも

  • Alarm
  • Email
  • Queue
  • Scheduled(cron的な)
    • 3つまでの制限あり
  • Tail
    • リアルタイムでログを処理しロギングサービスや分析サービスに送信するために使うらしい

などトリガーにすることもできる*1

developers.cloudflare.com

Node.js Compatibility

Cloudflare workerは完全にnodejsのAPIをサポートしてるわけではない

developers.cloudflare.com

ただNode.js compatibilityというのがありwrangler.tomlcompatibility_flags = [ "nodejs_compat" ]と書いてフラグをオンにするとnode:bufferなど一部のAPIが使えるようになるらしい

developers.cloudflare.com

環境変数

基本的にはwrangler.toml[vars]部分に記述するらしいが、gitignoreの対象ではないので内容によっては書くのに抵抗がある

そういう時はローカルで動かす時は.dev.varsというファイルを作り、その中に.envのように記述するとwrangler devした時に引数のenvに入る。

developers.cloudflare.com

debug

デバッグwrangler devで行う事ができる。実行するとローカルサーバーが起動する。 なのでdevを実行してるターミナルと、httpie*2を使ってリクエストを送るターミナルの2つを開いてやってみる。

# terminal A
pnpm run dev # 裏でwrangler devを実行している

# terminal B
http localhost:8787
HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/plain;charset=UTF-8

Hello World!

テスト

テストにはwranglerパッケージから出てるunstable_devを使う

developers.cloudflare.com

hello worldのテンプレートにはテストツールが入っていないのでvitestを入れた*3
公式のサンプルで示されてるのはjsなのでtsとして書いた

import {unstable_dev, type UnstableDevWorker} from 'wrangler'
import {describe, beforeAll, afterAll, it, expect} from 'vitest'

describe("Worker", () => {
  let worker: UnstableDevWorker

  beforeAll(async () => {
    worker = await unstable_dev('src/index.ts', {
      experimental: { disableExperimentalWarning: true }
    })
  })

  afterAll(async () => {
    await worker.stop()
  })

  it('should return Hello World', async () => {
    const resp = await worker.fetch()
    if(resp) {
      const text = await resp.text()
      expect(text).toMatchInlineSnapshot(`"Hello World!"`)
    }
  })
})

今回は文字列を返すシンプルなものだが、KVなどを使い始めるとminiflareを使えばテストできるのか今後確認したい

miniflare.dev

その他

quickstartsとしてHonoを使っているテンプレートやGraphQL Yogaのテンプレートのようなものまであるようなのでgenerateしてみて中を見るのも良さそう。

developers.cloudflare.com

ただwarngler generateを実行すると

[WARNING] The generate command is no longer supported and will be removed in a future version.

と表示されるのでそのうち動かなくなりそう

またasync fetch以外にもasync cronのように書くと定期実行できるみたいなのでそっちもそのうち試してみる

*1:cloudflareのコンソール上にそれぞれTriggersとして定義されている

*2:https://httpie.io/

*3:ts-nodeとか使うとnodeのテストランナーでもできるとは思うTest runner | Node.js v21.2.0 Documentation