cloudflare-worker-base by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill cloudflare-worker-base生产环境测试 : cloudflare-worker-base-test (https://cloudflare-worker-base-test.webfonts.workers.dev) 最后更新 : 2026-01-20 状态 : 生产就绪 ✅ 最新版本 : hono@4.11.3, @cloudflare/vite-plugin@1.17.1, vite@7.3.1, wrangler@4.54.0 技能版本 : 3.1.0
近期更新 (2025-2026) :
wrangler deploy --x-autoconfig)WorkerEntrypoint 类实现服务绑定的 JavaScript 原生 RPC广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
# 1. 创建项目脚手架
npm create cloudflare@latest my-worker -- --type hello-world --ts --git --deploy false --framework none
# 2. 安装依赖
cd my-worker
npm install hono@4.11.3
npm install -D @cloudflare/vite-plugin@1.17.1 vite@7.3.1
# 3. 创建 wrangler.jsonc
{
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID",
"compatibility_date": "2025-11-11",
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"] // 关键:防止 SPA 回退机制拦截 API 路由
}
}
# 4. 创建 vite.config.ts
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({ plugins: [cloudflare()] })
# 5. 创建 src/index.ts
import { Hono } from 'hono'
type Bindings = { ASSETS: Fetcher }
const app = new Hono<{ Bindings: Bindings }>()
app.get('/api/hello', (c) => c.json({ message: 'Hello!' }))
app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))
export default app // 关键:使用此模式(而非 { fetch: app.fetch })
# 6. 部署
npm run dev # 本地开发:http://localhost:8787
wrangler deploy # 生产环境
关键配置 :
run_worker_first: ["/api/*"] - 若无此项,SPA 回退机制会拦截 API 路由,返回 index.html 而非 JSON (workers-sdk #8879)export default app - 使用 { fetch: app.fetch } 会导致“无法读取未定义的属性”错误 (honojs/hono #3955)本技能可预防 10 个已记录的问题 :
错误 : “无法读取未定义的属性(读取 'map')” 来源 : honojs/hono #3955 预防方法 : 使用 export default app(而非 { fetch: app.fetch })
错误 : API 路由返回 index.html 而非 JSON 来源 : workers-sdk #8879 预防方法 : 在 wrangler.jsonc 中添加 "run_worker_first": ["/api/*"]
错误 : “处理程序未导出 scheduled() 函数” 来源 : honojs/vite-plugins #275 预防方法 : 需要时使用模块 Worker 格式:
export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}
错误 : 开发期间出现“挂起的 Promise 被取消” 来源 : workers-sdk #9518 预防方法 : 使用 @cloudflare/vite-plugin@1.13.13 或更高版本
错误 : CI/CD 中非确定性的部署失败 来源 : workers-sdk #7555 预防方法 : 使用 Wrangler 4.x+ 并启用重试逻辑(近期版本已修复)
错误 : 使用已弃用的 Service Worker 格式 来源 : Cloudflare 迁移指南 预防方法 : 始终使用 ES 模块格式
错误 : 渐进式部署期间带指纹的资源出现 404 错误 来源 : Cloudflare 静态资源文档 原因 : 现代框架(使用 Vite 的 React/Vue/Angular)会生成带指纹的文件名(例如 index-a1b2c3d4.js)。在版本间的渐进式部署过程中,用户的初始请求可能发送到版本 A(HTML 引用 index-a1b2c3d4.js),但后续的资源请求却路由到版本 B(仅包含 index-m3n4o5p6.js),从而导致 404 错误 预防方法 :
错误 : 超出免费套餐限制时,资源请求返回 429(请求过多)响应 来源 : Cloudflare 静态资源计费文档 原因 : 使用 run_worker_first 时,匹配指定模式的请求总会调用你的 Worker 脚本(计入免费套餐限制)。超出限制后,这些请求会收到 429 错误,而无法回退到免费的静态资源服务 预防方法 :
!/pattern) 将路径排除在 Worker 调用之外run_worker_first 模式限制在仅必要的 API 路由错误 : 在未暴露 require 函数的环境中调用 "buffer" 的 require 来源 : workers-sdk #11948 受影响版本 : Vite 8.x 配合 @cloudflare/vite-plugin 1.21.0+ 原因 : Vite 8 使用 Rolldown 打包器,它不会将 require() 转换为外部模块的 import。Workers 不暴露 require() 函数,导致运行时 Node 内置模块导入失败。预防方法 :
// vite.config.ts - 添加 esmExternalRequirePlugin
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import { esmExternalRequirePlugin } from 'vite'
import { builtinModules } from 'node:module'
export default defineConfig({
plugins: [
cloudflare(),
esmExternalRequirePlugin({
external: [/^node:/, ...builtinModules],
}),
],
})
状态 : 已有变通方案。Vite 团队正在修复 (vitejs/vite#21452)。
错误 : curl http://localhost:5173/prefix 返回 404 而非 index.html 来源 : workers-sdk #11857 受影响版本 : @cloudflare/vite-plugin 1.13.8+ 原因 : 插件现在将包含基础路径的完整 URL 传递给 Asset Worker(与生产环境行为匹配)。平台对 assets.base 的支持尚不可用。预防方法(开发模式变通方案):
// worker.ts - 在开发环境中移除基础路径
if (import.meta.env.DEV) {
url.pathname = url.pathname.replace(import.meta.env.BASE_URL, '');
if (url.pathname === '/') {
return this.env.ASSETS.fetch(request);
}
request = new Request(url, request);
}
状态 : 为对齐开发与生产环境而做的有意变更。平台功能 assets.base 计划于 2026 年第一季度推出 (workers-sdk #9885)。
关键理解 : "not_found_handling": "single-page-application" 会为未知路由返回 index.html(启用 React Router、Vue Router)。若无 run_worker_first,这会拦截 API 路由!
使用 run_worker_first: ["/api/*"] 的请求路由:
/api/hello → Worker 处理(返回 JSON)/ → 静态资源服务提供 index.html/styles.css → 静态资源服务提供 styles.css/unknown → 静态资源服务提供 index.html(SPA 回退)静态资源缓存 : 自动边缘缓存。使用查询字符串清除缓存:<link href="/styles.css?v=1.0.0">
免费套餐警告 (2025): run_worker_first 模式计入免费套餐限制。超出后,请求会收到 429 错误,而无法回退到免费的静态资源服务。使用负向模式 (!/pattern) 或升级到付费计划。
默认行为 : Wrangler 在部署时会自动配置 R2 存储桶、D1 数据库和 KV 命名空间。这消除了手动创建资源的步骤。
关键:始终指定资源名称
⚠️ 边缘情况 (workers-sdk #11870): 如果仅提供 binding 而未指定 database_name/bucket_name,Wrangler 会将绑定名称用作资源名称。这会导致 wrangler dev 和子命令出现令人困惑的行为,因为它们优先使用 database_id → database_name → binding。
// ❌ 不要:仅指定绑定会创建名为 "DB" 的数据库
{
"d1_databases": [{ "binding": "DB" }]
}
// ✅ 要:显式命名可避免混淆
{
"d1_databases": [
{
"binding": "DB",
"database_name": "my-app-db" // 始终指定!
}
],
"r2_buckets": [
{
"binding": "STORAGE",
"bucket_name": "my-app-files" // 始终指定!
}
],
"kv_namespaces": [
{
"binding": "CACHE",
"title": "my-app-cache" // 始终指定!
}
]
}
# 部署 - 如果资源不存在则自动配置
wrangler deploy
# 禁用自动配置(仅使用现有资源)
wrangler deploy --no-x-provision
优势 :
wrangler d1 create / wrangler r2 create 步骤wrangler dev 会创建本地模拟资源)是什么 : 用于在 Worker 之间调用方法的 JavaScript 原生 RPC 系统。底层使用 Cap'n Proto 实现零拷贝消息传递。
使用场景 : 将应用程序拆分为多个 Worker(例如 API Worker + 认证 Worker + 邮件 Worker),它们可以通过类型安全的方法相互调用。
定义 RPC 服务 :
import { WorkerEntrypoint } from 'cloudflare:workers'
export class AuthService extends WorkerEntrypoint<Env> {
async verifyToken(token: string): Promise<{ userId: string; valid: boolean }> {
// 通过 this.env 访问绑定
const session = await this.env.SESSIONS.get(token)
return session ? { userId: session.userId, valid: true } : { userId: '', valid: false }
}
async createSession(userId: string): Promise<string> {
const token = crypto.randomUUID()
await this.env.SESSIONS.put(token, JSON.stringify({ userId }), { expirationTtl: 3600 })
return token
}
}
// 默认导出仍处理 HTTP 请求
export default { fetch: ... }
从另一个 Worker 调用 :
// wrangler.jsonc
{
"services": [
{ "binding": "AUTH", "service": "auth-worker", "entrypoint": "AuthService" }
]
}
// 在你的主 Worker 中
const { valid, userId } = await env.AUTH.verifyToken(authHeader)
要点 :
wrangler dev 中,同一 Worker 的调用显示为 [connected]症状 : wrangler dev 期间偶发 ResponseSentError: 响应已发送到浏览器且无法更改 来源 : workers-sdk #11932 原因 : .wrangler 目录中的缓存损坏或过时的 Vite 缓存
解决方案 :
# 清除所有缓存
rm -rf .wrangler dist node_modules/.vite
# 重新构建
npm run build
# 如有需要,重新创建本地 D1 数据库
wrangler d1 execute DB --local --file schema.sql
适用于 : Wrangler 4.x 完整 Workers 模式(非 Cloudflare Pages)
注意 : 这些技巧来自社区讨论。请根据你的版本进行验证。
来源 : workers-sdk #11825(社区提供)
如果使用 React SSR 配合 @cloudflare/vite-plugin,请固定使用 vite-tsconfig-paths@5.1.4:
npm install vite-tsconfig-paths@5.1.4
原因 : 6.x 版本在依赖扫描期间不遵循路径别名,导致重复的 React 实例和“无效的 hook 调用”错误。
适用于 : 使用 TypeScript 路径别名配合 React SSR 的项目
来源 : workers-sdk #11957
uuid@11 包(ESM)可能导致运行时崩溃,出现“fileURLToPath 未定义”错误。请改用原生的 Web Crypto API:
// ✅ 原生 Workers API(推荐)
const uuid = crypto.randomUUID();
// ❌ 避免在 Workers 中使用 uuid 包
import { v4 as uuidv4 } from 'uuid'; // 可能崩溃
适用于 : 所有需要 UUID 的 Workers 项目
/deploy - 一键部署流水线使用时机 : 准备提交、推送并部署你的 Cloudflare Worker 时。
功能 :
wrangler deploy,捕获 Worker URL节省时间 : 每个部署周期节省 2-3 分钟
处理的边缘情况 :
模板 : templates/ 目录中的完整设置文件(wrangler.jsonc、vite.config.ts、package.json、tsconfig.json、src/index.ts、public/index.html、styles.css、script.js)
mcp__cloudflare-docs__search_cloudflare_documentation 获取最新文档{
"dependencies": {
"hono": "^4.11.3"
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.17.1",
"@cloudflare/workers-types": "^4.20260103.0",
"vite": "^7.3.1",
"wrangler": "^4.54.0",
"typescript": "^5.9.3"
}
}
在线示例 : https://cloudflare-worker-base-test.webfonts.workers.dev(构建时间:45 分钟,0 错误,所有 10 个问题均已预防)
最后验证 : 2026-01-20 | 技能版本 : 3.1.0 | 变更 : 添加了 Vite 8 nodejs_compat 变通方案(问题 #9)、Vite base 选项回归问题(问题 #10)、自动配置边缘情况警告、缓存损坏故障排除部分,以及关于 vite-tsconfig-paths v6 和 uuid 包替代方案的社区技巧。研究由技能研究代理进行,涵盖 2025 年 5 月后的 Workers SDK 更新。
每周安装量
394
代码仓库
GitHub 星标
643
首次出现
2026年1月20日
安全审计
安装于
claude-code335
opencode279
gemini-cli277
cursor246
codex240
antigravity238
Production-tested : cloudflare-worker-base-test (https://cloudflare-worker-base-test.webfonts.workers.dev) Last Updated : 2026-01-20 Status : Production Ready ✅ Latest Versions : hono@4.11.3, @cloudflare/vite-plugin@1.17.1, vite@7.3.1, wrangler@4.54.0 Skill Version : 3.1.0
Recent Updates (2025-2026) :
wrangler deploy --x-autoconfig)WorkerEntrypoint class for service bindings# 1. Scaffold project
npm create cloudflare@latest my-worker -- --type hello-world --ts --git --deploy false --framework none
# 2. Install dependencies
cd my-worker
npm install hono@4.11.3
npm install -D @cloudflare/vite-plugin@1.17.1 vite@7.3.1
# 3. Create wrangler.jsonc
{
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID",
"compatibility_date": "2025-11-11",
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"] // CRITICAL: Prevents SPA fallback from intercepting API routes
}
}
# 4. Create vite.config.ts
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({ plugins: [cloudflare()] })
# 5. Create src/index.ts
import { Hono } from 'hono'
type Bindings = { ASSETS: Fetcher }
const app = new Hono<{ Bindings: Bindings }>()
app.get('/api/hello', (c) => c.json({ message: 'Hello!' }))
app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))
export default app // CRITICAL: Use this pattern (NOT { fetch: app.fetch })
# 6. Deploy
npm run dev # Local: http://localhost:8787
wrangler deploy # Production
Critical Configuration :
run_worker_first: ["/api/*"] - Without this, SPA fallback intercepts API routes returning index.html instead of JSON (workers-sdk #8879)export default app - Using { fetch: app.fetch } causes "Cannot read properties of undefined" (honojs/hono #3955)This skill prevents 10 documented issues :
Error : "Cannot read properties of undefined (reading 'map')" Source : honojs/hono #3955 Prevention : Use export default app (NOT { fetch: app.fetch })
Error : API routes return index.html instead of JSON Source : workers-sdk #8879 Prevention : Add "run_worker_first": ["/api/*"] to wrangler.jsonc
Error : "Handler does not export a scheduled() function" Source : honojs/vite-plugins #275 Prevention : Use Module Worker format when needed:
export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}
Error : "A hanging Promise was canceled" during development Source : workers-sdk #9518 Prevention : Use @cloudflare/vite-plugin@1.13.13 or later
Error : Non-deterministic deployment failures in CI/CD Source : workers-sdk #7555 Prevention : Use Wrangler 4.x+ with retry logic (fixed in recent versions)
Error : Using deprecated Service Worker format Source : Cloudflare migration guide Prevention : Always use ES Module format
Error : 404 errors for fingerprinted assets during gradual deployments Source : Cloudflare Static Assets Docs Why It Happens : Modern frameworks (React/Vue/Angular with Vite) generate fingerprinted filenames (e.g., index-a1b2c3d4.js). During gradual rollouts between versions, a user's initial request may go to Version A (HTML references index-a1b2c3d4.js), but subsequent asset requests route to Version B (only has index-m3n4o5p6.js), causing 404s Prevention :
Error : 429 (Too Many Requests) responses on asset requests when exceeding free tier limits Source : Cloudflare Static Assets Billing Docs Why It Happens : When using run_worker_first, requests matching specified patterns ALWAYS invoke your Worker script (counted toward free tier limits). After exceeding limits, these requests receive 429 instead of falling back to free static asset serving Prevention :
!/pattern) to exclude paths from Worker invocationrun_worker_first patterns to only essential API routesError : Calling require for "buffer" in an environment that doesn't expose the require function Source : workers-sdk #11948 Affected Versions : Vite 8.x with @cloudflare/vite-plugin 1.21.0+ Why It Happens : Vite 8 uses Rolldown bundler which doesn't convert require() to import for external modules. Workers don't expose require() function, causing Node built-in module imports to fail at runtime. Prevention :
// vite.config.ts - Add esmExternalRequirePlugin
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import { esmExternalRequirePlugin } from 'vite'
import { builtinModules } from 'node:module'
export default defineConfig({
plugins: [
cloudflare(),
esmExternalRequirePlugin({
external: [/^node:/, ...builtinModules],
}),
],
})
Status : Workaround available. Vite team working on fix (vitejs/vite#21452).
Error : curl http://localhost:5173/prefix returns 404 instead of index.html Source : workers-sdk #11857 Affected Versions : @cloudflare/vite-plugin 1.13.8+ Why It Happens : Plugin now passes full URL with base path to Asset Worker (matching prod behavior). Platform support for assets.base not yet available. Prevention (dev-mode workaround):
// worker.ts - Strip base path in development
if (import.meta.env.DEV) {
url.pathname = url.pathname.replace(import.meta.env.BASE_URL, '');
if (url.pathname === '/') {
return this.env.ASSETS.fetch(request);
}
request = new Request(url, request);
}
Status : Intentional change to align dev with prod. Platform feature assets.base planned for Q1 2026 (workers-sdk #9885).
Critical Understanding : "not_found_handling": "single-page-application" returns index.html for unknown routes (enables React Router, Vue Router). Without run_worker_first, this intercepts API routes!
Request Routing withrun_worker_first: ["/api/*"]:
/api/hello → Worker handles (returns JSON)/ → Static Assets serve index.html/styles.css → Static Assets serve styles.css/unknown → Static Assets serve index.html (SPA fallback)Static Assets Caching : Automatic edge caching. Cache bust with query strings: <link href="/styles.css?v=1.0.0">
Free Tier Warning (2025): run_worker_first patterns count toward free tier limits. After exceeding, requests get 429 instead of falling back to free static assets. Use negative patterns (!/pattern) or upgrade to Paid plan.
Default Behavior : Wrangler automatically provisions R2 buckets, D1 databases, and KV namespaces when deploying. This eliminates manual resource creation steps.
Critical: Always Specify Resource Names
⚠️ Edge Case (workers-sdk #11870): If you provide only binding without database_name/bucket_name, Wrangler uses the binding name as the resource name. This causes confusing behavior with wrangler dev and subcommands, which prefer database_id → database_name → binding.
// ❌ DON'T: Binding-only creates database named "DB"
{
"d1_databases": [{ "binding": "DB" }]
}
// ✅ DO: Explicit names prevent confusion
{
"d1_databases": [
{
"binding": "DB",
"database_name": "my-app-db" // Always specify!
}
],
"r2_buckets": [
{
"binding": "STORAGE",
"bucket_name": "my-app-files" // Always specify!
}
],
"kv_namespaces": [
{
"binding": "CACHE",
"title": "my-app-cache" // Always specify!
}
]
}
# Deploy - resources auto-provisioned if they don't exist
wrangler deploy
# Disable auto-provisioning (use existing resources only)
wrangler deploy --no-x-provision
Benefits :
wrangler d1 create / wrangler r2 create steps neededwrangler dev creates local emulated resources)What It Is : JavaScript-native RPC system for calling methods between Workers. Uses Cap'n Proto under the hood for zero-copy message passing.
Use Case : Split your application into multiple Workers (e.g., API Worker + Auth Worker + Email Worker) that call each other with type-safe methods.
Defining an RPC Service :
import { WorkerEntrypoint } from 'cloudflare:workers'
export class AuthService extends WorkerEntrypoint<Env> {
async verifyToken(token: string): Promise<{ userId: string; valid: boolean }> {
// Access bindings via this.env
const session = await this.env.SESSIONS.get(token)
return session ? { userId: session.userId, valid: true } : { userId: '', valid: false }
}
async createSession(userId: string): Promise<string> {
const token = crypto.randomUUID()
await this.env.SESSIONS.put(token, JSON.stringify({ userId }), { expirationTtl: 3600 })
return token
}
}
// Default export still handles HTTP requests
export default { fetch: ... }
Calling from Another Worker :
// wrangler.jsonc
{
"services": [
{ "binding": "AUTH", "service": "auth-worker", "entrypoint": "AuthService" }
]
}
// In your main Worker
const { valid, userId } = await env.AUTH.verifyToken(authHeader)
Key Points :
wrangler dev, shows as [connected] for same-Worker callsSymptom : Sporadic ResponseSentError: The response has already been sent to the browser and cannot be altered during wrangler dev Source : workers-sdk #11932 Cause : Cache corruption in .wrangler directory or stale Vite cache
Solution :
# Clear all caches
rm -rf .wrangler dist node_modules/.vite
# Rebuild
npm run build
# Recreate local D1 databases if needed
wrangler d1 execute DB --local --file schema.sql
Applies to : Wrangler 4.x full Workers mode (not Cloudflare Pages)
Note : These tips come from community discussions. Verify against your version.
Source : workers-sdk #11825 (Community-sourced)
If using React SSR with @cloudflare/vite-plugin, pin to vite-tsconfig-paths@5.1.4:
npm install vite-tsconfig-paths@5.1.4
Why : Version 6.x doesn't follow path aliases during dependency scan, causing duplicate React instances and "Invalid hook call" errors.
Applies to : Projects using TypeScript path aliases with React SSR
Source : workers-sdk #11957
The uuid@11 package (ESM) can cause runtime crashes with "fileURLToPath undefined" in Workers. Use the native Web Crypto API instead:
// ✅ Native Workers API (recommended)
const uuid = crypto.randomUUID();
// ❌ Avoid uuid package in Workers
import { v4 as uuidv4 } from 'uuid'; // May crash
Applies to : All Workers projects needing UUIDs
/deploy - One-Command Deploy PipelineUse when : Ready to commit, push, and deploy your Cloudflare Worker in one step.
Does :
wrangler deploy, captures Worker URLTime savings : 2-3 min per deploy cycle
Edge Cases Handled :
Templates : Complete setup files in templates/ directory (wrangler.jsonc, vite.config.ts, package.json, tsconfig.json, src/index.ts, public/index.html, styles.css, script.js)
mcp__cloudflare-docs__search_cloudflare_documentation for latest docs{
"dependencies": {
"hono": "^4.11.3"
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.17.1",
"@cloudflare/workers-types": "^4.20260103.0",
"vite": "^7.3.1",
"wrangler": "^4.54.0",
"typescript": "^5.9.3"
}
}
Live Example : https://cloudflare-worker-base-test.webfonts.workers.dev (build time: 45 min, 0 errors, all 10 issues prevented)
Last verified : 2026-01-20 | Skill version : 3.1.0 | Changes : Added Vite 8 nodejs_compat workaround (Issue #9), Vite base option regression (Issue #10), auto-provisioning edge case warning, troubleshooting section for cache corruption, and community tips for vite-tsconfig-paths v6 and uuid package alternatives. Research conducted by skill-researcher agent covering post-May 2025 Workers SDK updates.
Weekly Installs
394
Repository
GitHub Stars
643
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykWarn
Installed on
claude-code335
opencode279
gemini-cli277
cursor246
codex240
antigravity238
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
106,200 周安装