動くデモサイトを作る

Yusuke Wada
Workers Tech Talks in Osaka #3


Yusuke Wada

::right::

me


今日話すこと


そもそも何か?


プロダクトを紹介したい!

::right::

dos


最低限のコード例

import { Hono } from 'hono'

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

app.get('/markdown', (c) => {
  const url = c.req.query('url') ?? 'https://example.com'
  return c.env.BROWSER.quickAction('markdown', { url })
})

export default app

どうするか?

::right::

github


どうせなら...


動かす?


WebページはWorkersで動いている

::right::

web


各デモは独立したWorkersプログラムになっている

// cloudflare-demos/demos/browser-run/src/index.ts
import { Hono } from 'hono'

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

app.get('/markdown', (c) => {
  const url = c.req.query('url') ?? 'https://example.com'
  return c.env.BROWSER.quickAction('markdown', { url })
})

export default app

::right::

github


WorkersからWorkersを立ち上げらればいい!


Dynamic Workers


コードの中にコードを書ける

// src/index.ts
export default {
  async fetch(request, env): {
    const worker = env.LOADER.load({
      compatibilityDate: '2026-06-01',
      mainModule: 'src/index.js',
      modules: {
        'src/index.js': `
          export default {
            fetch(request) {
              return new Response("Hello from a dynamic Worker");
            },
          };
        `
      }
    })
    const entrypoint = worker.getEntrypoint()
    return entrypoint.fetch(request)
  }
}

詳しくは2026年6月3日「Workers Tech Talks in Hokkaido #2」でやった「Dynamic Workersについて」を参考に


基本的な仕組み

  1. 親Workerがデモ用のコードを持っている
  2. リクエストが来たら、対象のデモのコードをDynamic Workersで実行
  3. デモWorkerにリクエストを渡す
  4. レスポンスをそのまま返却

もう少し詳しく


例: KVのデモコード

// demos/kv/src/index.ts
import { Hono } from 'hono'

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

app.get('/keys/:key', async (c) => {
  const value = await c.env.KV.get(c.req.param('key'))
  return c.text(value)
})

export default app

1. ブラウザからリクエスト

WebのUI

browser

::right::

親Workerへのリクエスト

// GET /run/kv/keys/greeting
fetch('/run/kv/keys/greeting')

2. 親WorkerがデモWorkerを立ち上げる


image


Bindingsをどう実現しているか?


問題

  1. 親WorkerのBindings env.KV はそのまま渡せない
  2. デモごとにネームスペース、データベースを分けたい
  3. デモWorkerは外部へのアクセスを制限したい(globalOutbound: null等)

やりたいこと

デモのコードは本物のWorkerと同じまま、実行環境だけ多人数共有のサンドボックスにする


どうやってるか


カスタムBindingsを作る

import { WorkerEntrypoint } from 'cloudflare:workers'

export class KVFacade extends WorkerEntrypoint<Env, Props> {
  #key(key: string) {
    // prefix => `sessions:${sid}:kv`
    return `${this.ctx.props.prefix}:${key}`
  }
  get(key: string) {
    return this.env.SITE_KV.get(this.#key(key))
  }
}

デモWorkerに渡す

const worker = c.env.LOADER.get(`kv@${sid}`, async () => ({
  mainModule: 'index.js',
  modules: { 'index.js': bundle },
  env: {
    KV: c.executionCtx.exports.KVFacade({ props: { prefix: `sessions:${sid}:kv` } }) }
  },
  globalOutbound: null
}))

対応プロダクト

cf-demo


その他工夫した点


3つのRate Limiting


デモ


まとめ

← → / space ・ f: fullscreen