通用基础项目
11. 重构为worker
会员专享 · 非会员仅可阅读 30% 的正文。
- 发布时间
- May 17, 2025
- 阅读时间
- 7 min read
- 作者
- Felix
- 访问
- 会员专享
这是预览内容
非会员仅可阅读 30% 的正文。
基础配置流程
将Next.js应用重构为Cloudflare Worker需要一些下面的配置和操作,但其实代码已经写好了在Tag里,只是讲一下过程。
下载依赖、修改配置文件、添加脚本
首先执行pnpm add @opennextjs/cloudflare,紧接着完成wrangler.jsonc的配置,这部分配置会在上传到Cloudflare的时候自动完成绑定。
重构的配置是这些:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "cloudflare-template",
"main": ".open-next/worker.js",
"compatibility_date": "2025-04-22",
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
"observability": {
"logs": {
"enabled": true
}
},
"assets": {
"directory": ".open-next/assets",
"binding": "ASSETS"
},
"ai": {
"binding": "AI"
},
"r2_buckets": [
{
"bucket_name": "demo",
"binding": "NEXT_INC_CACHE_R2_BUCKET"
}
],
"durable_objects": {
"bindings": [
{
"name": "NEXT_CACHE_DO_QUEUE",
"class_name": "DOQueueHandler"
},
{
"name": "NEXT_TAG_CACHE_DO_SHARDED",
"class_name": "DOShardedTagCache"
}
]
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache"]
}
],
"services": [
{
"binding": "WORKER_SELF_REFERENCE",
"service": "cloudflare-template"
}
]
}
```
- `$schema`: 指向配置文件的JSON Schema,提供编辑器自动完成功能。
- `name`: Worker的名称,这将是你的 Worker 在 Cloudflare 控制台中显示的名称,也是访问 Worker 时使用的子域名的一部分。
- `main`: Worker的入口文件,对于 OpenNext 项目,这通常是构建后生成的 .open-next/worker.js 文件。
- `compatibility_date`: 指定Worker运行时版本的日期,Cloudflare 会根据这个日期确定使用哪个版本的 Workers 运行时。
- `compatibility_flags`: 启用Node.js兼容层和公共URL请求功能
- `observability`: 启用日志记录,方便在Cloudflare控制台查看运行日志
- `assets`: 配置静态资源
- `directory`: 静态资源目录
- `binding`: 在Worker中访问资源的变量名,也是我们在环境中写的变量名。
- `ai`: 绑定Cloudflare AI服务,可用于文本生成、图像处理等AI功能
- `r2_buckets`: 配置R2存储桶
- `bucket_name`: 存储桶名称
- `binding`: 创建一个名为 `NEXT_INC_CACHE_R2_BUCKET` 的绑定,用于 Next.js 的增量缓存
- `durable_objects`: 配置有状态存储服务
- `NEXT_CACHE_DO_QUEUE`: 处理Next.js缓存队列
- `NEXT_TAG_CACHE_DO_SHARDED`: 处理Next.js标签缓存
- `migrations`: 为Durable Objects创建SQLite数据库
- `services`: 这个配置允许 Worker 引用自己,这在某些需要 Worker 调用自身的场景中很有用,比如实现某些递归操作或分布式处理。
在package.json中添加以下脚本,简化开发和部署流程:
```json
"scripts": {
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"upload": "opennextjs-cloudflare build && opennextjs-cloudflare upload",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
```
这些命令分别用于:
- preview: 构建应用并在本地Workers运行时预览,让你通过单个命令快速预览应用
- deploy: 构建并立即部署到Cloudflare
- upload: 构建并上传新版本到Cloudflare
- cf-typegen: 在项目根目录生成包含env类型的cloudflare-env.d.ts文件
紧接着跑一下`pnpm cf-typegen`自动生成项目的类型,这个命令在每次新增绑定的服务的时候都可以调用一下,用于生成类型,便于语法提示。
### 配置文件设置
虽然在构建过程中`@opennextjs/cloudflare`会自动创建配置文件(如果不存在),但你也可以自己创建。除了上面的`wrangler.jsonc`配置外,还需要创建一个`open-next.config.ts`文件:
```typescript
import { defineCloudflareConfig } from '@opennextjs/cloudflare'
import r2IncrementalCache from '@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache'
import doQueue from '@opennextjs/cloudflare/overrides/queue/do-queue'
import doShardedTagCache from '@opennextjs/cloudflare/overrides/tag-cache/do-sharded-tag-cache'
export default defineCloudflareConfig({
incrementalCache: r2IncrementalCache,
tagCache: doShardedTagCache({ baseShardSize: 12, regionalCache: true }),
queue: doQueue
})
```
这个配置是启用了Cloudflare的缓存以支持Nextjs的缓存功能。
### 静态资源缓存优化
创建`public/_headers`文件,添加缓存控制:
```
/_next/static/*
Cache-Control: public,max-age=31536000,immutable
```
这能确保静态资源得到适当缓存,提高加载速度。更多信息可以参考静态资源缓存文档。
### 修改Next.js配置
更新`next.config.ts`文件,添加Cloudflare开发集成:
```typescript
import { initOpenNextCloudflareForDev } from '@opennextjs/cloudflare'
import { NextConfig } from 'next'
import createNextIntlPlugin from 'next-intl/plugin'
initOpenNextCloudflareForDev()
const nextConfig: NextConfig = {
devIndicators: false,
experimental: {
staleTimes: {
dynamic: 3600,
static: 3600
}
}
}
const withNextIntl = createNextIntlPlugin({
experimental: {
createMessagesDeclaration: './messages/en.json'
}
})
export default withNextIntl(nextConfig)
```
添加`initOpenNextCloudflareForDev()`调用后,你可以在本地开发过程中访问Cloudflare绑定的本地版本,如绑定文档中所述。
我们在第3步中还添加了`npm run preview`命令,它允许你在Workers运行时而不是Node.js中快速预览应用。这使你能够在与部署到Cloudflare时相同的运行时中测试更改。
### 替换移除代码
- 移除任何`export const runtime = "edge";`声明,因为@opennextjs/cloudflare不支持edge运行时。
- 移除`@cloudflare/next-on-pages`这个包。
- 用`@opennextjs/cloudflare`中的`getCloudflareContext`替换`@cloudflare/next-on-pages`中的`getRequestContext`
### 部署
- 通过Push,CL会自己完成部署。
- `pnpm deploy:c`会读取本地的`.env`文件进行部署。
## Cloudflare如何实现Nextjs的缓存
> 接下来讲一下原理源码,这部分的内容是属于可看可不看的,这是满足我对技术的好奇心以及对使用一门新技术的安全感。
[官方的简单文档](https://opennext.js.org/cloudflare/caching)
Next.js提供了多种通过缓存路由和网络请求来提高应用性能的方法。应用程序会尝试在构建时预渲染并缓存尽可能多的数据,以减少向用户提供响应时所需的工作量。
缓存数据通过重新验证进行更新,可以是定期的或按需的:
- **基于时间的重新验证**:在应用程序指定的重新验证延迟过期后更新缓存数据
- **按需重新验证**:允许通过特定标签(通过`revalidateTag`)或在给定路径(通过`revalidatePath`)使缓存条目无效。
`@opennextjs/cloudflare`的缓存支持依赖于3个组件:
1. **增量缓存(Incremental Cache)**:存储缓存数据
2. **队列(Queue)**:同步和去重基于时间的重新验证
3. **标签缓存(Tag Cache)**:用于通过`revalidateTag`和`revalidatePath`进行按需重新验证
### 缓存实现
而对于这三者的实现我采用的是:
- **增量缓存**:使用R2存储数据,[源码地址](https://github1s.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src/api/overrides/incremental-cache/r2-incremental-cache.ts)
- **队列**:使用由Durable Objects实现的时间验证队列,[源码地址](https://github1s.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src/api/durable-objects/queue.ts)
- **标签缓存**:使用由Durable Objects实现的缓存验证系统,[源码地址](https://github1s.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src/api/durable-objects/sharded-tag-cache.ts)
### R2增量缓存实现原理
R2增量缓存是Next.js在Cloudflare环境中存储缓存数据的主要机制。它利用Cloudflare的R2对象存储服务,提供高性能、低成本的数据存储解决方案。
R2增量缓存实现了标准的Next.js增量缓存接口,包括`get`、`set`和`delete`方法,使其能够无缝集成到Next.js的缓存系统中。
核心实现代码如下:
```typescript
class R2IncrementalCache implements IncrementalCache {会员专享
订阅后解锁完整文章
支持创作、解锁全文,未来更新也会第一时间送达。
评论
加入讨论
登录后评论
还没有评论,来占个沙发吧。