Skip to content

Cloudflare Workers

Cloudflare Workers 是运行在 Cloudflare CDN 上的 JavaScript 边缘运行时。

通过 Wrangler 可以在本地开发,并只需几条命令就能发布。Wrangler 自带转译能力,因此可以直接编写 TypeScript 代码。

下面让我们使用 Hono 在 Cloudflare Workers 上创建第一个应用。

1. 环境准备

Cloudflare Workers 提供了启动模板,可用 create-hono 命令初始化项目。本示例选择 cloudflare-workers 模板。

sh
npm create hono@latest my-app
sh
yarn create hono my-app
sh
pnpm create hono my-app
sh
bun create hono@latest my-app
sh
deno init --npm hono my-app

进入 my-app 并安装依赖。

sh
cd my-app
npm i
sh
cd my-app
yarn
sh
cd my-app
pnpm i
sh
cd my-app
bun i

2. Hello World

src/index.ts 修改如下:

ts
import { Hono } from 'hono'
const app = new Hono()

app.get('/', (c) => c.text('Hello Cloudflare Workers!'))

export default app

3. 运行

在本地启动开发服务器,然后访问 http://localhost:8787

sh
npm run dev
sh
yarn dev
sh
pnpm dev
sh
bun run dev

修改端口

如果需要修改端口号,可参考以下文档更新 wrangler.toml/wrangler.json/wrangler.jsonc

或通过 CLI 参数配置:

4. 部署

拥有 Cloudflare 账号后即可部署。在 package.json 中,请将 $npm_execpath 替换为所用的包管理器。

sh
npm run deploy
sh
yarn deploy
sh
pnpm run deploy
sh
bun run deploy

完成以上步骤即可。

与其他事件处理器一起使用 Hono

在模块化 Worker 模式下,可以将 Hono 与其他事件处理器(例如 scheduled)结合使用。导出 app.fetch 作为模块的 fetch 处理器,并按需实现其他处理器:

ts
const app = new Hono()

export default {
  fetch: app.fetch,
  scheduled: async (batch, env) => {},
}

提供静态文件

若需提供静态文件,可使用 Cloudflare Workers 的静态资源功能。在 wrangler.toml 中指定目录:

toml
assets = { directory = "public" }

然后创建 public 目录并放置文件。例如 ./public/static/hello.txt 可通过 /static/hello.txt 访问。

.
├── package.json
├── public
│   ├── favicon.ico
│   └── static
│       └── hello.txt
├── src
│   └── index.ts
└── wrangler.toml

类型支持

如果想获得 Workers 类型定义,需要安装 @cloudflare/workers-types

sh
npm i --save-dev @cloudflare/workers-types
sh
yarn add -D @cloudflare/workers-types
sh
pnpm add -D @cloudflare/workers-types
sh
bun add --dev @cloudflare/workers-types

测试

推荐使用 @cloudflare/vitest-pool-workers 进行测试,可参考 examples 仓库 中的配置。

假设应用如下:

ts
import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Please test me!'))

可以通过以下测试验证是否返回 200 OK

ts
describe('Test the application', () => {
  it('Should return 200 response', async () => {
    const res = await app.request('http://localhost/')
    expect(res.status).toBe(200)
  })
})

绑定(Bindings)

在 Cloudflare Workers 中可以绑定环境变量、KV 命名空间、R2 Bucket、Durable Object 等。通过在 Hono 泛型中传入绑定类型结构体,即可在 c.env 中获取并拥有完整类型信息。

ts
type Bindings = {
  MY_BUCKET: R2Bucket
  USERNAME: string
  PASSWORD: string
}

const app = new Hono<{ Bindings: Bindings }>()

// 访问环境值
app.put('/upload/:key', async (c) => {
  const key = c.req.param('key')
  await c.env.MY_BUCKET.put(key, c.req.body)
  return c.text(`Put ${key} successfully!`)
})

在中间件中使用变量

在模块化 Worker 模式下,如果希望在中间件中使用变量或机密变量(如 Basic Auth 中的用户名和密码),可以这样编写:

ts
import { basicAuth } from 'hono/basic-auth'

type Bindings = {
  USERNAME: string
  PASSWORD: string
}

const app = new Hono<{ Bindings: Bindings }>()

// ...

app.use('/auth/*', async (c, next) => {
  const auth = basicAuth({
    username: c.env.USERNAME,
    password: c.env.PASSWORD,
  })
  return auth(c, next)
})

同样适用于 Bearer 认证、JWT 认证等其他中间件。

通过 GitHub Actions 部署

在 CI 中将代码部署到 Cloudflare,需要先创建 Cloudflare Token。可在 User API Tokens 中管理。

如果是新建 Token,请选择 Edit Cloudflare Workers 模板;若使用已有 Token,请确保其拥有相应权限(Cloudflare Pages 与 Workers 的 Token 权限并不通用)。

随后在 GitHub 仓库的 Settings -> Secrets and variables -> Actions -> Repository secrets 中新增名为 CLOUDFLARE_API_TOKEN 的机密。

在项目根目录创建 .github/workflows/deploy.yml 并写入:

yml
name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

随后在 wrangler.toml 中、compatibility_date 行之后加入:

toml
main = "src/index.ts"
minify = true

至此一切就绪,提交代码即可。

本地开发时加载环境变量

在项目根目录创建 .dev.vars.env 文件,为本地开发配置环境变量。这些文件应采用 dotenv 格式,例如:

SECRET_KEY=value
API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

更多信息请参见 Cloudflare 文档:https://developers.cloudflare.com/workers/wrangler/configuration/#secrets

随后即可通过 c.env.* 在代码中读取这些变量。

INFO

默认情况下,Cloudflare Workers 中无法使用 process.env,建议通过 c.env 获取环境变量。如需使用 process.env,请启用 nodejs_compat_populate_process_env 标志,或从 cloudflare:workers 导入 env。详细说明参见 Cloudflare 文档:如何访问 env

ts
type Bindings = {
  SECRET_KEY: string
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/env', (c) => {
  const SECRET_KEY = c.env.SECRET_KEY
  return c.text(SECRET_KEY)
})

在将项目部署到 Cloudflare 之前,别忘了在 Cloudflare Workers 的项目配置中设置对应的环境变量或机密。

更多信息请参考 Cloudflare 文档:https://developers.cloudflare.com/workers/configuration/environment-variables/#add-environment-variables-via-the-dashboard

Released under the MIT License.