架构概述
OpenNext 并不创建底层基础设施。您可以使用偏好的工具(如 SST、AWS CDK、Terraform、Serverless Framework 等)为应用创建基础设施。
以下是推荐的基础架构方案。
我们将逐一解析 OpenNext 创建的各个组件。
静态资源文件
OpenNext 会生成一个 .open-next/assets
文件夹,其中包含经过哈希处理和未哈希处理的文件。这些文件可以直接提供服务,无需经过服务器函数处理。.open-next/assets
中的文件应该从网站根路径提供服务。例如,文件 .open-next/assets/favicon.ico
应该通过 /favicon.ico
路径访问。
.open-next/assets
文件夹中包含两种类型的文件:
哈希文件
这些文件名中包含哈希值,位于 .open-next/assets/_next
文件夹中,例如 .open-next/assets/_next/static/css/0275f6d90e7ad339.css
。当文件内容修改时,文件名中的哈希值会确保发生变化。因此,哈希文件应该在 CDN 和浏览器级别都进行缓存。推荐的缓存控制设置为:
public,max-age=31536000,immutable
非哈希文件
其他位于 .open-next/assets
文件夹中的文件是从应用的 public/
文件夹复制而来,例如 .open-next/assets/favicon.ico
。当内容修改时,非哈希文件的文件名可能保持不变。非哈希文件应该在 CDN 级别缓存,但不在浏览器级别缓存。当非哈希文件内容更新时,应在部署时使 CDN 缓存失效。推荐的缓存控制设置为:
public,max-age=0,s-maxage=31536000,must-revalidate
缓存文件
OpenNext 会创建一个 .open-next/cache
文件夹,其中包含增量缓存(即 ISR 和 SSG 路由)使用的缓存数据。这些文件不应公开访问。
.open-next/cache
文件夹中有两种类型的缓存:
- 路由缓存:该缓存包含构建期间预渲染的
html
、json
或rsc
文件。它们会被合并为一个.cache
文件,用于填充重新验证缓存。 - 获取缓存:该缓存包含 fetch 调用的响应,可能包含敏感信息。请确保这些文件不被公开访问。
图片优化后端
当使用 Next.js 的 <Image>
组件时,此后端会处理图片优化请求。它使用与函数捆绑的 sharp (opens in a new tab) 库来转换图片。该库针对选定架构(默认为 arm64
)编译,旨在 Node 环境中运行。
请注意,图片优化后端会返回带有 Cache-Control
头的响应,因此图片会在 CDN 层级和浏览器层级都被缓存。
更多详情请参阅 图片优化。
Servers Lambda 后端
这些后端处理来自 Next.js 应用的所有其他类型请求,包括服务端渲染(SSR)请求、增量静态再生(ISR)请求、静态站点生成(SSG)请求以及 API 请求。OpenNext 以 standalone 模式构建 Next.js 应用。standalone 模式会生成一个包含处理请求的 NextServer 类的 .next
文件夹,以及一个包含运行 NextServer
所需 所有依赖项 的 node_modules
文件夹。结构如下所示:
.next/ -> NextServer
node_modules/ -> 依赖项
服务器后端适配器封装了 NextServer
并导出一个支持 Lambda 请求和响应的处理函数。server-function
的打包结构如下:
.next/ -> NextServer
+ .open-next/
node_modules/ -> 依赖项
+ index.mjs -> 服务器函数适配器
Monorepo 项目结构
在 monorepo 项目中,构建输出的结构会略有不同。例如,如果应用位于 packages/web
目录下,构建输出将如下所示:
packages/
web/
.next/ -> NextServer 服务
node_modules/ -> 来自根 node_modules 的依赖项(可选)
node_modules/ -> 来自包 node_modules 的依赖项
这种情况下,需要在 packages/web
目录下(与 .next/
同级)创建 server function 适配器。这是为了确保适配器能够同时从两个 node_modules
文件夹导入依赖项。我们不建议将 Lambda 配置与项目结构耦合,因此不会直接将 Lambda 处理器设置为 packages/web/index.mjs
,而是在 server-function
包根目录添加一个包装器 index.mjs
来重新导出适配器。最终结构如下:
packages/
web/
.next/ -> NextServer 服务
+ .open-next/
node_modules/ -> 来自根 node_modules 的依赖项(可选)
+ index.mjs -> server function 适配器
node_modules/ -> 来自包 node_modules 的依赖项
+ index.mjs -> 适配器包装器
这样可以确保函数处理器始终位于 index.mjs
。
重新验证后端
OpenNext 会创建一个 .open-next/revalidation-function
文件夹,其中包含重新验证后端。
该后端用于处理来自重新验证队列的请求。重新验证队列是一个 FIFO 队列,包含需要重新验证的路由消息。重新验证后端会轮询队列中的消息,并向指定路由发送 HEAD 请求以触发重新验证。
预热后端
OpenNext 会创建一个 .open-next/warmer-function
文件夹,其中包含预热后端。
了解更多关于预热机制的工作原理。
标签提供者后端
该后端用于向重新验证表填充标签数据。