从零开始:Cloudflare Worker 开发与部署教程
前言:Serverless 的浪潮与 Cloudflare Workers 的崛起
在当今的云计算时代,Serverless(无服务器)架构以其按需付费、自动扩缩容、无需管理服务器等优点,成为了开发者构建应用的热门选择。它极大地简化了后端服务的部署与运维,让开发者能够更专注于业务逻辑的实现。
在众多 Serverless 平台中,Cloudflare Workers 凭借其独特的“全球边缘计算”能力脱颖而出。它允许开发者在 Cloudflare 遍布全球的数百个数据中心上运行 JavaScript、TypeScript 或 WebAssembly 代码。这意味着你的代码运行在离用户最近的网络边缘,极大缩短了请求延迟,提升了用户体验。无论是构建API服务、处理用户请求、分发静态内容,还是进行实时数据处理,Cloudflare Workers 都提供了强大的、高性能的解决方案。
本教程旨在为零基础的开发者提供一份详尽的 Cloudflare Worker 开发与部署指南。我们将从环境搭建开始,一步步带领你创建第一个 Worker,理解其核心概念,直至最终将其部署到全球网络。
第一章:准备工作——环境搭建与账户配置
在开始编写代码之前,我们需要确保开发环境和 Cloudflare 账户都已准备就绪。
1.1 注册 Cloudflare 账户
如果你还没有 Cloudflare 账户,请访问 Cloudflare 官方网站 进行注册。注册过程简单,只需提供邮箱和密码即可。完成注册后,你将拥有一个免费的账户,足以进行 Worker 的开发和部署(免费账户每月有慷慨的请求额度)。
1.2 安装 Node.js 与 npm/yarn
Cloudflare Workers 的开发工具 wrangler
是基于 Node.js 构建的,因此你需要安装 Node.js 运行时环境。Node.js 通常会自带 npm(Node Package Manager),如果你偏好 yarn,也可以额外安装。
- 下载 Node.js: 访问 Node.js 官方网站,下载并安装 LTS(长期支持)版本。
-
验证安装: 安装完成后,打开你的终端或命令行工具,运行以下命令验证是否安装成功:
bash
node -v
npm -v如果显示版本号,则表示安装成功。
1.3 安装 Cloudflare Wrangler CLI
wrangler
是 Cloudflare 官方提供的命令行工具,用于开发、测试和部署 Workers。它是我们与 Cloudflare Workers 平台交互的主要接口。
在终端中运行以下命令安装 wrangler
:
bash
npm install -g wrangler
或使用 yarn:
bash
yarn global add wrangler
-
验证安装: 安装完成后,运行以下命令:
bash
wrangler -v如果显示版本号,则表示
wrangler
已成功安装。
1.4 登录 Cloudflare 账户(通过 Wrangler CLI)
首次使用 wrangler
部署 Worker 时,你需要通过 CLI 登录 Cloudflare 账户。
在终端中运行:
bash
wrangler login
该命令会打开你的浏览器,跳转到 Cloudflare 的授权页面。点击“Allow”或“授权”按钮,即可完成登录。成功后,终端会显示登录成功的消息。
第二章:创建你的第一个 Cloudflare Worker
现在,所有准备工作就绪,我们可以开始创建第一个 Worker 了。
2.1 初始化 Worker 项目
wrangler init
命令用于初始化一个新的 Worker 项目。
在终端中,导航到你希望创建项目的目录,然后运行:
bash
wrangler init my-first-worker --type simple
my-first-worker
:这是你的项目名称,也是 Worker 的默认名称。--type simple
:指定项目类型为simple
。wrangler
支持多种项目类型:simple
(默认): 最简单的 JavaScript 模板,适合快速启动。webpack
: 包含 Webpack 配置的模板,适合需要打包复杂依赖的项目。typescript
: 包含 TypeScript 配置的模板,适合偏好 TypeScript 的开发者。hono
: 预配置了 Hono 框架的模板,适合构建更复杂的 Web 应用。
运行命令后,wrangler
会自动为你创建一个名为 my-first-worker
的文件夹,并生成必要的文件。
🥳 Created my-first-worker
2.2 项目结构概览
进入新创建的项目目录:
bash
cd my-first-worker
然后查看项目文件:
bash
ls
你将看到类似以下结构:
.
├── .gitattributes
├── .gitignore
├── package.json
├── package-lock.json (或 yarn.lock)
├── src
│ └── index.js
└── wrangler.toml
src/index.js
:这是 Worker 的主入口文件,你的核心代码将写在这里。wrangler.toml
:这是 Worker 的配置文件,包含了 Worker 的名称、入口文件、绑定(如 KV 存储、Durable Objects)等重要信息。package.json
:标准的 Node.js 项目配置文件,用于管理项目依赖。
2.3 理解 src/index.js
代码
打开 src/index.js
文件,你将看到一个简单的 JavaScript 代码:
``javascript
npm run dev
/**
* Welcome to Cloudflare Workers! This is your first worker.
*
* - Runin your terminal to start a development server
npm run deploy` to publish your worker
* - Open a browser tab at http://localhost:8787/ to see your worker in action
* - Run
*
* Learn more at https://developers.cloudflare.com/workers/
*/
export default {
async fetch(request, env, ctx) {
return new Response(‘Hello World!’);
},
};
“`
让我们逐行分析这段代码:
export default { ... };
:Cloudflare Workers 使用 ES Modules 语法。Worker 的核心逻辑通常暴露为一个默认导出的对象。async fetch(request, env, ctx) { ... }
:这是 Worker 的入口函数,当请求到达 Worker 时,Cloudflare 运行时会调用这个fetch
方法。它接收三个参数:request
:一个Request
对象,包含了客户端请求的所有信息,如 URL、请求方法、请求头、请求体等。env
:一个包含环境变量和绑定(如 KV 命名空间、Durable Objects 绑定、Secrets)的对象。你将在后续章节了解如何使用它。ctx
:一个ExecutionContext
对象,提供了用于管理 Worker 生命周期的方法,如waitUntil
,用于在响应发送后执行异步任务。
return new Response('Hello World!');
:这是 Worker 返回给客户端的响应。Response
对象是 Web Standard API 的一部分,可以包含响应体(字符串、JSON、HTML等)、状态码、响应头等信息。在这里,我们简单地返回了一个文本“Hello World!”。
2.4 理解 wrangler.toml
配置文件
打开 wrangler.toml
文件:
toml
name = "my-first-worker"
main = "src/index.js"
compatibility_date = "2024-05-18" # 或其他日期,取决于你创建项目时的最新日期
name
:Worker 的名称,也是 Cloudflare 仪表盘中显示的名称。main
:Worker 的入口文件路径,相对于wrangler.toml
文件。compatibility_date
:一个重要的配置项,它决定了你的 Worker 运行时所使用的 Cloudflare Workers 平台版本。设置一个日期可以确保你的 Worker 在未来保持行为一致,因为 Cloudflare 平台可能会引入新的功能或行为更改。建议始终使用最新的兼容性日期,除非有特定原因需要使用旧版本。
第三章:本地开发与测试
在部署到生产环境之前,我们应该先在本地测试 Worker 的功能。wrangler
提供了一个功能强大的本地开发服务器。
3.1 启动本地开发服务器
在 my-first-worker
项目目录下,运行:
bash
wrangler dev
wrangler
将启动一个本地开发服务器,并提供一个访问地址(通常是 http://localhost:8787/
)。
✨ Starting a local server...
🚧 "my-first-worker" listening on http://localhost:8787
3.2 测试你的 Worker
打开你的浏览器,访问 http://localhost:8787/
。你将看到页面显示 Hello World!
。
你也可以使用 curl
命令进行测试:
bash
curl http://localhost:8787/
输出应为:
Hello World!
3.3 热重载 (Hot Reloading)
wrangler dev
支持热重载。在 src/index.js
中修改 Hello World!
为 Hello Cloudflare Workers!
,然后保存文件。无需重启 wrangler dev
,刷新浏览器或再次运行 curl
,你就会看到更改后的响应。
javascript
export default {
async fetch(request, env, ctx) {
return new Response('Hello Cloudflare Workers!');
},
};
热重载极大地提高了开发效率,让你能够实时查看代码更改的效果。
第四章:部署你的 Cloudflare Worker
本地测试通过后,是时候将你的 Worker 部署到 Cloudflare 的全球网络了。
4.1 部署命令
在 my-first-worker
项目目录下,运行:
bash
wrangler deploy
如果你是首次部署,wrangler
可能会提示你选择一个 Zone(域名)来部署 Worker。通常,你会选择你的主域名或一个子域名。如果你还没有将域名添加到 Cloudflare,你需要先在 Cloudflare 仪表盘中添加并配置你的域名。
成功部署后,wrangler
会提供 Worker 的 URL:
✨ Successfully published my-first-worker
my-first-worker.YOUR_SUBDOMAIN.workers.dev
这里的 YOUR_SUBDOMAIN
通常是你的 Cloudflare 账户名称或一个随机生成的子域名。这个 URL 就是你的 Worker 的默认路由。
4.2 验证部署
打开浏览器,访问 my-first-worker.YOUR_SUBDOMAIN.workers.dev
(将 YOUR_SUBDOMAIN
替换为你的实际子域名),你将看到 Hello Cloudflare Workers!
。
现在,你的第一个 Worker 已经部署到全球的 Cloudflare 边缘节点,可以在极低的延迟下响应请求了!
第五章:Worker 进阶——构建更强大的应用
简单的“Hello World”只是 Worker 的冰山一角。下面我们将探索一些更高级的概念,以构建更实用的应用。
5.1 处理请求与路由
Worker 能够根据不同的请求路径、方法等信息,执行不同的逻辑。
修改 src/index.js
:
“`javascript
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url); // 解析请求URL
if (url.pathname === '/') {
return new Response('Welcome to the homepage!');
}
if (url.pathname === '/api/hello') {
const name = url.searchParams.get('name') || 'Guest'; // 获取查询参数
return new Response(`Hello, ${name}!`, {
headers: { 'Content-Type': 'text/plain' },
});
}
if (url.pathname === '/api/json') {
const data = {
message: 'This is a JSON response.',
timestamp: new Date().toISOString(),
};
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
});
}
// 默认处理未知路径
return new Response('404 Not Found', { status: 404 });
},
};
“`
new URL(request.url)
:将请求 URL 字符串转换为 URL 对象,方便解析路径 (pathname
)、查询参数 (searchParams
) 等。url.searchParams.get('name')
:获取 URL 中名为name
的查询参数值。JSON.stringify(data)
和Content-Type: application/json
:返回 JSON 格式的响应。
保存并重新 wrangler dev
或 wrangler deploy
,然后测试:
http://localhost:8787/
->Welcome to the homepage!
http://localhost:8787/api/hello?name=Alice
->Hello, Alice!
http://localhost:8787/api/json
->{"message":"This is a JSON response.","timestamp":"..."}
http://localhost:8787/some-other-path
->404 Not Found
5.2 使用 KV 存储(Key-Value Store)
Cloudflare KV 是一个超快的键值存储服务,非常适合存储小块数据(如配置、计数器、短链接映射等),并且数据会自动在全球范围内同步。
5.2.1 创建 KV 命名空间
首先,你需要在 Cloudflare 账户下创建一个 KV 命名空间。每个命名空间可以包含多个键值对。
在项目目录下运行:
bash
wrangler kv namespace create my_data_store
该命令会返回一个命名空间的 ID,并提示你将其添加到 wrangler.toml
中。
✨ Creating namespace "my_data_store"
Success! Namespace created. Add the following to your wrangler.toml:
kv_namespaces = [
{ binding = "MY_DATA_STORE", id = "YOUR_NAMESPACE_ID" }
]
5.2.2 配置 wrangler.toml
将上述输出添加到 wrangler.toml
文件的末尾(注意替换 YOUR_NAMESPACE_ID
为你实际获取到的 ID):
“`toml
… 其他配置 …
[[kv_namespaces]]
binding = “MY_DATA_STORE” # 这是在 Worker 代码中访问 KV 存储的变量名
id = “YOUR_NAMESPACE_ID” # 你的 KV 命名空间的实际 ID
“`
5.2.3 在 Worker 中使用 KV
现在,你可以在 Worker 中通过 env.MY_DATA_STORE
访问这个 KV 命名空间。
修改 src/index.js
:
“`javascript
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/data/put') {
const key = url.searchParams.get('key');
const value = url.searchParams.get('value');
if (key && value) {
await env.MY_DATA_STORE.put(key, value); // 写入数据
return new Response(`Stored ${key}: ${value}`);
}
return new Response('Missing key or value', { status: 400 });
}
if (url.pathname === '/data/get') {
const key = url.searchParams.get('key');
if (key) {
const value = await env.MY_DATA_STORE.get(key); // 读取数据
if (value) {
return new Response(`Value for ${key}: ${value}`);
}
return new Response(`Key "${key}" not found`, { status: 404 });
}
return new Response('Missing key', { status: 400 });
}
return new Response('Please use /data/put?key=xxx&value=xxx or /data/get?key=xxx', { status: 200 });
},
};
“`
部署并测试:
wrangler deploy
- 访问
https://my-first-worker.YOUR_SUBDOMAIN.workers.dev/data/put?key=message&value=hello_from_kv
- 访问
https://my-first-worker.YOUR_SUBDOMAIN.workers.dev/data/get?key=message
->Value for message: hello_from_kv
5.3 使用 Secrets (环境变量)
敏感信息(如 API 密钥、数据库凭证)绝不能直接写入代码中。Cloudflare Workers 提供了 Secrets 机制,让你能够安全地存储和访问这些信息。
5.3.1 设置 Secret
在项目目录下运行:
bash
wrangler secret put API_KEY
wrangler
会提示你输入 Secret 的值。输入后按回车。
5.3.2 在 Worker 中访问 Secret
Secret 会自动作为 env
对象的一个属性注入到 Worker 中。
修改 src/index.js
:
“`javascript
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/api/secret') {
// 敏感信息通过 env 对象访问
const apiKey = env.API_KEY;
if (apiKey) {
return new Response(`Your API Key (for demonstration): ${apiKey}`);
}
return new Response('API_KEY not set.', { status: 500 });
}
return new Response('Access the /api/secret path.', { status: 200 });
},
};
“`
部署并测试:
wrangler deploy
- 访问
https://my-first-worker.YOUR_SUBDOMAIN.workers.dev/api/secret
你将看到你设置的 API 密钥(在实际应用中,你不会直接返回 Secret 给客户端)。
5.4 使用 TypeScript
对于大型项目,TypeScript 能够提供更好的类型检查和代码提示,提高代码质量和开发效率。
如果最初你没有使用 --type typescript
初始化项目,你可以手动将其转换为 TypeScript 项目:
- 安装 TypeScript 和
@cloudflare/workers-types
:
bash
npm install --save-dev typescript @cloudflare/workers-types - 创建
tsconfig.json
文件:
json
{
"compilerOptions": {
"target": "es2022",
"lib": ["es2022"],
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"types": ["@cloudflare/workers-types"]
}
} - 将
src/index.js
重命名为src/index.ts
。 - 修改
wrangler.toml
的main
路径:
toml
main = "src/index.ts" -
现在你可以在
src/index.ts
中使用 TypeScript 编写代码了:“`typescript
export interface Env {
MY_DATA_STORE: KVNamespace; // 定义 KV 绑定类型
API_KEY: string; // 定义 Secret 类型
}export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise{
const url = new URL(request.url);if (url.pathname === '/api/typed-hello') { return new Response('Hello from TypeScript Worker!'); } // 可以继续使用 env.MY_DATA_STORE 和 env.API_KEY,现在它们有了类型提示 // ... return new Response('Hello Cloudflare Workers with TypeScript!');
},
};
“`
当运行 wrangler dev
或 wrangler deploy
时,wrangler
会自动使用 TypeScript 编译器将你的 .ts
文件编译成 JavaScript。
5.5 使用 Web 框架(如 Hono)
对于复杂的路由、中间件、请求验证等场景,直接使用原生的 fetch
API 可能会导致代码变得冗长。这时,可以考虑使用专门为 Worker 设计的轻量级 Web 框架,如 Hono、Itty Router 等。Hono 是一个非常流行且性能优异的选择。
5.5.1 安装 Hono
bash
npm install hono
5.5.2 在 Worker 中使用 Hono
修改 src/index.js
(或 src/index.ts
):
“`javascript
import { Hono } from ‘hono’;
const app = new Hono();
app.get(‘/’, (c) => c.text(‘Welcome to Hono-powered Worker!’));
app.get(‘/users/:id’, (c) => {
const id = c.req.param(‘id’);
return c.json({ id: id, name: User ${id}
});
});
app.post(‘/submit’, async (c) => {
const body = await c.req.json();
return c.json({ received: body, message: ‘Data submitted successfully!’ });
});
app.onError((err, c) => {
console.error(${err}
);
return c.text(‘Custom Error Message’, 500);
});
export default app;
“`
import { Hono } from 'hono';
:导入 Hono 框架。const app = new Hono();
:创建 Hono 应用实例。app.get()
,app.post()
:定义不同 HTTP 方法和路径的路由。c
:Hono 的上下文对象,包含了请求、响应、环境变量等信息。c.text()
,c.json()
:方便地返回文本或 JSON 响应。c.req.param('id')
:获取路径参数。c.req.json()
:异步解析 JSON 请求体。app.onError()
: 定义全局错误处理。
部署并测试:
wrangler deploy
- 访问
https://my-first-worker.YOUR_SUBDOMAIN.workers.dev/
->Welcome to Hono-powered Worker!
- 访问
https://my-first-worker.YOUR_SUBDOMAIN.workers.dev/users/123
->{"id":"123","name":"User 123"}
- 使用 POST 请求到
https://my-first-worker.YOUR_SUBDOMAIN.workers.dev/submit
,带 JSON Body{ "item": "test" }
第六章:调试与故障排除
尽管 Worker 运行在边缘,但 Cloudflare 提供了多种工具帮助你调试和排查问题。
6.1 console.log
与 Cloudflare Logs
在 Worker 代码中使用 console.log()
打印信息是最直接的调试方法。这些日志会显示在 wrangler dev
的终端中,同时也会发送到 Cloudflare 仪表盘的 Workers 日志(Logs)页面。
登录 Cloudflare 仪表盘,进入 Workers & Pages,选择你的 Worker,然后点击“Logs”选项卡,你可以实时查看 Worker 的请求日志和 console.log
输出。
6.2 wrangler tail
wrangler tail
命令允许你在本地终端实时接收 Cloudflare Worker 的生产日志。这对于调试部署后的 Worker 非常有用。
bash
wrangler tail -n 100 # 获取最近的 100 条日志
运行该命令后,当有请求到达你的 Worker 时,相关的日志(包括请求信息和 console.log
输出)会实时显示在你的终端中。
6.3 捕获错误
务必在 Worker 中实现错误捕获。例如,使用 try...catch
块来处理可能出错的异步操作。
javascript
export default {
async fetch(request, env, ctx) {
try {
// 尝试一些可能出错的操作,例如外部 API 调用
const response = await fetch('https://invalid.url.example.com');
if (!response.ok) {
throw new Error(`Failed to fetch: ${response.statusText}`);
}
const data = await response.json();
return new Response(JSON.stringify(data));
} catch (error) {
console.error('Worker Error:', error.message);
return new Response(`An error occurred: ${error.message}`, { status: 500 });
}
},
};
第七章:最佳实践与未来展望
7.1 安全性
- 永远不要在代码中硬编码敏感信息:使用
wrangler secret put
和env
对象来管理 API 密钥、密码等。 - 输入验证:对所有来自用户输入的请求参数、请求体进行严格的验证和清理,防止注入攻击(SQL 注入、XSS 等)。
- 最小权限原则:如果你的 Worker 与其他 Cloudflare 产品(如 R2, D1)交互,确保其拥有的权限是完成任务所需的最小权限。
7.2 性能优化
- 合理利用缓存:Cloudflare CDN 本身就提供强大的缓存能力。在 Worker 中,可以结合
Cache API
(通过caches.default
) 来缓存 Worker 自身产生的响应或上游服务的内容,减少重复计算和外部请求。 - 避免不必要的外部请求:尽可能在 Worker 内部处理逻辑,减少对外部服务的依赖。如果需要外部请求,考虑它们的延迟和失败率。
- 并发处理:对于多个独立的异步操作,使用
Promise.all()
进行并发处理,而不是顺序执行。 - Code Splitting(代码分割):对于大型 Worker,使用 Webpack 等工具进行代码分割,按需加载模块,减少首次加载时间。
7.3 代码组织
- 模块化:将 Worker 逻辑拆分为多个模块(
.js
或.ts
文件),保持index.js
/index.ts
的整洁,只作为入口文件和主路由。 - 错误处理:统一的错误处理机制,捕获未处理的异常,并返回友好的错误信息。
- 使用框架:对于复杂的 Web 服务,使用 Hono 等轻量级框架可以帮助你更好地组织路由、中间件和请求处理逻辑。
7.4 未来展望
Cloudflare Workers 生态系统正在迅速发展,不断推出新的服务和功能,与 Worker 紧密集成:
- Cloudflare R2:兼容 S3 的对象存储服务,可用于存储非结构化数据(图片、视频、文件)。
- Cloudflare D1:基于 SQLite 的 Serverless 数据库,让你可以在边缘运行 SQL 数据库。
- Cloudflare Queues:用于消息队列服务,实现异步任务处理。
- Cloudflare Durable Objects:提供有状态的 Serverless 应用,非常适合构建实时协作、聊天室等场景。
- Cloudflare AI Platform:在边缘运行 AI 推理模型,提供超低延迟的 AI 能力。
这些服务为开发者提供了构建全栈 Serverless 应用的强大工具集,未来 Cloudflare Workers 的应用场景将更加广阔。
总结
恭喜你!你已经从零开始,成功地创建、开发并部署了你的第一个 Cloudflare Worker。我们不仅学习了如何使用 wrangler
CLI 进行项目的初始化、本地开发和部署,还深入探讨了 Worker 的核心概念,并触及了 KV 存储、Secrets、TypeScript 以及 Web 框架等进阶话题。
Cloudflare Workers 凭借其独特的全球边缘计算能力,为开发者带来了前所未有的性能、可扩展性和开发效率。它不仅仅是一个简单的 FaaS(Function as a Service),更是一个强大的平台,让你能够在全球网络边缘构建高性能、低延迟的应用程序。
现在,你已经掌握了 Cloudflare Worker 的基础知识。未来,你可以尝试将你的 Worker 与 R2、D1、Durable Objects 等其他 Cloudflare 服务结合,构建更复杂、更强大的 Serverless 应用。持续学习和实践,你将能够驾驭这个令人兴奋的边缘计算世界!