cloudflare-worker-base
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare Worker Base Stack
Cloudflare Worker 基础架构
Production-tested: cloudflare-worker-base-test (https://cloudflare-worker-base-test.webfonts.workers.dev)
Last Updated: 2025-10-20
Status: Production Ready ✅
经过生产验证:cloudflare-worker-base-test(https://cloudflare-worker-base-test.webfonts.workers.dev)
最后更新:2025-10-20
状态:可用于生产环境 ✅
Quick Start (5 Minutes)
快速开始(5分钟)
1. Scaffold Project
1. 搭建项目框架
bash
npm create cloudflare@latest my-worker -- \
--type hello-world \
--ts \
--git \
--deploy false \
--framework noneWhy these flags:
- : Clean starting point
--type hello-world - : TypeScript support
--ts - : Initialize git repo
--git - : Don't deploy yet (configure first)
--deploy false - : We'll add Vite ourselves
--framework none
bash
npm create cloudflare@latest my-worker -- \
--type hello-world \
--ts \
--git \
--deploy false \
--framework none选择这些参数的原因:
- :干净的起始模板
--type hello-world - :支持TypeScript
--ts - :初始化Git仓库
--git - :暂不部署(先完成配置)
--deploy false - :我们将自行添加Vite
--framework none
2. Install Dependencies
2. 安装依赖
bash
cd my-worker
npm install hono@4.10.1
npm install -D @cloudflare/vite-plugin@1.13.13 vite@^7.0.0Version Notes:
- : Latest stable (verified 2025-10-20)
hono@4.10.1 - : Latest stable, fixes HMR race condition
@cloudflare/vite-plugin@1.13.13 - : Latest version compatible with Cloudflare plugin
vite
bash
cd my-worker
npm install hono@4.10.1
npm install -D @cloudflare/vite-plugin@1.13.13 vite@^7.0.0版本说明:
- :最新稳定版(2025-10-20已验证)
hono@4.10.1 - :最新稳定版,修复了HMR竞争条件问题
@cloudflare/vite-plugin@1.13.13 - :与Cloudflare插件兼容的最新版本
vite
3. Configure Wrangler
3. 配置Wrangler
Create or update :
wrangler.jsoncjsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID", // Find this in your Cloudflare dashboard (Workers & Pages -> Overview).
"compatibility_date": "2025-10-11",
"observability": {
"enabled": true
},
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"]
}
}CRITICAL: Configuration
run_worker_first- Without this, SPA fallback intercepts API routes
- API routes return instead of JSON
index.html - Source: workers-sdk #8879
创建或更新:
wrangler.jsoncjsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID", // 在Cloudflare控制台中查找(Workers & Pages -> 概览)。
"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 fallback会拦截API路由
- API路由会返回而非JSON
index.html - 来源:workers-sdk #8879
4. Configure Vite
4. 配置Vite
Create :
vite.config.tstypescript
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [
cloudflare({
// Optional: Configure the plugin if needed
}),
],
})Why @cloudflare/vite-plugin:
- Official plugin from Cloudflare
- Supports HMR with Workers
- Enables local development with Miniflare
- Version 1.13.13 fixes "A hanging Promise was canceled" error
创建:
vite.config.tstypescript
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [
cloudflare({
// 可选:根据需要配置插件
}),
],
})为何使用@cloudflare/vite-plugin:
- Cloudflare官方推出的插件
- 支持Workers的HMR功能
- 可通过Miniflare实现本地开发
- 1.13.13版本修复了"A hanging Promise was canceled"错误
The Four-Step Setup Process
四步搭建流程
Step 1: Create Hono App with API Routes
步骤1:创建带API路由的Hono应用
Create :
src/index.tstypescript
/**
* 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 appWhy This Export Pattern:
- Source: honojs/hono #3955
- Using causes: "Cannot read properties of undefined (reading 'map')"
{ fetch: app.fetch } - Exception: If you need scheduled/tail handlers, use Module Worker format:
typescript
export default { fetch: app.fetch, scheduled: async (event, env, ctx) => { /* ... */ } }
创建:
src/index.tstypescript
/**
* 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
- 使用会导致:"Cannot read properties of undefined (reading 'map')"
{ fetch: app.fetch } - 例外情况:若需要定时/尾处理器,使用Module Worker格式:
typescript
export default { fetch: app.fetch, scheduled: async (event, env, ctx) => { /* ... */ } }
Step 2: Create Static Frontend
步骤2:创建静态前端
Create :
public/index.htmlhtml
<!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>Create :
public/script.jsjavascript
async function testAPI() {
const response = await fetch('/api/hello')
const data = await response.json()
document.getElementById('output').textContent = JSON.stringify(data, null, 2)
}Create :
public/styles.csscss
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;
}创建:
public/index.htmlhtml
<!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.jsjavascript
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.csscss
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;
}Step 3: Update Package Scripts
步骤3:更新包脚本
Update :
package.jsonjson
{
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"cf-typegen": "wrangler types"
}
}更新:
package.jsonjson
{
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"cf-typegen": "wrangler types"
}
}Step 4: Test & Deploy
步骤4:测试与部署
bash
undefinedbash
undefinedGenerate TypeScript types for bindings
为绑定生成TypeScript类型
npm run cf-typegen
npm run cf-typegen
Start local dev server (http://localhost:8787)
启动本地开发服务器(http://localhost:8787)
npm run dev
npm run dev
Deploy to production
部署到生产环境
npm run deploy
---npm run deploy
---Known Issues Prevention
已知问题预防
This skill prevents 6 documented issues:
本方案可预防6类已记录的问题:
Issue #1: Export Syntax Error
问题1:导出语法错误
Error: "Cannot read properties of undefined (reading 'map')"
Source: honojs/hono #3955
Prevention: Use (NOT )
export default app{ fetch: app.fetch }错误信息:"Cannot read properties of undefined (reading 'map')"
来源:honojs/hono #3955
预防方案:使用(而非)
export default app{ fetch: app.fetch }Issue #2: Static Assets Routing Conflicts
问题2:静态资源路由冲突
Error: API routes return instead of JSON
Source: workers-sdk #8879
Prevention: Add to wrangler.jsonc
index.html"run_worker_first": ["/api/*"]错误信息:API路由返回而非JSON
来源:workers-sdk #8879
预防方案:在wrangler.jsonc中添加
index.html"run_worker_first": ["/api/*"]Issue #3: Scheduled/Cron Not Exported
问题3:定时/CRON任务未导出
Error: "Handler does not export a scheduled() function"
Source: honojs/vite-plugins #275
Prevention: Use Module Worker format when needed:
typescript
export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}错误信息:"Handler does not export a scheduled() function"
来源:honojs/vite-plugins #275
预防方案:必要时使用Module Worker格式:
typescript
export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}Issue #4: HMR Race Condition
问题4:HMR竞争条件
Error: "A hanging Promise was canceled" during development
Source: workers-sdk #9518
Prevention: Use or later
@cloudflare/vite-plugin@1.13.13错误信息:开发过程中出现"A hanging Promise was canceled"
来源:workers-sdk #9518
预防方案:使用或更高版本
@cloudflare/vite-plugin@1.13.13Issue #5: Static Assets Upload Race
问题5:静态资源上传竞争
Error: Non-deterministic deployment failures in CI/CD
Source: workers-sdk #7555
Prevention: Use Wrangler 4.x+ with retry logic (fixed in recent versions)
错误信息:CI/CD中出现非确定性部署失败
来源:workers-sdk #7555
预防方案:使用带重试逻辑的Wrangler 4.x+(最新版本已修复)
Issue #6: Service Worker Format Confusion
问题6:Service Worker格式混淆
Error: Using deprecated Service Worker format
Source: Cloudflare migration guide
Prevention: Always use ES Module format (shown in Step 1)
错误信息:使用已弃用的Service Worker格式
来源:Cloudflare迁移指南
预防方案:始终使用ES Module格式(如步骤1所示)
Configuration Files Reference
配置文件参考
wrangler.jsonc (Full Example)
wrangler.jsonc(完整示例)
jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID", // Find this in your Cloudflare dashboard (Workers & Pages -> Overview).
"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" }
// ]
}Why wrangler.jsonc over wrangler.toml:
- JSON format preferred since Wrangler v3.91.0
- Better IDE support with JSON schema
- Comments allowed with JSONC
jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID", // 在Cloudflare控制台中查找(Workers & Pages -> 概览)。
"compatibility_date": "2025-10-11",
"observability": {
"enabled": true
},
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"]
}
/* 可选:环境变量 */
// "vars": { "MY_VARIABLE": "production_value" }
/* 可选:KV命名空间绑定 */
// "kv_namespaces": [
// { "binding": "MY_KV", "id": "YOUR_KV_ID" }
// ]
/* 可选:D1数据库绑定 */
// "d1_databases": [
// { "binding": "DB", "database_name": "my-db", "database_id": "YOUR_DB_ID" }
// ]
/* 可选:R2存储桶绑定 */
// "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 (Full Example)
vite.config.ts(完整示例)
typescript
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,
},
})typescript
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [
cloudflare({
// 可选:在HMR更新之间保留状态
persist: true,
}),
],
// 可选:配置服务器
server: {
port: 8787,
},
// 可选:构建优化
build: {
target: 'esnext',
minify: true,
},
})tsconfig.json
tsconfig.json
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"]
}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 Route Patterns
API路由模式
Basic JSON Response
基础JSON响应
typescript
app.get('/api/users', (c) => {
return c.json({
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
})
})typescript
app.get('/api/users', (c) => {
return c.json({
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
})
})POST with Request Body
带请求体的POST请求
typescript
app.post('/api/users', async (c) => {
const body = await c.req.json()
// Validate and process body
return c.json({ success: true, data: body }, 201)
})typescript
app.post('/api/users', async (c) => {
const body = await c.req.json()
// 验证并处理请求体
return c.json({ success: true, data: body }, 201)
})Route Parameters
路由参数
typescript
app.get('/api/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: 'User' })
})typescript
app.get('/api/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: 'User' })
})Query Parameters
查询参数
typescript
app.get('/api/search', (c) => {
const query = c.req.query('q')
return c.json({ query, results: [] })
})typescript
app.get('/api/search', (c) => {
const query = c.req.query('q')
return c.json({ query, results: [] })
})Error Handling
错误处理
typescript
app.get('/api/data', async (c) => {
try {
// Your logic here
return c.json({ success: true })
} catch (error) {
return c.json({ error: error.message }, 500)
}
})typescript
app.get('/api/data', async (c) => {
try {
// 业务逻辑
return c.json({ success: true })
} catch (error) {
return c.json({ error: error.message }, 500)
}
})Using Bindings (KV, D1, R2)
使用绑定(KV、D1、R2)
typescript
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 })
})typescript
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 })
})Static Assets Best Practices
静态资源最佳实践
Directory Structure
目录结构
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/public/
├── index.html # 主入口文件
├── styles.css # 全局样式
├── script.js # 客户端JavaScript
├── favicon.ico # 网站图标
└── assets/ # 图片、字体等资源
├── logo.png
└── fonts/SPA Fallback
SPA Fallback
The configuration means:
"not_found_handling": "single-page-application"- Unknown routes return
index.html - Useful for React Router, Vue Router, etc.
- BUT requires for API routes!
run_worker_first
"not_found_handling": "single-page-application"- 未知路由返回
index.html - 适用于React Router、Vue Router等场景
- !!!但必须为API路由配置!!!
run_worker_first
Route Priority
路由优先级
With :
"run_worker_first": ["/api/*"]- → Worker handles it (returns JSON)
/api/hello - → Static Assets serve
/index.html - → Static Assets serve
/styles.cssstyles.css - → Static Assets serve
/unknown(SPA fallback)index.html
配置后:
"run_worker_first": ["/api/*"]- → 由Worker处理(返回JSON)
/api/hello - → 静态资源服务返回
/index.html - → 静态资源服务返回
/styles.cssstyles.css - → 静态资源服务返回
/unknown(SPA fallback)index.html
Caching Static Assets
静态资源缓存
Static Assets are automatically cached at the edge. To bust cache:
html
<link rel="stylesheet" href="/styles.css?v=1.0.0">
<script src="/script.js?v=1.0.0"></script>静态资源会自动在边缘节点缓存。如需刷新缓存,可添加版本号:
html
<link rel="stylesheet" href="/styles.css?v=1.0.0">
<script src="/script.js?v=1.0.0"></script>Development Workflow
开发工作流
Local Development
本地开发
bash
npm run dev- Server runs on http://localhost:8787
- HMR enabled (file changes reload automatically)
- Uses Miniflare for local simulation
- All bindings work locally (KV, D1, R2)
bash
npm run dev- 服务器运行在http://localhost:8787
- 启用HMR(文件变更后自动重载)
- 使用Miniflare进行本地模拟
- 所有绑定(KV、D1、R2等)均可在本地使用
Testing API Routes
测试API路由
bash
undefinedbash
undefinedTest GET endpoint
测试GET接口
Test POST endpoint
测试POST接口
curl -X POST http://localhost:8787/api/echo
-H "Content-Type: application/json"
-d '{"test": "data"}'
-H "Content-Type: application/json"
-d '{"test": "data"}'
undefinedcurl -X POST http://localhost:8787/api/echo
-H "Content-Type: application/json"
-d '{"test": "data"}'
-H "Content-Type: application/json"
-d '{"test": "data"}'
undefinedType Generation
类型生成
bash
npm run cf-typegenGenerates with:
worker-configuration.d.ts- Binding types (KV, D1, R2, etc.)
- Environment variable types
- Auto-completes in your editor
bash
npm run cf-typegen生成文件,包含:
worker-configuration.d.ts- 绑定类型(KV、D1、R2等)
- 环境变量类型
- 编辑器中可自动补全
Deployment
部署
bash
undefinedbash
undefinedDeploy to production
部署到生产环境
npm run deploy
npm run deploy
Deploy to specific environment
部署到指定环境
wrangler deploy --env staging
wrangler deploy --env staging
Tail logs in production
查看生产环境日志
wrangler tail
wrangler tail
Check deployment status
检查部署状态
wrangler deployments list
---wrangler deployments list
---Complete Setup Checklist
完整搭建检查清单
- Project scaffolded with
npm create cloudflare@latest - Dependencies installed: ,
hono@4.10.1@cloudflare/vite-plugin@1.13.13 - created with:
wrangler.jsonc- set to your Cloudflare account
account_id - pointing to
assets.directory./public/ - includes
assets.run_worker_first/api/* - set to recent date
compatibility_date
-
- created with
vite.config.ts@cloudflare/vite-plugin - created with Hono app
src/index.ts- Uses (NOT
export default app){ fetch: app.fetch } - Includes ASSETS binding type
- Has fallback route:
app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))
- Uses
- directory created with static files
public/ - executed successfully
npm run cf-typegen - starts without errors
npm run dev - API routes tested in browser/curl
- Static assets serve correctly
- HMR works without crashes
- Ready to deploy with
npm run deploy
- 使用完成项目搭建
npm create cloudflare@latest - 已安装依赖:、
hono@4.10.1@cloudflare/vite-plugin@1.13.13 - 已创建,包含:
wrangler.jsonc- 已设置为你的Cloudflare账户ID
account_id - 指向
assets.directory./public/ - 包含
assets.run_worker_first/api/* - 设置为近期日期
compatibility_date
-
- 已创建并配置
vite.config.ts@cloudflare/vite-plugin - 已创建并包含Hono应用
src/index.ts- 使用(而非
export default app){ fetch: app.fetch } - 包含ASSETS绑定类型
- 包含 fallback路由:
app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))
- 使用
- 已创建目录并添加静态文件
public/ - 执行成功
npm run cf-typegen - 可正常启动且无错误
npm run dev - API路由已通过浏览器/curl测试
- 静态资源可正常访问
- HMR功能正常,无崩溃
- 可通过完成部署
npm run deploy
Advanced Topics
进阶话题
Adding Middleware
添加中间件
typescript
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()
})typescript
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { cors } from 'hono/cors'
const app = new Hono<{ Bindings: Bindings }>()
// 全局中间件
app.use('*', logger())
app.use('/api/*', cors())
// 路由专属中间件
app.use('/admin/*', async (c, next) => {
// 权限校验
await next()
})Environment-Specific Configuration
环境专属配置
jsonc
// wrangler.jsonc
{
"name": "my-worker",
"env": {
"staging": {
"vars": { "ENV": "staging" }
},
"production": {
"vars": { "ENV": "production" }
}
}
}Deploy:
wrangler deploy --env stagingjsonc
// wrangler.jsonc
{
"name": "my-worker",
"env": {
"staging": {
"vars": { "ENV": "staging" }
},
"production": {
"vars": { "ENV": "production" }
}
}
}部署命令:
wrangler deploy --env stagingCustom Error Pages
自定义错误页面
typescript
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)
})typescript
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)
})Testing with Vitest
使用Vitest进行测试
bash
npm install -D vitest @cloudflare/vitest-pool-workersCreate :
vitest.config.tstypescript
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
poolOptions: {
workers: {
wrangler: { configPath: './wrangler.jsonc' },
},
},
},
})See for complete testing guide.
reference/testing.mdbash
npm install -D vitest @cloudflare/vitest-pool-workers创建:
vitest.config.tstypescript
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
poolOptions: {
workers: {
wrangler: { configPath: './wrangler.jsonc' },
},
},
},
})完整测试指南请查看。
reference/testing.mdFile Templates
文件模板
All templates are available in the directory:
templates/- wrangler.jsonc - Complete Worker configuration
- vite.config.ts - Vite + Cloudflare plugin setup
- package.json - Dependencies and scripts
- tsconfig.json - TypeScript configuration
- src/index.ts - Hono app with API routes
- public/index.html - Static frontend example
- public/styles.css - Example styling
- public/script.js - API test functions
Copy these files to your project and customize as needed.
所有模板文件均位于目录下:
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测试函数
可将这些文件复制到你的项目中并按需自定义。
Reference Documentation
参考文档
For deeper understanding, see:
- architecture.md - Deep dive into export patterns, routing, and Static Assets
- common-issues.md - All 6 issues with detailed troubleshooting
- deployment.md - Wrangler commands, CI/CD patterns, and production tips
如需深入了解,请查看:
- architecture.md - 导出模式、路由与静态资源的深度解析
- common-issues.md - 6类问题的详细排查方案
- deployment.md - Wrangler命令、CI/CD模式与生产环境技巧
Official Documentation
官方文档
- Cloudflare Workers: https://developers.cloudflare.com/workers/
- Static Assets: https://developers.cloudflare.com/workers/static-assets/
- Vite Plugin: https://developers.cloudflare.com/workers/vite-plugin/
- Wrangler Configuration: https://developers.cloudflare.com/workers/wrangler/configuration/
- Hono: https://hono.dev/docs/getting-started/cloudflare-workers
- Context7 Library ID:
/websites/developers_cloudflare-workers
- Cloudflare Workers:https://developers.cloudflare.com/workers/
- Static Assets:https://developers.cloudflare.com/workers/static-assets/
- Vite Plugin:https://developers.cloudflare.com/workers/vite-plugin/
- Wrangler Configuration:https://developers.cloudflare.com/workers/wrangler/configuration/
- Hono:https://hono.dev/docs/getting-started/cloudflare-workers
- Context7 Library ID:
/websites/developers_cloudflare-workers
Dependencies (Latest Verified 2025-10-20)
依赖包(2025-10-20最新验证版本)
json
{
"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"
}
}json
{
"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"
}
}Production Example
生产环境示例
This skill is based on the cloudflare-worker-base-test project:
- Live: https://cloudflare-worker-base-test.webfonts.workers.dev
- Build Time: ~45 minutes (actual)
- Errors: 0 (all 6 known issues prevented)
- Validation: ✅ Local dev, HMR, production deployment all successful
All patterns in this skill have been validated in production.
Questions? Issues?
- Check first
reference/common-issues.md - Verify all steps in the 4-step setup process
- Ensure (not
export default app){ fetch: app.fetch } - Ensure is configured
run_worker_first - Check official docs: https://developers.cloudflare.com/workers/
本方案基于cloudflare-worker-base-test项目:
- 在线地址:https://cloudflare-worker-base-test.webfonts.workers.dev
- 搭建时长:约45分钟(实际耗时)
- 错误情况:0(已预防全部6类已知问题)
- 验证结果:✅ 本地开发、HMR、生产部署均成功
本方案中的所有模式均已通过生产环境验证。
有疑问?遇到问题?
- 首先查看
reference/common-issues.md - 验证四步搭建流程中的所有步骤
- 确保使用(而非
export default app){ fetch: app.fetch } - 确保已配置
run_worker_first - 查看官方文档:https://developers.cloudflare.com/workers/