用途
Composition Root 用于为 Cloudflare Workers 组织依赖注入:在一个组合根(composition root)中,从运行时能力构建应用依赖,并按依赖所属的生命周期进行装配。它要解决的问题是:避免 Env 或原始绑定(KV、R2、D1、Durable Objects、Queues、service bindings、Workflows 等)渗入应用内部代码。内层代码只接收端口(port),永远不接收 Env、原始绑定、框架服务定位器或绑定名称。
主要能力
文档给出的核心结构是一条依赖装配链:
Cloudflare 入口点 → tracer + 解析后的配置 → 绑定适配器 → 精确的服务依赖 → 应用服务 → 协议投影
同时明确了各角色的职责:
- 组合根:按所属作用域构建适配器与服务,并提供给可运行的入口点。
- 入口适配器:解析外部输入、建立调用上下文、用传入的依赖调用服务,并投影其结果。
- 绑定适配器:用 KV、R2、D1、Durable Objects、Queues、service bindings、Workflows 或其他外部能力实现应用自有的端口。
- 应用服务:负责单个用例的时序、回退、重试与尽力而为策略。
- 领域模块:负责纯值与不变量。
- 端口:精确命名消费者所需的能力,不镜像 Cloudflare API。
原始平台值只能存在于组合根和绑定适配器中;绑定适配器只接受最小的平台能力,而不是整个 Env。
使用方式
文档给出五步流程:
-
梳理边界:检查仓库说明与受影响的部分,包括 TanStack Start 的 src/server.ts、请求上下文类型、中间件顺序与服务端函数;Worker、WorkerEntrypoint、Durable Object、Workflow、队列与定时入口点;Env 声明及目标绑定的每一处使用;tracer 创建、关联、错误上报与分离工作的归属;现有服务、适配器、端口、测试与架构检查。对每个受影响行为,从入口点追踪到副作用和调用方可见结果;重构时先记录当前错误、重试、回退、序列化与追踪行为。
-
设计应用自有的依赖:从消费者需求定义契约,使用领域输入与已解析输出,而不是原始 key、字符串、请求对象或绑定选项;只暴露真实调用方需要的操作;每个服务的依赖对象保持精确,不创建共享大杂烩对象,也不把 Env 重命名为 Dependencies;把平台序列化、键空间、分页令牌、TTL、元数据与输出解析放进绑定适配器;让应用服务掌握策略;只在确有需要创建 span 的服务与适配器中注入 Tracer;仅当组合后作用域真正动态时才添加应用自有工厂(工厂不得暴露 Env 或原始绑定);显式选择生命周期——不可变适配器与服务在并发调用下安全时可复用,持有请求作用域运行时对象或可变调用状态时按调用构造,分离工作交给显式所有者(如窄接口的后台任务端口),不要把 ExecutionContext 泄漏进内层。
-
新建或重构:新服务分支中,针对端口实现应用服务,不导入 TanStack 或 Cloudflare 运行时类型;每个外部角色实现一个绑定适配器,技术相关实现用明确名称(如 WorkersKvDocumentStore);协议关注点留在 HTTP、RPC、队列、Workflow 或定时适配器中;把组合好的服务提供给服务该用例的每个可运行入口点。重构分支中,先在当前公共接缝处用测试保留调用方可见行为;从直接消费者已使用的操作定义端口;在改策略前把现有原始绑定放到适配器之后;用端口替换直接消费者的原始依赖;逐层把适配器构造向外移动,中间层可以传递类型化端口,但不能把端口与原始绑定同时保留为永久设计;拆分混合模块——策略移到应用服务、平台机制移到适配器、协议映射留在入口点;在最后的调用方迁移后,移除过时的 Env 参数、工厂、泛型包装、重复的解析器/键构造器与兼容重载;不要仅为了对称而把重构扩大到无关绑定。
-
组装每个运行时表面:在每个组合根按顺序执行——解析配置与入口点 props;创建或获取 tracer;在调用被追踪工作前建立关联;用适配器包装原始绑定(需要时注入 tracer);组装精确的服务依赖;通过薄协议适配器调用服务;把结果与安全错误映射到外部契约。对 TanStack Start:在 src/server.ts 中用一个工厂(如 createAppDeps(env, ctx))为每次 fetch、队列与定时调用构建依赖图;把它作为请求上下文传给 Start handler,并通过 Register 声明其类型;服务端函数与中间件从 context.deps 读取精确能力,绝不读取 env 或绑定名;注入根追踪中间件所用的 tracer,而不是在应用更深处创建无关 tracer。按依赖生命周期选择组合根,而不是按构造函数或 handler 名称;在多个可运行入口点间复用其依赖工厂,而不是在每个路由或 SDK 回调内构建独立依赖图。
-
验证接缝:通过生产接缝验证——用实现真实端口的小型记录型假对象验证应用服务行为;在代表性本地 Cloudflare 运行时验证绑定适配器的序列化、解析与失败;验证入口点组装与外部结果/错误投影;验证 span 名称、关联、安全属性与分离工作归属;执行类型检查、聚焦测试、架构检查与仓库要求的验证。用项目的绑定名与运行时类型搜索泄漏,例如:
rg 'Env|KVNamespace|R2Bucket|D1Database|DurableObjectNamespace|ExecutionContext' src
对每一处匹配分类:组合根、绑定适配器、不可避免的框架声明,或违规;同时搜索路由、服务、领域与能力模块中直接访问 context.env 与绑定名的情况。
适用场景
适用于 Cloudflare Workers 及相关运行时表面的项目,尤其是需要在多个入口点(HTTP、RPC、队列、Workflow、定时、Durable Object)之间共享同一套应用服务与依赖装配,或需要把 Env 与原始绑定从业务代码中移除、把平台机制收敛到适配器的场景。文档也给出了与 TanStack Start 结合的具体落地方式。
限制
本文为规范/技能说明类文档,未提供许可证、定价、安装命令、包管理器或版本号等信息,这些内容暂未提供。文中提到的 ../typescript-standards/SKILL.md 与 EXAMPLES.md 为配套参考文件,其具体内容未在本文中给出。适用范围聚焦于 Cloudflare Workers 与 TanStack Start,其他框架或运行时的做法暂未提供。