Workerd 运行时 API 实战指南:从 Worker 入口、Web 平台 API 到 CLI 与 Wrangler 集成
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
本篇指南以 Cloudflare Deploy 技能库(skills/.curated/cloudflare-deploy)中的 Workerd API 文档 为骨架,系统讲解 Workerd 运行时的 Worker 代码模型(ES Modules / Service Worker / Durable Objects / 服务间 RPC)、内置 Web 平台 API 全集、CLI 命令以及 Wrangler 集成方式。读完本文,你将能直接编写可运行的 Workerd Worker 代码、为绑定生成 TypeScript 类型,并把本地开发、测试与生产部署串成一条完整链路。
一、背景:Workerd 是什么,以及 API 文档的适用范围
Workerd 是基于 V8 的 JS/Wasm 运行时,也是 Cloudflare Workers 的底层引擎。正如 Workerd 运行时总览 所述,它可以作为应用服务器、开发工具或 HTTP 反向代理使用,核心特性包括:基于标准的 Fetch API / Web Crypto / Streams / WebSocket、通过服务绑定实现"纳米服务"式本地调用、以及通过显式绑定实现能力安全(防止 SSRF)。
需要特别注意的是官方安全提醒:workerd 不是加固型沙箱,切勿运行不可信代码。它面向的是"本地/自托管部署你自己的代码"场景,Cloudflare 生产环境在其之上叠加了额外安全层。因此 cloudflare-deploy SKILL 给出的决策树是:95% 的用户应当直接使用 Wrangler(wrangler dev内部即调用 workerd),只有在自托管生产环境、嵌入 C++ 应用、自定义测试工具或调试 workerd 特有行为时才直接操作 workerd 二进制。
workerd 的整体架构以 Cap'n Proto 配置文件(workerd.capnp)为入口,向下展开为 Services(worker/网络/磁盘/外部端点)、Sockets(HTTP/HTTPS 监听)与 Extensions(全局能力)。本文聚焦其中的运行时 API 层:即 Worker 代码里能调用的所有入口与接口。
二、Worker 代码模型(JS/TS)
2.1 ES Modules(推荐入口)
Workerd 的 Worker 代码推荐使用 ES Modules 语法,通过export default导出多个具名处理器,每个处理器对应一种运行时事件。以下示例完整覆盖了全部入口(api.md 原文):
export default { async fetch(request, env, ctx) { const value = await env.KV.get("key"); // Bindings in env const response = await env.API.fetch(request); // Service binding ctx.waitUntil(logRequest(request)); // Background task return new Response("OK"); }, async adminApi(request, env, ctx) { /* Named entrypoint */ }, async queue(batch, env, ctx) { /* Queue consumer */ }, async scheduled(event, env, ctx) { /* Cron handler */ } };逐行拆解这段代码,就能理解 Workerd 运行时的核心参数约定:
fetch(request, env, ctx):HTTP 请求入口,是绝大多数 Worker 的主入口。request是标准Request对象,env承载所有绑定(KV、R2、服务绑定、环境变量等),ctx是ExecutionContext,提供waitUntil()用于后台任务、passThroughOnException()用于异常时回源。env.KV.get("key"):ES Modules 模式下所有绑定都挂在env上。这里的KV是在 workerd 配置(capnp 或 wrangler 配置)中声明的绑定名,代码中通过env.<绑定名>访问。而旧式 Service Worker 语法中绑定则作为全局变量存在(见 2.3)。env.API.fetch(request):服务绑定(Service Binding)。它让当前 Worker 能以本地调用的性能把请求转发给另一个 Worker 服务,是"纳米服务"架构的关键。ctx.waitUntil(logRequest(request)):把异步后台任务挂到请求生命周期上,响应返回后任务继续执行,不会阻塞响应——适合埋点、日志、缓存预热等场景。adminApi:具名入口(Named Entrypoint)。一个 Worker 可以导出多个入口,外部服务绑定可以通过entrypoint指定调用哪一个(配置方式见configuration.md 的服务绑定小节)。queue(batch, env, ctx):队列消费者入口,处理 Cloudflare Queues 投递的消息批次。scheduled(event, env, ctx):定时任务(Cron)入口,由调度事件触发。
2.2 TypeScript 类型:生成与手写
Workerd/Workers 生态强烈推荐为env定义类型,以获得完整的 IDE 提示与编译期检查。文档给出了两条路径:
路径一:由wrangler.toml自动生成(推荐)
wrangler types # Output: worker-configuration.d.ts该命令读取 wrangler 配置文件中的绑定声明,生成worker-configuration.d.ts。绑定变更后重新执行即可同步类型。关于类型生成的完整工作流(含安装 wrangler、查看生成结果等),可参考 bindings/api.md。
路径二:手动声明Env接口
interface Env { API: Fetcher; CACHE: KVNamespace; STORAGE: R2Bucket; ROOMS: DurableObjectNamespace; API_KEY: string; } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { return new Response(await env.CACHE.get("key")); } };注意不同类型绑定对应不同的 TS 类型:服务绑定是Fetcher,KV 是KVNamespace,R2 是R2Bucket,Durable Object 是DurableObjectNamespace,普通字符串变量(如API_KEY)直接是string。
环境搭建(两者都需要):
npm install -D @cloudflare/workers-types// tsconfig.json {"compilerOptions": {"types": ["@cloudflare/workers-types"]}}安装@cloudflare/workers-types并提供标准 Workers API 类型(Request、Response、ExecutionContext等),wrangler types则补充你项目特有的绑定类型。运行时类型与构建期类型的分工可参考 bindings/api.md 的类型来源表。
2.3 Service Worker 语法(旧式)
在 ES Modules 普及之前,Worker 使用 Service Worker 风格:通过addEventListener注册fetch事件,绑定直接作为全局变量访问:
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { const value = await KV.get("key"); // Bindings as globals return new Response("OK"); }这段代码展示了两个关键差异:事件回调里必须调用event.respondWith()交出响应权;且KV无需经过env,直接是全局对象。文档与patterns.md 最佳实践均明确建议优先使用 ES Modules,旧式语法仅用于维护遗留代码。
2.4 Durable Objects:有状态对象
Durable Objects(DO)是 Workerd 提供的单实例有状态对象,适合需要强一致状态、协调、实时场景。每个 DO 是一个导出类,构造器接收state(含持久化存储state.storage)与env:
export class Room { constructor(state, env) { this.state = state; this.env = env; } async fetch(request) { const url = new URL(request.url); if (url.pathname === "/increment") { const value = (await this.state.storage.get("counter")) || 0; await this.state.storage.put("counter", value + 1); return new Response(String(value + 1)); } return new Response("Not found", {status: 404}); } }state.storage.get/put提供持久化的键值存储,自动保证同一时刻同一 DO 实例只处理一个请求,避免并发写冲突。- DO 的实例通过
fetch()方法对外提供 HTTP 语义接口,调用方用env.ROOMS.idFromName(...)+get(id)获取 stub 后调用(详见 bindings/api.md 的 Durable Objects 调用示例)。 - 要在 workerd 配置中启用 DO,需要同时声明绑定
durableObjectNamespace、命名空间durableObjectNamespaces与存储位置durableObjectStorage,完整配置见configuration.md 的 DO 小节。
2.5 服务间 RPC:直接方法调用
除了通过fetch()转发请求,服务绑定还支持结构化 RPC——直接调用另一个服务的导出方法并拿到返回数据,无需序列化成 HTTP:
// Caller: env.AUTH.validateToken(token) returns structured data const user = await env.AUTH.validateToken(request.headers.get("Authorization")); // Callee: export methods that return data export default { async validateToken(token) { return {id: 123, name: "Alice"}; } };调用方把AUTH绑定当作一个本地对象直接调用方法,validateToken返回的{id, name}对象会作为结构化数据传回调用方。这是"纳米服务"架构的核心开发体验:服务之间以本地函数调用的方式协作,同时保留进程/隔离边界。
三、Web 平台 API 全景
Workerd 实现了与浏览器/Cloudflare Workers 对齐的 Web 平台 API 子集,开发者可直接复用 Web 生态的既有知识。文档将其分为以下几组:
| API 分组 | 包含接口 | 典型用途 |
|---|---|---|
| Fetch | fetch()、Request、Response、Headers | 发起到源站的子请求、构造响应 |
| Streams | ReadableStream、WritableStream、TransformStream,含字节流与 BYOB reader | 流式处理请求/响应体 |
| Web Crypto | crypto.subtle(encrypt/decrypt/sign/verify)、crypto.randomUUID()、crypto.getRandomValues() | 加密、签名、生成 UUID |
| Encoding | TextEncoder、TextDecoder、atob()、btoa() | 文本与二进制互转 |
| Web Standards | URL、URLSearchParams、Blob、File、FormData、WebSocket | URL 解析、表单处理、实时双向通信 |
3.1 服务端事件流(SSE)
SSE 是单向服务器推送的标准方案。workerd 中可以利用TransformStream构造一个流式响应体,配合text/event-stream内容类型即可:
// Server-side SSE const { readable, writable } = new TransformStream(); const writer = writable.getWriter(); writer.write(new TextEncoder().encode('data: Hello\n\n')); return new Response(readable, {headers: {'Content-Type': 'text/event-stream'}});注意 SSE 事件格式:每行以data:开头,事件之间以空行\n\n分隔。Response可以直接接收一个ReadableStream作为 body,这是流式接口互通性的直接体现。
3.2 HTMLRewriter:HTML 解析与转换
HTMLRewriter 是 Cloudflare 生态特有的流式 HTML 重写器,允许你像用 jQuery 选择器一样对 HTML 元素做变换,且以流式处理、开销极低。文档示例展示了链接改写 + 脚本移除的组合用法:
const response = await fetch('https://example.com'); return new HTMLRewriter() .on('a[href]', { element(el) { el.setAttribute('href', `/proxy?url=${encodeURIComponent(el.getAttribute('href'))}`); } }) .on('script', { element(el) { el.remove(); } }) .transform(response);.on(selector, handlers)注册元素处理器,element(el)回调中可读写属性、增删内容。- 典型场景包括 A/B 测试注入、分析脚本注入、链接重写(HTTPS 升级、代理包装)、敏感脚本移除等,详见 workers/api.md 的 HTMLRewriter 小节。
3.3 TCP Sockets(实验性)
connect()提供原始 TCP 能力,可绕过 HTTP 层直接与任意主机通信。文档给出一个极简的"手工 HTTP GET"示例:
const socket = await connect({ hostname: 'example.com', port: 80 }); const writer = socket.writable.getWriter(); await writer.write(new TextEncoder().encode('GET / HTTP/1.1\r\n\r\n')); const reader = socket.readable.getReader(); const { value } = await reader.read(); return new Response(value);socket.writable/socket.readable复用了 Streams 标准接口,写入请求、读取响应。需注意该能力在文档中标注为Experimental,正式使用前应确认当前 compatibility date 下的可用性。
3.4 Performance 与 Console
performance.now()、performance.timeOrigin:精确计时与基准测试。setTimeout()、setInterval()、queueMicrotask():定时与微任务调度。console.log()、console.error()、console.warn():结构化日志,配合 workerd 的--verbose与logging配置输出到标准输出/错误流(见configuration.md 日志小节)。
3.5 Node.js 兼容(nodejs_compatflag)
Workerd 提供了 Node.js 兼容层,通过 compatibility flag 开启后即可import部分node:模块:
import { Buffer } from 'node:buffer'; import { randomBytes } from 'node:crypto'; const buf = Buffer.from('Hello'); const random = randomBytes(16);可用模块:node:buffer、node:crypto、node:stream、node:util、node:events、node:assert、node:path、node:querystring、node:url。
不可用模块(涉及文件系统与网络服务端):node:fs、node:http、node:net、node:child_process。
这一点与 workerd 的安全模型一致:Worker 是无文件系统、无任意网络监听的运行时,需要文件或服务端能力时应改用 KV/R2/外部服务绑定。开启方式是在 capnp 配置的compatibilityFlags中加入"nodejs_compat"(见configuration.md 兼容性小节)。
四、CLI 命令
workerd 提供四个核心 CLI 子命令(api.md 原文):
workerd serve config.capnp [constantName] # Start server workerd serve config.capnp --socket-addr http=*:3000 --verbose workerd compile config.capnp constantName -o binary # Compile to binary workerd test config.capnp [--test-only=test.js] # Run tests逐个说明:
workerd serve:按 capnp 配置文件启动服务器。constantName是配置文件中定义的 Config 常量名(省略时取默认);--socket-addr http=*:3000覆盖某个 socket 的监听地址(*:3000表示监听所有网卡的 3000 端口);--verbose输出详细日志便于排错。workerd compile:把配置与嵌入的模块编译为单一二进制,-o binary指定输出路径。编译产物可直接执行,启动更快、部署更简单(生产部署首选,详见 patterns.md 的生产部署小节)。workerd test:运行配置中声明的测试模块,--test-only=test.js指定只跑某个测试文件。测试文件必须出现在配置的modules = [...]中。
配套的校验手段:capnp compile -I. config.capnp可对配置文件做语法与 schema 校验(见 gotchas.md 的构建问题);systemd 场景下还可用--socket-fd配合 socket 激活(见 patterns.md 的 systemd 示例)。
五、Wrangler 集成与开发工作流
对绝大多数开发者,日常开发不应直接操作 workerd 二进制,而是通过 Wrangler:
wrangler dev # Uses workerd internally wrangler types # Generate TypeScript types from wrangler.tomlwrangler dev内部启动 workerd 作为本地运行时,提供热重载与自动配置读取,是本地开发的首选。wrangler types与 2.2 节衔接:从 wrangler 配置生成类型定义。wrangler deploy则将同一份代码部署到 Cloudflare 生产环境。
在使用任何部署命令(wrangler deploy、wrangler pages deploy、npm run deploy)之前,SKILL.md 的认证章节 要求先执行npx wrangler whoami确认已登录;CI/CD 场景通过CLOUDFLARE_API_TOKEN环境变量认证。
若你需要绕过 HTTP 层做测试或嵌入,Wrangler 还提供了 Node.js 编程接口:startWorker以真实本地绑定启动 Worker 做集成测试,getPlatformProxy在 Node.js 中直接模拟绑定做单元测试(详见 wrangler/api.md);而 miniflare 则是在 workerd 沙箱上实现的本地模拟器,无需联网即可测试 KV、DO、R2、D1、WebSocket、Queues 等完整能力。
六、绑定如何进入env:与配置文件的衔接
API 文档中的env.KV、env.API、env.CACHE等绑定名并非凭空而来,而是由 workerd 的 capnp 配置声明。理解这一层,才能把 2.1 节的代码真正跑起来。下面是一个最小化的完整配置(configuration.md 基础结构):
using Workerd = import "/workerd/workerd.capnp"; const config :Workerd.Config = ( services = [(name = "main", worker = .mainWorker)], sockets = [(name = "http", address = "*:8080", http = (), service = "main")] ); const mainWorker :Workerd.Worker = ( modules = [(name = "index.js", esModule = embed "src/index.js")], compatibilityDate = "2024-01-15", bindings = [...] );其中bindings决定env上有哪些键:
- 基本类型:
(name = "API_KEY", text = "secret")映射为env.API_KEY(字符串);json会解析为对象;data为ArrayBuffer;fromEnvironment从系统环境变量取值。 - 服务绑定:
(name = "AUTH", service = "auth-worker")映射为env.AUTH(Fetcher),可配合entrypoint指向具名入口,props注入ctx.props。 - 存储绑定:
kvNamespace→KVNamespace、r2Bucket→R2Bucket、durableObjectNamespace→DurableObjectNamespace、memoryCache提供进程内缓存(可设maxKeys/maxValueSize上限)。 - 其他:
queue→ 队列、analyticsEngine→ 分析、cryptoKey→ 密钥绑定、wrapped→ 包装绑定。
因此调试"绑定找不到"类错误时,按 gotchas.md 的排查步骤 在代码里打印Object.keys(env)即可核对配置名与代码访问名是否一致。开发阶段还可以通过Remote Bindings让本地 workerd 直连生产环境的 KV/R2/DO 资源(需要accountId、namespaceId/bucketName/scriptName与 API Token,见 configuration.md 远程绑定章节)。
七、编写 Worker 代码的最佳实践与常见陷阱
结合 patterns.md 的最佳实践清单 与 gotchas.md 的排错指南,与 API 层直接相关的要点如下:
- 优先 ES Modules 而非 Service Worker 语法:绑定显式挂在
env上,类型安全且职责清晰,避免全局命名空间污染。 - 永远设置
compatibilityDate:这是 workerd 的功能门控。缺失会直接报 "Missing compatibility date";日期决定哪些 API 可用,升级日期前务必先本地测试。 - 后台任务用
ctx.waitUntil(),绝不await阻塞:把日志、埋点等放到waitUntil中,响应即刻返回(workers/api.md 亦强调此点)。 - 错误处理用 try/catch 包裹:捕获后记录
console.error并返回 5xx,避免未处理异常导致请求失败:
export default { async fetch(request, env, ctx) { try { return await handleRequest(request, env); } catch (error) { console.error("Request failed", error); return new Response("Internal Error", {status: 500}); } } };- 绑定类型别混用:DO 必须用
durableObjectNamespace而非service;JSON 要用json =而非text =(后者只是字符串,不会解析)。 - 模块名与导入路径必须一致:配置中
name = "index.js"使用简单名,embed用相对路径嵌入,二者不要混写成name = "src/index.js"。 - 安全基线:密钥用
fromEnvironment从环境变量注入而非硬编码在text绑定;网络访问收敛为allow = ["public"]或指定主机,避免"*";crypto 密钥默认extractable = false。 - 生产部署前把配置编译为二进制(
workerd compile),并固定 workerd 版本与 compatibility date 的匹配关系。
八、延伸阅读
- workerd/configuration.md:capnp 配置语法、services/sockets/bindings 全量字段、远程绑定与参数继承。
- workerd/patterns.md:多服务架构、反向代理、Hono/itty-router 框架集成、Docker/systemd 部署。
- workerd/gotchas.md:常见错误、性能问题、安全与兼容性陷阱的排查手册。
- workers/api.md:Workers 运行时 API 补充(Cache API、WebSocket Hibernation、D1 Session 等)。
- bindings/api.md:绑定类型对照表与类型生成工作流。
- miniflare/README.md 与 wrangler/api.md:本地测试与编程式启动 Worker 的方案。
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考