ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

@vinext/cloudflare 完全指南:为 vinext 接入 Workers KV、CDN 缓存、Response Store 与 Cloudflare Images

@vinext/cloudflare 完全指南:为 vinext 接入 Workers KV、CDN 缓存、Response Store 与 Cloudflare Images 后端Web框架SSR【免费下载链接】vinextVite plugin that reimplements the Next.js API surface — deploy anywhere项目地址https://gitcode.com/gh_mirrors/vi/vinext点击查看免费下载vinext/cloudflare 是 vinextVite plugin 重新实现 Next.js API 的部署方案在 Cloudflare Workers 上的官方配套包提供 KV 数据缓存、Workers Cache CDN 缓存、Workers Response Store 与 Cloudflare Images 四类运行时适配器以及一条vinext-cloudflare deploy部署 CLI。本文以 packages/cloudflare/README.md 为主体结合 packages/cloudflare/src 下的源码与 examples/response-store-demo 示例工程完整讲解每个适配器的配置方式、底层实现原理与生产级部署流程。读完你可以为任意 vinext 项目选配缓存后端、在 Vite 配置中声明适配器、并掌握含 CDN 预热的双阶段部署。一、包定位vinext 的 Cloudflare 专属运行时适配层在 vinext 的架构里核心包负责把 Next.js 的页面渲染、ISR、next/image等能力重现在任意平台上而“缓存存哪里、图片怎么变换”这类平台强相关的能力由适配器adapter完成。vinext/cloudflare 正是这一层它不参与业务渲染而是把 vinext 的数据缓存data cache、页面级缓存page-level cache和图片优化接到 Cloudflare 的原生基础设施上。从 package.json 可以看到包的产物通过exports字段暴露了两个子路径族./cache/*→dist/cache/*包含全部缓存适配器./images/*→dist/images/*包含图片优化器。同时它声明了bin字段vinext/cloudflare与vinext-cloudflare均指向dist/cli.js提供deploy子命令用于把构建产物直接部署到 Cloudflare Workers。包依赖cloudflare/workers-response-storeResponse Store 的实现peer 依赖vinext要求 Node.js 22。该包当前共提供四个核心适配器对应 README 的四条主线适配器导入路径职责kvDataAdapter()vinext/cloudflare/cache/kv-data-adapter用 Workers KV namespace 支撑数据缓存fetch、use cache、unstable_cachecdnAdapter()vinext/cloudflare/cache/cdn-adapter用 Cloudflare Workers Cache 承接页面级 ISR 的对外提供与再验证responseStoreAdapter()vinext/cloudflare/cache/response-store-adapter用 Workers Response Store 同时承担响应缓存与数据缓存imagesOptimizer()vinext/cloudflare/images/images-optimizer用 Cloudflare Images binding 支撑next/image的图片变换二、快速上手在 Vite 配置中声明适配器所有适配器都是“配置期构造器”它们可以在vite.config.ts中安全调用返回一个可序列化的描述符真正的运行时实例由生成的virtual:vinext-cache-adapters注册表在首个请求时按需实例化。以 KV 数据缓存加 Cloudflare Images 的典型组合为例// vite.config.ts import { kvDataAdapter } from vinext/cloudflare/cache/kv-data-adapter; import { imagesOptimizer } from vinext/cloudflare/images/images-optimizer; export default defineConfig({ plugins: [ vinext({ cache: { data: kvDataAdapter(), // KV-backed data cache (binding: VINEXT_KV_CACHE) }, images: { optimizer: imagesOptimizer() }, // Cloudflare Images binding: IMAGES }), cloudflare(), ], });配合cloudflare()插件vite-plugin-cloudflare一起使用。这里kvDataAdapter()对应数据缓存fetch缓存、use cache、unstable_cache的统一底层imagesOptimizer()对应图片变换。为什么必须要求适配器是“配置期可序列化”的看 images-optimizer.ts 的实现就明白了它只做两件事——校验binding参数类型然后返回{ adapter: fileURLToPath(import.meta.resolve(./images-optimizer.runtime.js)), options }。fileURLToPath(import.meta.resolve(...))把运行时工厂的绝对路径解析出来交给构建流程配置期绝不实例化优化器、也绝不读取 binding因此 Vite 配置可以被安全地执行和序列化。kvDataAdapter、cdnAdapter、responseStoreAdapter全部遵循同一模式。三、数据缓存kvDataAdapter 与 KV 后端3.1 前置条件在 Wrangler 配置中声明 KV namespacekvDataAdapter()需要一个已存在的 KV namespace。运行时工厂在构造KVCacheHandler时从 Worker 的env读取绑定默认名VINEXT_KV_CACHE找不到会直接抛错并提示补全配置。对应的 kv-data-adapter.ts 给出了 Wrangler 配置写法// wrangler.jsonc { kv_namespaces: [ { binding: VINEXT_KV_CACHE, id: your-kv-namespace-id } ] }3.2 选项参数一览kvDataAdapter(options?)接受以下可选参数定义见 kv-data-adapter.ts默认值均有源码注释佐证参数类型默认值说明bindingstringVINEXT_KV_CACHEWorkerenv上的 KV namespace 绑定名appPrefixstring无缓存键的命名空间前缀用于在一个 KV namespace 中隔离多个应用ttlSecondsnumber259200030 天KVexpirationTtl即条目在 KV 中的物理存储期限tagCacheTtlMsnumber5000进程内 tag 失效缓存in-memory tag-invalidation cache的 TTL毫秒entryCacheTtlSecondsnumber不设置沿用 KV 默认 60s条目读取时的 KVcacheTtl让某个 colo 可以命中本地缓存而不用每次都回中心存储其中binding若传了非字符串会抛出TypeError源码第 48-50 行有显式校验。3.3 底层原理KVCacheHandler 如何工作kvDataAdapter()返回的描述符指向 kv-data-adapter.runtime.ts其默认导出是createKvDataCacheAdapter工厂请求到达时从env[binding]读取 KV namespace构造KVCacheHandler实例。该类实现了 vinext 的CacheHandler接口核心逻辑值得展开序列化策略。KV 只能存字符串而缓存值里的rscDataAPP_PAGE、bodyAPP_ROUTE、bufferIMAGE都是ArrayBuffer。运行时先把这些字段用 base64 编码serializeForJSON读回时再做安全解码恢复restoreArrayBuffers。任何 base64 校验失败都视为损坏条目静默当作 miss 并后台删除绝不把脏数据交给上层对应源码第 278-289 行与base64ToArrayBuffer的字母表预校验。TTL 与“陈旧”解耦。这是最容易踩坑的设计KV 的物理过期expirationTtl与“什么时候该后台重新生成”revalidateAt是两回事。revalidateAt存进 JSON 而非依赖 KV 驱逐——如果让 KV TTL 跟着 revalidate 窗口走一个revalidate5的页面在 50 秒无流量后就会被物理驱逐下一次请求被迫阻塞等待全新渲染而不是立刻返回 stale 内容。因此运行时固定把条目保留 30 天ttlSeconds默认值活跃页面由后台再验证不断覆盖键对应源码第 505-519 行注释。基于 tag 的失效与路径失效。revalidateTag()为每个合法 tag 写一个“失效标记”时间戳键revalidatePath()走的是revalidateByPathPrefix()——它利用 KVlist的 metadata 字段发现 entry 携带的 tags每个 entry 写入时把 tags 序列化进 KV metadata上限 1024 字节超出则优雅降级跳过从而把前缀失效的复杂度降到 O(list_pages) 而不是 O(entries × get)。标签校验规则也很严格长度上限 256、拒绝控制字符与:因为:是内部 key 分隔符放行用户 tag 会造成 key 歧义、允许/revalidatePath依赖/posts/hello这类路径 tag。软标签与批量读取优化。get()里“soft tags”读之前就已知的 tag和 entry 自带 tags 被分批读取批量get()受 Cloudflare 限制每次最多 100 个键运行时按 100 分块并发KV_BULK_GET_LIMIT。进程内_tagCache用 5 秒 TTL 兜底避免高频请求重复读同一批标记同时用单调递增的order防止并发读回写旧值源码第 381-392 行。entryCacheTtlSeconds只作用于 entry 读取、绝不作用于 tag 标记——因为revalidateTag()写入的标记若被某个 colo 长时间缓存发布后的失效会被该 colo 掩盖失效窗口始终被控制在tagCacheTtlMs KV 默认 60s 以内。从测试与 shim 的角度看这类 handler 被注册进vinext/shims/cache的缓存接口可参考 packages/vinext/src/shims/cache.ts 与 cache-adapters-virtual.ts 的注册机制。四、页面级 CDN 缓存cdnAdapter 与 Workers Cache4.1 双入口设计缓存命中不启动应用cdnAdapter()是可选适配器负责把页面级 ISR 的对外提供serving与再验证revalidation交给 Cloudflare Workers Cache。它与数据缓存的关键区别在 cdn-adapter.ts 的注释里说得很清楚数据缓存把条目存进持久存储、自己判定 HIT/STALE而 CDN 适配器把“对外提供”委托给 Workers Cache 上的一个命名入口。配置后Cloudflare 构建会产出两个 Worker entrypoint默认入口运行 middleware 与请求期路由缓存关闭VinextCachedResponse懒加载渲染阶段render stageWorkers Cache 开启。这些设置会被写入生成的dist/server/wrangler.json。因此 README 特别强调不要在源配置source config的默认入口上手动开启 Workers Cache——生成的配置才是权威来源。同时生成配置还会声明“版本元数据绑定”version metadata binding供分阶段预热staged warmup使用。import { cdnAdapter } from vinext/cloudflare/cache/cdn-adapter; vinext({ cache: { cdn: cdnAdapter() } });4.2 版本元数据绑定与响应入口生成的版本元数据绑定用于让 staged warmup 证明每一个 discovery、probe、fill 请求都真实命中了已上传的 Worker 版本。默认绑定名是CF_VERSION_METADATADEFAULT_CDN_VERSION_METADATA_BINDING只有部署确实需要自定义绑定名时才给cdnAdapter()传versionMetadataBinding且必须是非空字符串否则抛TypeError见 cdn-adapter.ts。适配器的output字段源码第 52-80 行揭示了双入口的落法它只对virtual:cloudflare/worker-entry做transformHostEntry注入追加export { VinextCachedResponse, VinextUncachedResponse } from worker-entryfinalizeBuildOutput负责在构建收尾时把 Workers Cache 与版本元数据绑定写进生成的 Wrangler 配置并以multi-stage类型参与构建。VinextUncachedResponse保持缓存关闭让 bypass 与 probe 渲染不经过缓存网关。响应入口会把完整传输身份transport identity哈希进 Workers Cache URL——这是独立于 zone Cache Rules 的。也就是说即使 zone 层面配置了缓存的 key 规则不同的 query 与表示变体representation variants在 Workers Cache 中也不会互相碰撞README 与源码第 31-33 行注释相互印证。4.3 CDN 预热与两阶段部署cdnAdapter()通常与部署期的--experimental-warm-cdn-cache配合使用默认流程每个被准入admitted的身份只发一个最终的 fill 请求追加--warm-cdn-certify开启一个可选的头-only 二次请求要求每一个计划内的条目在提升promotion前都必须被证明可复用。关于这些 CLI 参数与 Workers Cache 的 tiered caching 行为详见第七节的完整参数表。五、统一缓存后端responseStoreAdapter 与 Workers Response StoreresponseStoreAdapter()是二合一方案它同时替换cdnAdapter()和kvDataAdapter()用 Workers Response Store 同时承担响应缓存与数据缓存。定义见 response-store-adapter.ts它返回{ cdn: {...}, data: {...} }两个描述符分别挂在vinext()的cache.cdn与cache.data上。5.1 模式一service-binding默认独立缓存 Worker默认模式把存储放进独立的缓存 Worker应用 Worker 通过RESPONSE_STOREservice binding 访问它。vinext init会生成两份并列的源配置wrangler.jsonc应用 Worker 配置wrangler.response-store.jsonc缓存 Worker 配置。后者直接指向已安装的cloudflare/workers-response-store实现main为./node_modules/cloudflare/workers-response-store/dist/service.js并拥有自己的 R2 bucket、SQLite Durable Object、Worker 名称与缓存设置。示例见 examples/response-store-demo/wrangler.response-store.jsoncR2 bucketCACHE_BODIES、SQLite Durable ObjectCacheMetadata、cache-enabled 入口ResponseStoreBinding都在这一份配置里。对应的应用配置 examples/response-store-demo/wrangler.jsonc 则通过services字段把RESPONSE_STOREbinding 指向名为response-store-demo-response-store的缓存 Worker并声明version_metadataCF_VERSION_METADATA。两个 Worker 刻意分开部署缓存 Worker 的包或配置变更时先部署它然后正常部署应用npx wrangler deploy --config wrangler.response-store.jsonc npx vinext/cloudflare deploy需要强调的是vinext-cloudflare deploy永远不会创建、改写或部署 Response Store WorkerREADME 原文承诺也与 CLI 的实现一致——deploy 命令只处理应用本身。要调整缓存 Worker 名称、R2 bucket 名称直接编辑wrangler.response-store.jsonc同时保持应用配置里的 service binding 与缓存 Worker 名称对齐。5.2 元数据分片shards元数据分片metadata sharding是可选能力两种部署模式都支持vinext({ cache: responseStoreAdapter({ shards: 16 }) });开启后键keys仍然固定钉在同一个分片上保证单键一致性而 tag/path 的变更mutations会扇出到所有分片。不传shards则保留原来的单一元数据 Durable Object。源码对shards有严格校验必须是大于 1 的安全整数否则抛TypeErrorresponse-store-adapter.ts。5.3 位置提示locationHint要让新建的元数据 Durable Object 靠近稳定的流量与 R2 区域可以传 Cloudflare location hintvinext({ cache: responseStoreAdapter({ locationHint: weur }) });合法值由源码中的RESPONSE_STORE_LOCATION_HINTS表限定response-store-adapter.tsafr、apac、apac-ne、apac-se、eeur、enam、me、oc、sam、weur、wnam。传入不支持的字符串同样抛TypeError。注意事项README 原话务必遵守hint 是 best-effort且只影响每个 Durable Object首次创建的位置修改 hint不会迁移已存在的对象应把修改 hint 视为一次“缓存冷却”cache-cold的部署变更并让 hint 与 R2 bucket 所在区域保持一致。5.4 模式二self-contained自包含模式如果希望把存储与缓存入口和应用一起部署不拆分第二个 Worker使用自包含模式import { responseStoreAdapter } from vinext/cloudflare/cache/response-store-adapter; vinext({ cache: responseStoreAdapter({ mode: self-contained }) });在此模式下vinext init把所需的 R2、SQLite Durable Object、Workers Cache 入口和版本元数据配置全部放进单个wrangler.jsonc无需第二份 Wrangler 配置。示例可见 examples/response-store-demo/wrangler.self-contained.jsonc一个文件内同时包含 assets、cache.enabled、exportsdefault /ResponseStoreBinding/CacheMetadata、r2_buckets、durable_objects与version_metadata。源码层面mode决定运行时工厂文件response-store-adapter.self-contained.worker.js或response-store-adapter.service-binding.worker.js以及注入的入口集合——自包含模式导出CacheMetadata, ResponseStoreBinding, ResponseStoreRevalidator而 service-binding 模式只导出ResponseStoreClient, ResponseStoreRevalidatorresponse-store-adapter.ts。mode传未知值会抛Error源码第 47-49 行。六、图片优化imagesOptimizer 与 Cloudflare ImagesimagesOptimizer()把next/image的变换请求/_next/image接到 Cloudflare Images binding在边缘完成 resize、格式协商AVIF/WebP与质量变换——无需自定义 Worker 入口images-optimizer.ts 的注释明确写了这一点。用法与 KV 数据缓存组合的完整示例已在第二节给出import { imagesOptimizer } from vinext/cloudflare/images/images-optimizer; vinext({ images: { optimizer: imagesOptimizer() } });唯一可配置项是bindingCloudflare Images binding 在 Workerenv上的名字默认IMAGES。其运行时实现位于 images-optimizer.runtime.ts同样遵循“配置期构造器返回可序列化描述符 运行时工厂按需实例化”的模式binding非字符串时抛TypeError。七、部署vinext-cloudflare deploy 全参数解析7.1 基本用法项目构建完成后用包自带的 CLI 一键部署npx vinext/cloudflare deployVite 环境下还可以用vpx vinext/cloudflare deploy # 或运行本地安装的 bin vp exec vinext-cloudflare deploy命令入口在 cli.ts解析deploy子命令并把全部参数透传给deploy()来自 deploy.ts。--version/-v打印vinext-cloudflare vversion--help/-h打印完整帮助文案见 deploy-help.ts。7.2 基础选项选项说明--preview部署到 preview 环境等价于--env preview--env name使用 wrangler 的env.name环境部署--name name自定义 Worker 名称默认取自 package.json--config pathWrangler 配置路径默认自动发现 wrangler.jsonc / json / toml--skip-build跳过构建直接使用现有dist/--dry-run只校验配置不构建也不部署--verbose打印内部 Wrangler 命令的原始输出--no-promote上传 Worker 版本但不把流量提升到 100%--prerender-all构建后预渲染已发现的路由--prerender-concurrency count并行预渲染的最大路由数7.3 CDN 预热选项配合 cdnAdapter选项说明--experimental-warm-cdn-cache上传 Worker 版本 → 通过生产 URL 预热构建发现的路由 → 再提升experimental--warm-cdn-target origin显式指定 HTTPS origin 用于 discovery、probing 与 warming覆盖从 Wrangler 输出推断的 URL--warm-cdn-concurrency count并行 CDN 预热请求数默认 25--warm-cdn-timeout ms单请求预热超时默认 10000--warm-cdn-retries n单请求失败重试默认 1staged 版本传播场景默认 60--warm-cdn-discovery-timeout msstaged 路径发现总时限默认 120000--warm-cdn-discovery-retries n可选staged 路径发现重试上限默认由发现时限推导--warm-cdn-probe-timeout ms缓存能力探测无进展时的中止时限默认 120000--warm-cdn-probe-retries n缓存能力探测重试默认 2--warm-cdn-certify配合--experimental-warm-cdn-cache用 header-only 请求重放已预热条目要求每个计划条目在提升前都证明可复用--warm-cdn-readiness-timeout msstaged 就绪检查显式总时限默认 120000--warm-cdn-readiness-retries nstaged 就绪重试默认 60--warm-cdn-readiness-probes count预热前需要的连续成功就绪探测次数默认 6--warm-cdn-readiness-probe-delay ms就绪探测间隔默认 1000--dangerously-promote-on-cdn-warm-error普通 staged 预热无法验证时仍然提升绝不绕过--warm-cdn-certify--warm-cdn-promotion-delay ms预热完成到提升之间的延迟默认 15000--warm-cdn-include-fallbacks额外预热 PPR fallback-shell 占位路径7.4 流量感知预热experimental针对流量选择预热路由的选项组选项说明--experimental-traffic-aware-warm-cache从流量分析中选择 CDN 预热路由--traffic-aware-coverage pct流量覆盖目标百分比 0-100默认 90--traffic-aware-limit count选中路由硬上限默认 1000--traffic-aware-window hoursAnalytics 回看窗口默认 24 小时流量感知预热使用 Cloudflare zone analytics 挑选流量最高的路由再喂进与--experimental-warm-cdn-cache相同的 staged 预热流程。它要求自定义域名以及具备Zone Analytics 读取权限的CLOUDFLARE_API_TOKEN。另外Workers Cache 自动启用 tiered caching因此预热过的条目在缓存传播后可以被预热请求所达数据中心之外的边缘复用但部署不会等待每个边缘位置都填满。7.5 常用组合示例# 构建并部署到生产 npx vinext/cloudflare deploy # Vite 环境 vpx vinext/cloudflare deploy # 部署到 preview / 指定环境 vinext-cloudflare deploy --preview vinext-cloudflare deploy --env staging # 使用生成的 Wrangler 配置部署cdnAdapter 场景 vinext-cloudflare deploy --config dist/server/wrangler.json # 只校验不部署 vinext-cloudflare deploy --dry-run # 上传版本但不改流量 vinext-cloudflare deploy --no-promote # 两阶段 CDN 预热部署 vinext-cloudflare deploy --experimental-warm-cdn-cache vinext-cloudflare deploy --experimental-warm-cdn-cache --warm-cdn-target https://example.com # 流量感知预热 vinext-cloudflare deploy --experimental-traffic-aware-warm-cache --traffic-aware-coverage 95八、选型建议与示例工程8.1 三个缓存方案怎么选从 README 与源码可以归纳出清晰的取舍逻辑kvDataAdapter轻量起点。一个 KV namespace 即可支撑数据缓存适合缓存量可控、不需要页面级 CDN 网关的场景若要页面级 ISR 对外缓存需叠加cdnAdapter()。cdnAdapter页面级 ISR 的 CDN 化提供。与kvDataAdapter互补而非替代配合--experimental-warm-cdn-cache做缓存预热与版本化部署。responseStoreAdapter替代前两者README 原文“replaces bothcdnAdapter()andkvDataAdapter()”。一份配置同时解决数据缓存与响应缓存有独立缓存 Workerservice-binding与单 Workerself-contained两种形态并支持分片与区域提示。适合希望减少运维面、把缓存基础设施交给 Cloudflare Response Store 的项目。8.2 参考示例response-store-demo仓库中的 examples/response-store-demo 是围绕 Response Store 三种形态的完整示例工程包含README.md与四份 Wrangler 配置可作为实操蓝本wrangler.jsonc应用 Workerservice-binding 模式RESPONSE_STOREservice binding 指向独立缓存 Workerversion_metadata绑定CF_VERSION_METADATAwrangler.response-store.jsonc缓存 Worker持有 R2 bucket、SQLite Durable Object 与缓存入口wrangler.self-contained.jsoncself-contained 单文件配置wrangler.kv.jsoncKV 数据缓存形态的参考配置。vinext/cloudflare的测试脚本package.json 的test也以VINEXT_RESPONSE_STORE_MODEself-contained与VINEXT_RESPONSE_STORE_LOCATION_HINTweur/wnam组合实际构建 response-store-demo验证两种模式与位置提示在真实构建链路中的行为——需要调试或验证配置时可以直接复用这条命令。结语vinext/cloudflare 把 vinext 的缓存与图片能力完整地映射到 Cloudflare Workers 的原生基础设施上KV 数据缓存、Workers Cache 的 CDN 化页面缓存、Response Store 的统一缓存后端以及 Cloudflare Images 的图片变换全部通过声明式适配器接入vinext()插件并配有覆盖基础部署、环境部署、CDN 预热与流量感知预热的单命令 CLI。无论是从零起步的 KV 方案还是追求统一缓存与最小运维面的 Response Store 方案本文给出的配置示例、参数表与源码级原理分析都可以直接指导落地。下一步建议对照 examples/response-store-demo 的配置跑通一次vinext init与npx vinext/cloudflare deploy再按需引入cdnAdapter与预热参数做生产优化。赞分享后端Web框架SSR【免费下载链接】vinextVite plugin that reimplements the Next.js API surface — deploy anywhere项目地址https://gitcode.com/gh_mirrors/vi/vinext点击查看免费下载相关推荐Android-DFU-Library与Kotlin集成教程现代化蓝牙固件更新方案Android DFU Library与Kotlin集成教程现代化蓝牙固件更新方案 想要为你的Android应用添加蓝牙设备固件更新功能吗Android D后端Web框架SSRruflo SONA Learning Optimizer基于 LoRA 与 EWC 的 Agent 自优化学习技能全解析ruflo SONA Learning Optimizer基于 LoRA 与 EWC 的 Agent 自优化学习技能全解析 本文围绕 ruflo 仓库中的后端Web框架SSR解锁暗黑2新姿势d2s-editor编辑器10大超实用功能详解解锁暗黑2新姿势d2s editor编辑器10大超实用功能详解 你是否曾为暗黑破坏神2中刷不到心仪装备而烦恼是否想体验不同角色build却苦于重新练级现在后端Web框架SSR上一篇Flipper Zero Unleashed固件FAP应用架构深度解析与技术实现下一篇SurfSense 前端设计工程指南基于 Emil Kowalski 设计哲学的 UI 打磨、动画决策与细节实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表