Aller au contenu

Cloudflare Workers

Cloudflare s’appuie sur la base d’adaptateur Web (le même modèle Request/Response que Bun) : contrairement à Vercel et Netlify, il streame en directres.stream() et les SSE émettent les chunks au fur et à mesure plutôt que de bufferiser toute la réponse.

Node / BunVercel / NetlifyCloudflare
Configchaîne / ServerlessConfigServerlessConfigServerlessConfig
Découverte des routesscan / manifestManifest pré-compiléManifest pré-compilé
Streamingdirectbufferisédirect
req.platform{}{}{ env, ctx, cf }
my-app/
├── routes/
│ ├── index.ts
│ └── users/
│ └── [id]/
│ └── index.ts
├── worker.ts
├── env.d.ts
└── wrangler.toml
// worker.ts
import { cloudflareAdapter } from 'lacis/adapters'
import { routes } from './routes/_manifest.js'
export default cloudflareAdapter.createHandler({ routes })

Sur Cloudflare, le contexte runtime vit sous req.platform :

  • req.platform.env — vos bindings Worker (KV, D1, R2, Queues, secrets…)
  • req.platform.ctx — l’ExecutionContext (ex. ctx.waitUntil)
  • req.platform.cf — les IncomingRequestCfProperties de la requête
// routes/users/[id]/index.ts
import type { Request, Response } from 'lacis'
export async function GET(req: Request, res: Response) {
const user = await req.platform.env.MY_KV.get(req.params!.id)
res.json({ user, country: req.platform.cf.country })
}

req.platform est vide par défaut et augmenté par déclaration merging. Le template Cloudflare génère un env.d.ts pour accéder aux bindings sans as any :

// env.d.ts
/// <reference types="@cloudflare/workers-types" />
interface Env {
MY_KV: KVNamespace
MY_DB: D1Database
// …vos bindings
}
declare module 'lacis' {
interface PlatformContext {
env: Env
ctx: ExecutionContext
cf: IncomingRequestCfProperties
}
}
name = "my-app"
main = "worker.ts"
compatibility_date = "2024-09-23"
# [[kv_namespaces]]
# binding = "MY_KV"
# id = "..."
  1. Ajoutez lacis build à votre script de build :

    {
    "scripts": {
    "build": "lacis build",
    "deploy": "wrangler deploy"
    }
    }
  2. Générez le manifest et déployez :

    Fenêtre de terminal
    npm run build
    wrangler deploy

lacis dev détecte wrangler.toml et lance wrangler dev après avoir généré le manifest.

  • SSE / initSSE() : comme Bun, Cloudflare décide du streaming de façon synchrone — appelez res.initSSE() avant le premier await du handler.
  • IP client : req.connection.remoteAddress est renseignée depuis l’en-tête cf-connecting-ip.
  • defaultHeaders est supporté (passez-le dans le ServerlessConfig).
export default cloudflareAdapter.createHandler({
routes,
maxBodySize: 5_000_000,
defaultHeaders: { 'X-Powered-By': 'Lacis' },
cors: { origin: 'https://myapp.com', credentials: true },
})