AWS
默认架构

架构概述

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 文件夹中有两种类型的缓存:

  • 路由缓存:该缓存包含构建期间预渲染的 htmljsonrsc 文件。它们会被合并为一个 .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 文件夹,其中包含预热后端。

了解更多关于预热机制的工作原理

标签提供者后端

该后端用于向重新验证表填充标签数据。