关于 cloudflare-worker-base
cloudflare-worker-base 是面向 Cloudflare Workers 开发者的项目搭建技能,提供基于 Hono、Vite 和 Wrangler 的配置步骤与模板,并说明常见问题的规避方法。
主要功能
- 01提供 Workers 项目搭建步骤
- 02配置 Hono、Vite 与 Wrangler
- 03包含配置文件和应用模板
- 04说明路由、静态资源与 API 设置
- 05整理开发、类型生成和部署流程
- 06列出已知问题及规避方法
适用场景
- 01从头创建 Cloudflare Worker 项目
- 02搭建含 API 路由和静态页面的应用
- 03配置本地开发和类型生成
- 04排查路由冲突或部署问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill cloudflare-worker-base安装后在 Claude Code 中输入/cloudflare-worker-base确认已加载。
附带文件README.mdSKILL.json
详细介绍
Cloudflare Worker 基础技术栈
已通过生产环境测试:cloudflare-worker-base-test (https://cloudflare-worker-base-test.webfonts.workers.dev) 最后更新:2025-10-20 状态:已准备好投入生产 ✅
快速开始(5 分钟)
1. 搭建项目
npm create cloudflare@latest my-worker -- \
--type hello-world \
--ts \
--git \
--deploy false \
--framework none
这些标志的作用:
--type hello-world:简洁的起点--ts:支持 TypeScript--git:初始化 git 仓库--deploy false:暂不部署(先进行配置)--framework none:我们会自行添加 Vite
2. 安装依赖项
cd my-worker
npm install [email protected]
npm install -D @cloudflare/[email protected] vite@latest
版本说明:
[email protected]:最新稳定版(已于 2025-10-20 验证)@cloudflare/[email protected]:最新稳定版,修复 HMR 竞态条件vite:与 Cloudflare 插件兼容的最新版本
3. 配置 Wrangler
创建或更新 wrangler.jsonc:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID",
"compatibility_date": "2025-10-11",
"observability": {
"enabled": true
},
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"]
}
}
重要:run_worker_first 配置
- 如果不配置,SPA 回退机制会拦截 API 路由
- API 路由会返回
index.html,而不是 JSON - 来源:workers-sdk #8879
4. 配置 Vite
创建 vite.config.ts:
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [
cloudflare({
// Optional: Configure the plugin if needed
}),
],
})
使用 @cloudflare/vite-plugin 的原因:
- Cloudflare 官方插件
- 支持 Workers HMR
- 支持使用 Miniflare 进行本地开发
- 1.13.13 版本修复了 “A hanging Promise was canceled” 错误
四步设置流程
第 1 步:创建包含 API 路由的 Hono 应用
创建 src/index.ts:
/**
* Cloudflare Worker with Hono
*
* CRITICAL: Export pattern to prevent build errors
* ✅ CORRECT: export default app
* ❌ WRONG: export default { fetch: app.fetch }
*/
import { Hono } from 'hono'
// Type-safe environment bindings
type Bindings = {
ASSETS: Fetcher
}
const app = new Hono<{ Bindings: Bindings }>()
/**
* API Routes
* Handled BEFORE static assets due to run_worker_first config
*/
app.get('/api/hello', (c) => {
return c.json({
message: 'Hello from Cloudflare Workers!',
timestamp: new Date().toISOString(),
})
})
app.get('/api/health', (c) => {
return c.json({
status: 'ok',
version: '1.0.0',
environment: c.env ? 'production' : 'development',
})
})
/**
* Fallback to Static Assets
* Any route not matched above is served from public/ directory
*/
app.all('*', (c) => {
return c.env.ASSETS.fetch(c.req.raw)
})
/**
* Export the Hono app directly (ES Module format)
* This is the correct pattern for Cloudflare Workers with Hono + Vite
*/
export default app
使用此导出模式的原因:
- 来源:honojs/hono #3955
- 使用
{ fetch: app.fetch }会导致:“Cannot read properties of undefined (reading 'map')” - 例外:如果需要 scheduled/tail 处理程序,请使用 Module Worker 格式:
export default { fetch: app.fetch, scheduled: async (event, env, ctx) => { /* ... */ } }
第 2 步:创建静态前端
创建 public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Worker App</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="container">
<h1>Cloudflare Worker + Static Assets</h1>
<button onclick="testAPI()">Test API</button>
<pre id="output"></pre>
</div>
<script src="/script.js"></script>
</body>
</html>
创建 public/script.js:
async function testAPI() {
const response = await fetch('/api/hello')
const data = await response.json()
document.getElementById('output').textContent = JSON.stringify(data, null, 2)
}
创建 public/styles.css:
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 20px;
}
button {
background: #0070f3;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
}
pre {
background: #f5f5f5;
padding: 16px;
border-radius: 6px;
overflow-x: auto;
}
第 3 步:更新 Package 脚本
更新 package.json:
{
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"cf-typegen": "wrangler types"
}
}
第 4 步:测试并部署
# Generate TypeScript types for bindings
npm run cf-typegen
# Start local dev server (http://localhost:8787)
npm run dev
# Deploy to production
npm run deploy
预防已知问题
此技能可预防 6 个已记录的问题:
问题 #1:导出语法错误
错误:“Cannot read properties of undefined (reading 'map')”
来源:honojs/hono #3955
预防方法:使用 export default app(不要使用 { fetch: app.fetch })
问题 #2:静态资源路由冲突
错误:API 路由返回 index.html,而不是 JSON
来源:workers-sdk #8879
预防方法:将 "run_worker_first": ["/api/*"] 添加到 wrangler.jsonc
问题 #3:未导出 Scheduled/Cron
错误:“Handler does not export a scheduled() function” 来源:honojs/vite-plugins #275 预防方法:需要时使用 Module Worker 格式:
export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}
问题 #4:HMR 竞态条件
错误:开发期间出现 “A hanging Promise was canceled”
来源:workers-sdk #9518
预防方法:使用 @cloudflare/[email protected] 或更高版本
问题 #5:静态资源上传竞态
错误:CI/CD 中出现非确定性的部署失败 来源:workers-sdk #7555 预防方法:使用带重试逻辑的 Wrangler 4.x+(近期版本已修复)
问题 #6:混淆 Service Worker 格式
错误:使用已弃用的 Service Worker 格式 来源:Cloudflare 迁移指南 预防方法:始终使用 ES Module 格式(见第 1 步)
配置文件参考
wrangler.jsonc(完整示例)
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID",
"compatibility_date": "2025-10-11",
"observability": {
"enabled": true
},
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"]
}
/* Optional: Environment Variables */
// "vars": { "MY_VARIABLE": "production_value" }
/* Optional: KV Namespace Bindings */
// "kv_namespaces": [
// { "binding": "MY_KV", "id": "YOUR_KV_ID" }
// ]
/* Optional: D1 Database Bindings */
// "d1_databases": [
// { "binding": "DB", "database_name": "my-db", "database_id": "YOUR_DB_ID" }
// ]
/* Optional: R2 Bucket Bindings */
// "r2_buckets": [
// { "binding": "MY_BUCKET", "bucket_name": "my-bucket" }
// ]
}
使用 wrangler.jsonc 而非 wrangler.toml 的原因:
- 自 Wrangler v3.91.0 起,优先使用 JSON 格式
- 使用 JSON schema 可获得更好的 IDE 支持
- JSONC 允许注释
vite.config.ts(完整示例)
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [
cloudflare({
// Persist state between HMR updates
persist: true,
}),
],
// Optional: Configure server
server: {
port: 8787,
},
// Optional: Build optimizations
build: {
target: 'esnext',
minify: true,
},
})
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": ["ES2022"],
"moduleResolution": "bundler",
"types": ["@cloudflare/workers-types/2023-07-01"],
"resolveJsonModule": true,
"allowJs": true,
"checkJs": false,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
API 路由模式
基本 JSON 响应
app.get('/api/users', (c) => {
return c.json({
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
})
})
使用请求正文的 POST
app.post('/api/users', async (c) => {
const body = await c.req.json()
// Validate and process body
return c.json({ success: true, data: body }, 201)
})
路由参数
app.get('/api/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: 'User' })
})
查询参数
app.get('/api/search', (c) => {
const query = c.req.query('q')
return c.json({ query, results: [] })
})
错误处理
app.get('/api/data', async (c) => {
try {
// Your logic here
return c.json({ success: true })
} catch (error) {
return c.json({ error: error.message }, 500)
}
})
使用绑定(KV、D1、R2)
type Bindings = {
ASSETS: Fetcher
MY_KV: KVNamespace
DB: D1Database
MY_BUCKET: R2Bucket
}
const app = new Hono<{ Bindings: Bindings }>()
app.get('/api/data', async (c) => {
// KV
const value = await c.env.MY_KV.get('key')
// D1
const result = await c.env.DB.prepare('SELECT * FROM users').all()
// R2
const object = await c.env.MY_BUCKET.get('file.txt')
return c.json({ value, result, object })
})
静态资源最佳实践
目录结构
public/
├── index.html # Main entry point
├── styles.css # Global styles
├── script.js # Client-side JavaScript
├── favicon.ico # Favicon
└── assets/ # Images, fonts, etc.
├── logo.png
└── fonts/
SPA 回退
"not_found_handling": "single-page-application" 配置表示:
- 未知路由会返回
index.html - 适用于 React Router、Vue Router 等
- 但是,API 路由需要设置
run_worker_first!
路由优先级
设置 "run_worker_first": ["/api/*"] 后:
/api/hello→ Worker 处理(返回 JSON)/→ 静态资源提供index.html/styles.css→ 静态资源提供styles.css/unknown→ 静态资源提供index.html(SPA 回退)
缓存静态资源
静态资源会自动在边缘缓存。要清除缓存:
<link rel="stylesheet" href="/styles.css?v=1.0.0">
<script src="/script.js?v=1.0.0"></script>
开发工作流
本地开发
npm run dev
- 服务器运行于 http://localhost:8787
- 已启用 HMR(文件更改后会自动重新加载)
- 使用 Miniflare 进行本地模拟
- 所有绑定都可在本地使用(KV、D1、R2)
测试 API 路由
# Test GET endpoint
curl http://localhost:8787/api/hello
# Test POST endpoint
curl -X POST http://localhost:8787/api/echo \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
类型生成
npm run cf-typegen
生成包含以下内容的 worker-configuration.d.ts:
- 绑定类型(KV、D1、R2 等)
- 环境变量类型
- 在编辑器中提供自动补全
部署
# Deploy to production
npm run deploy
# Deploy to specific environment
wrangler deploy --env staging
# Tail logs in production
wrangler tail
# Check deployment status
wrangler deployments list
完整设置清单
- 使用
npm create cloudflare@latest搭建项目框架 - 已安装依赖:
[email protected]、@cloudflare/[email protected] - 已创建
wrangler.jsonc,其中:-
account_id已设为你的 Cloudflare 账户 -
assets.directory指向./public/ -
assets.run_worker_first包含/api/* -
compatibility_date已设为近期日期
-
- 已创建包含
@cloudflare/vite-plugin的vite.config.ts - 已创建包含 Hono 应用的
src/index.ts- 使用
export default app(不要使用{ fetch: app.fetch }) - 包含 ASSETS 绑定类型
- 具有回退路由:
app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))
- 使用
- 已创建
public/目录并放入静态文件 - 已成功执行
npm run cf-typegen -
npm run dev可无错误地启动 - 已在浏览器/curl 中测试 API 路由
- 静态资源可正常提供
- HMR 可正常运行,不会崩溃
- 已准备好使用
npm run deploy进行部署
高级主题
添加中间件
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { cors } from 'hono/cors'
const app = new Hono<{ Bindings: Bindings }>()
// Global middleware
app.use('*', logger())
app.use('/api/*', cors())
// Route-specific middleware
app.use('/admin/*', async (c, next) => {
// Auth check
await next()
})
特定环境的配置
// wrangler.jsonc
{
"name": "my-worker",
"env": {
"staging": {
"vars": { "ENV": "staging" }
},
"production": {
"vars": { "ENV": "production" }
}
}
}
部署:wrangler deploy --env staging
自定义错误页面
app.onError((err, c) => {
console.error(err)
return c.json({ error: 'Internal Server Error' }, 500)
})
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})
使用 Vitest 进行测试
npm install -D vitest @cloudflare/vitest-pool-workers
创建 vitest.config.ts:
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
poolOptions: {
workers: {
wrangler: { configPath: './wrangler.jsonc' },
},
},
},
})
完整测试指南请参阅 reference/testing.md。
文件模板
所有模板均位于 templates/ 目录中:
- wrangler.jsonc - 完整的 Worker 配置
- vite.config.ts - Vite + Cloudflare 插件设置
- package.json - 依赖和脚本
- tsconfig.json - TypeScript 配置
- src/index.ts - 包含 API 路由的 Hono 应用
- public/index.html - 静态前端示例
- public/styles.css - 样式示例
- public/script.js - API 测试函数
将这些文件复制到项目中,并根据需要进行自定义。
参考文档
深入了解请参阅:
- architecture.md - 深入讲解导出模式、路由和静态资源
- common-issues.md - 详细排查全部 6 个问题
- deployment.md - Wrangler 命令、CI/CD 模式和生产环境提示
官方文档
- Cloudflare Workers:https://developers.cloudflare.com/workers/
- 静态资源:https://developers.cloudflare.com/workers/static-assets/
- Vite 插件:https://developers.cloudflare.com/workers/vite-plugin/
- Wrangler 配置:https://developers.cloudflare.com/workers/wrangler/configuration/
- Hono:https://hono.dev/docs/getting-started/cloudflare-workers
- Context7 库 ID:
/websites/developers_cloudflare-workers
依赖(最近验证于 2025-10-20)
{
"dependencies": {
"hono": "^4.10.1"
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.13.13",
"@cloudflare/workers-types": "^4.20251011.0",
"vite": "^7.0.0",
"wrangler": "^4.43.0",
"typescript": "^5.9.0"
}
}
生产示例
此技能基于 cloudflare-worker-base-test 项目:
- 线上地址:https://cloudflare-worker-base-test.webfonts.workers.dev
- 构建时间:约 45 分钟(实际)
- 错误:0 个(预防了所有 6 个已知问题)
- 验证:✅ 本地开发、HMR 和生产环境部署均成功
此技能中的所有模式均已在生产环境中验证。
有疑问?遇到问题?
- 先查看
reference/common-issues.md - 确认已完成 4 步设置流程中的所有步骤
- 确认使用
export default app(而不是{ fetch: app.fetch }) - 确认已配置
run_worker_first - 查看官方文档:https://developers.cloudflare.com/workers/