cloudflare-worker-base

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cloudflare 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 none
Why these flags:
  • --type hello-world
    : Clean starting point
  • --ts
    : TypeScript support
  • --git
    : Initialize git repo
  • --deploy false
    : Don't deploy yet (configure first)
  • --framework none
    : We'll add Vite ourselves
bash
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. 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.0
Version Notes:
  • hono@4.10.1
    : Latest stable (verified 2025-10-20)
  • @cloudflare/vite-plugin@1.13.13
    : Latest stable, fixes HMR race condition
  • vite
    : Latest version compatible with Cloudflare plugin
bash
cd my-worker
npm install hono@4.10.1
npm install -D @cloudflare/vite-plugin@1.13.13 vite@^7.0.0
版本说明:
  • hono@4.10.1
    :最新稳定版(2025-10-20已验证)
  • @cloudflare/vite-plugin@1.13.13
    :最新稳定版,修复了HMR竞争条件问题
  • vite
    :与Cloudflare插件兼容的最新版本

3. Configure Wrangler

3. 配置Wrangler

Create or update
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/*"]
  }
}
CRITICAL:
run_worker_first
Configuration
  • Without this, SPA fallback intercepts API routes
  • API routes return
    index.html
    instead of JSON
  • Source: workers-sdk #8879
创建或更新
wrangler.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/*"]
  }
}
关键配置:
run_worker_first
  • 缺少该配置时,SPA fallback会拦截API路由
  • API路由会返回
    index.html
    而非JSON
  • 来源:workers-sdk #8879

4. Configure Vite

4. 配置Vite

Create
vite.config.ts
:
typescript
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.ts
typescript
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.ts
:
typescript
/**
 * 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
Why This Export Pattern:
  • Source: honojs/hono #3955
  • Using
    { fetch: app.fetch }
    causes: "Cannot read properties of undefined (reading 'map')"
  • Exception: If you need scheduled/tail handlers, use Module Worker format:
    typescript
    export default {
      fetch: app.fetch,
      scheduled: async (event, env, ctx) => { /* ... */ }
    }
创建
src/index.ts
typescript
/**
 * 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')"
  • 例外情况:若需要定时/尾处理器,使用Module Worker格式:
    typescript
    export default {
      fetch: app.fetch,
      scheduled: async (event, env, ctx) => { /* ... */ }
    }

Step 2: Create Static Frontend

步骤2:创建静态前端

Create
public/index.html
:
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>
Create
public/script.js
:
javascript
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.css
:
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;
}
创建
public/index.html
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
javascript
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
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;
}

Step 3: Update Package Scripts

步骤3:更新包脚本

Update
package.json
:
json
{
  "scripts": {
    "dev": "wrangler dev",
    "deploy": "wrangler deploy",
    "cf-typegen": "wrangler types"
  }
}
更新
package.json
json
{
  "scripts": {
    "dev": "wrangler dev",
    "deploy": "wrangler deploy",
    "cf-typegen": "wrangler types"
  }
}

Step 4: Test & Deploy

步骤4:测试与部署

bash
undefined
bash
undefined

Generate 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
export default app
(NOT
{ 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
index.html
instead of JSON Source: workers-sdk #8879 Prevention: Add
"run_worker_first": ["/api/*"]
to wrangler.jsonc
错误信息:API路由返回
index.html
而非JSON 来源workers-sdk #8879 预防方案:在wrangler.jsonc中添加
"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
@cloudflare/vite-plugin@1.13.13
or later
错误信息:开发过程中出现"A hanging Promise was canceled" 来源workers-sdk #9518 预防方案:使用
@cloudflare/vite-plugin@1.13.13
或更高版本

Issue #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
"not_found_handling": "single-page-application"
configuration means:
  • Unknown routes return
    index.html
  • Useful for React Router, Vue Router, etc.
  • BUT requires
    run_worker_first
    for API routes!
"not_found_handling": "single-page-application"
配置的含义:
  • 未知路由返回
    index.html
  • 适用于React Router、Vue Router等场景
  • !!!但必须为API路由配置
    run_worker_first
    !!!

Route Priority

路由优先级

With
"run_worker_first": ["/api/*"]
:
  1. /api/hello
    → Worker handles it (returns JSON)
  2. /
    → Static Assets serve
    index.html
  3. /styles.css
    → Static Assets serve
    styles.css
  4. /unknown
    → Static Assets serve
    index.html
    (SPA fallback)
配置
"run_worker_first": ["/api/*"]
后:
  1. /api/hello
    → 由Worker处理(返回JSON)
  2. /
    → 静态资源服务返回
    index.html
  3. /styles.css
    → 静态资源服务返回
    styles.css
  4. /unknown
    → 静态资源服务返回
    index.html
    (SPA fallback)

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
undefined
bash
undefined

Test GET endpoint

测试GET接口

Test POST endpoint

测试POST接口

curl -X POST http://localhost:8787/api/echo
-H "Content-Type: application/json"
-d '{"test": "data"}'
undefined
curl -X POST http://localhost:8787/api/echo
-H "Content-Type: application/json"
-d '{"test": "data"}'
undefined

Type Generation

类型生成

bash
npm run cf-typegen
Generates
worker-configuration.d.ts
with:
  • 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
undefined
bash
undefined

Deploy 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
  • wrangler.jsonc
    created with:
    • account_id
      set to your Cloudflare account
    • assets.directory
      pointing to
      ./public/
    • assets.run_worker_first
      includes
      /api/*
    • compatibility_date
      set to recent date
  • vite.config.ts
    created with
    @cloudflare/vite-plugin
  • src/index.ts
    created with Hono app
    • Uses
      export default app
      (NOT
      { fetch: app.fetch }
      )
    • Includes ASSETS binding type
    • Has fallback route:
      app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))
  • public/
    directory created with static files
  • npm run cf-typegen
    executed successfully
  • npm run dev
    starts without errors
  • 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
    ,包含:
    • account_id
      已设置为你的Cloudflare账户ID
    • assets.directory
      指向
      ./public/
    • assets.run_worker_first
      包含
      /api/*
    • compatibility_date
      设置为近期日期
  • 已创建
    vite.config.ts
    并配置
    @cloudflare/vite-plugin
  • 已创建
    src/index.ts
    并包含Hono应用
    • 使用
      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 staging
jsonc
// wrangler.jsonc
{
  "name": "my-worker",
  "env": {
    "staging": {
      "vars": { "ENV": "staging" }
    },
    "production": {
      "vars": { "ENV": "production" }
    }
  }
}
部署命令:
wrangler deploy --env staging

Custom 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-workers
Create
vitest.config.ts
:
typescript
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    poolOptions: {
      workers: {
        wrangler: { configPath: './wrangler.jsonc' },
      },
    },
  },
})
See
reference/testing.md
for complete testing guide.

bash
npm install -D vitest @cloudflare/vitest-pool-workers
创建
vitest.config.ts
typescript
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    poolOptions: {
      workers: {
        wrangler: { configPath: './wrangler.jsonc' },
      },
    },
  },
})
完整测试指南请查看
reference/testing.md

File Templates

文件模板

All templates are available in the
templates/
directory:
  • 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

官方文档

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:
All patterns in this skill have been validated in production.

Questions? Issues?
  1. Check
    reference/common-issues.md
    first
  2. Verify all steps in the 4-step setup process
  3. Ensure
    export default app
    (not
    { fetch: app.fetch }
    )
  4. Ensure
    run_worker_first
    is configured
  5. Check official docs: https://developers.cloudflare.com/workers/
本方案基于cloudflare-worker-base-test项目:
本方案中的所有模式均已通过生产环境验证。

有疑问?遇到问题?
  1. 首先查看
    reference/common-issues.md
  2. 验证四步搭建流程中的所有步骤
  3. 确保使用
    export default app
    (而非
    { fetch: app.fetch }
  4. 确保已配置
    run_worker_first
  5. 查看官方文档:https://developers.cloudflare.com/workers/