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 direct — res.stream() et les SSE émettent les chunks au fur et à mesure plutôt que de bufferiser toute la réponse.
Différences avec les autres adaptateurs
Section intitulée « Différences avec les autres adaptateurs »| Node / Bun | Vercel / Netlify | Cloudflare | |
|---|---|---|---|
| Config | chaîne / ServerlessConfig | ServerlessConfig | ServerlessConfig |
| Découverte des routes | scan / manifest | Manifest pré-compilé | Manifest pré-compilé |
| Streaming | direct | bufferisé | direct |
req.platform | {} | {} | { env, ctx, cf } |
Structure du projet
Section intitulée « Structure du projet »my-app/├── routes/│ ├── index.ts│ └── users/│ └── [id]/│ └── index.ts├── worker.ts├── env.d.ts└── wrangler.tomlPoint d’entrée du Worker
Section intitulée « Point d’entrée du Worker »// worker.tsimport { cloudflareAdapter } from 'lacis/adapters'import { routes } from './routes/_manifest.js'
export default cloudflareAdapter.createHandler({ routes })Accéder aux bindings : req.platform
Section intitulée « Accéder aux bindings : req.platform »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— lesIncomingRequestCfPropertiesde la requête
// routes/users/[id]/index.tsimport 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 })}Typer req.platform avec env.d.ts
Section intitulée « Typer req.platform avec env.d.ts »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 }}wrangler.toml
Section intitulée « wrangler.toml »name = "my-app"main = "worker.ts"compatibility_date = "2024-09-23"
# [[kv_namespaces]]# binding = "MY_KV"# id = "..."Déploiement
Section intitulée « Déploiement »-
Ajoutez
lacis buildà votre script de build :{"scripts": {"build": "lacis build","deploy": "wrangler deploy"}} -
Générez le manifest et déployez :
Fenêtre de terminal npm run buildwrangler 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 — appelezres.initSSE()avant le premierawaitdu handler. - IP client :
req.connection.remoteAddressest renseignée depuis l’en-têtecf-connecting-ip. defaultHeadersest supporté (passez-le dans leServerlessConfig).
Config optionnelle
Section intitulée « Config optionnelle »export default cloudflareAdapter.createHandler({ routes, maxBodySize: 5_000_000, defaultHeaders: { 'X-Powered-By': 'Lacis' }, cors: { origin: 'https://myapp.com', credentials: true },})