JackyLove 的技术人生

人生艰难,唯有一技傍身才能慢慢走向通途。个人博客,记录生活,分享技术,记录成长。专注全栈技术,next技术。

第17章—配置篇路由段配置项

首次发表于 2024-03-22, 更新于 2024-03-22

前言

之前的文章中已经多次提到了路由段配置项,路由段配置选项可以配置页面、布局、路由处理程序的行为,本篇我们会详细介绍其中的配置内容。

1. 段(Segment)

如果大家翻阅 Next.js 的官方文档(英文),会经常发现 Segment 这个单词,其释义为:

image.png

为了简单起见,我翻译成“段”。Segment 放到 URL 这个场景时:

URL Segment 指的是由斜杠分隔的 URL Path 的一部分 URL Path 指的则是域名后面的 URL 部分(URL Path 由 URL Segment 组成)

用这张图表示更清晰一些:

image.png

Segment 放到 Route 这个场景时:

Router Segment,我翻译为“路由段”,路由中的每个文件夹都代表一个路由段。每个路由段都映射一个对应的 URL Segment:

image.png

在这张图中,/dashboard/settings由三段组成:

  • /:根段(Root Segment)
  • dashboard:段(Segment)
  • settings:叶段(Leaf Segment)

PS:叶段指的是没有子节点的段。

2. 路由段配置(Route Segment Config)

接下来我们来到本章的正题——路由段配置。

路由段配置选项可以配置页面、布局、路由处理程序的行为。比如我们使用 fetch 的时候可以单独配置某个请求的 revalidate ,借助路由段配置,我们可以配置这个路由下所有 fetch 请求的 revalidate

路由段配置的使用方式也很简单,导出一个约定变量名即可,比如:

// layout.js | page.js | route.js
export const dynamic = 'auto'
export const dynamicParams = true
export const revalidate = false
export const fetchCache = 'auto'
export const runtime = 'nodejs'
export const preferredRegion = 'auto'
export const maxDuration = 5
 
export default function MyComponent() {}

具体这些变量名和值的类型为:

变量名 类型 默认值
dynamic 'auto' | 'force-dynamic' | 'error' | 'force-static' 'auto'
dynamicParams boolean true
revalidate false | 'force-cache' | 0 | number false
fetchCache 'auto' | 'default-cache' | 'only-cache' | 'force-cache' | 'force-no-store' | 'default-no-store' | 'only-no-store' 'auto'
runtime 'nodejs' | 'edge' 'nodejs'
preferredRegion 'auto' | 'global' | 'home' | string | string[] 'auto'
maxDuration number 部署平台设置

注意配置选项的值目前是静态分析的,也就是说,配置revalidate = 600是有效的,但是 revalidate = 60 * 10是无效的。

我们来一一讲解这些配置选项的作用。

2.1. dynamic

更改布局或者页面的动态行为,用例如下:

// layout.js | page.js | route.js
export const dynamic = 'auto'
// 'auto' | 'force-dynamic' | 'error' | 'force-static'

为了讲解 dynamic 参数的选项,我们先复习下基础知识:

所谓静态渲染(Static Rendering),指的是路由在构建时渲染,或者在重新验证后后台渲染,其结果会被缓存并可以推送到 CDN。适用于未针对用户个性化且数据已知的情况,比如静态博客文章、产品介绍页面等。

所谓动态渲染(Dynamic Rendering),指的是路由在请求时渲染,适用于针对用户个性化或依赖请求中的信息(如 cookie、URL 参数)的情况。

因为渲染模式和数据缓存是相互独立的,所以在动态渲染下,数据请求也分为缓存和不缓存(uncached data request)的。默认是缓存,这样做的好处在于,即便选择了动态渲染,也不用担心渲染时获取所有数据对性能造成影响。

dynamic 影响的不仅是渲染模式,也会影响数据缓存的方式。

还有一个名词叫动态函数(Dynamic Functions),指的是获取只能在请求时才能得到的信息(如 cookie、请求头、URL 参数)的函数,在 Next.js 中,对应的就是 cookies()headers()useSearchParams()searchParams() 这些函数。如果使用了这些函数的任意一个,都会导致路由进行动态渲染。

接下来我们讲解 dynamic 的值都有哪些作用:

  • 'auto'(默认):自动判断
  • 'force-dynamic',强制动态渲染和退出所有 fetch 请求缓存,相当于:
    • Page Router 下使用了 getServerSideProps()
    • 将布局或页面中每个 fetch() 请求都设置为 { cache: 'no-store', next: { revalidate: 0 } }
    • 设置了路由段配置 export const fetchCache = 'force-no-store'
  • 'error'强制静态渲染并缓存数据,如果有组件使用了动态函数或不缓存数据请求(uncached data request),就会导致错误,相当于:
    • Page Router 下使用了getStaticProps()
    • 将布局或页面中每个 fetch() 请求都设置为 { cache: 'force-cache' }
    • 设置了路由段配置 fetchCache = 'only-cache', dynamicParams = false
    • 设置dynamic = 'error' 会更改 dynamicParams 的默认值 truefalse
  • 'force-static' 强制静态渲染并缓存数据,强制 cookies()headers()useSearchParams() 返回空值。

2.2. dynamicParams

控制当访问不是由 generateStaticParams 生成的动态路由段的时候发生什么。

// layout.jsx | page.jsx
export const dynamicParams = true // true | false,
  • true(默认):按需生成
  • false:返回 404

这个选项对应 Page Router 下的 getStaticPathsfallback: true | false | blocking选项。

如果使用了 dynamic = 'error'dynamic = 'force-static',它会更改 dynamicParams 的默认值为 false

2.3. revalidate

设置布局或者页面的默认验证时间。此设置不会覆盖单个 fetch 请求设置的 revalidate 的值。注意 revalidate 选项只能用于 Nodejs Runtime,不能用于 Edge Runtime。

// layout.jsx | page.jsx | route.js
export const revalidate = false
// false | 'force-cache' | 0 | number
  • false(默认),语义上相当于 revalidate: Infinity,资源无限期缓存。
  • 0,页面或布局总是动态渲染,即使没有使用动态函数或者不缓存数据请求(uncached data request)。
  • number :设置布局或页面的默认重新验证频率,以秒为单位。

关于重新验证频率,一个路由可能有多个布局和一个页面,此时会选择最低的 revalidate 值作为路由的重新验证频率。这是为了确保子路由的重新验证时间频率和父布局保持一致。此外,单个 fetch 请求可以设置比路由默认的 revalidate 值更低的 revalidate 值,这会增加整个路由的重新验证频率。这允许你根据某些动态条件进行更频繁的重新验证。

2.4. fetchCache

这是一个高级选项,仅当你特别需要覆盖默认行为时才应该使用。为了解释这个选项,我们先复习下 fetch 请求的 options.cache 选项:

fetch(`https://...`, { cache: 'force-cache' | 'no-store' })

其中 force-cache是默认值,表示优先从缓存中查找匹配请求,当没有匹配项或者匹配项过时时,才从服务器上获取资源并更新缓存。no-store表示每次请求都从服务器上获取资源,不从缓存中查,也不更新缓存。

回到 Next.js,默认情况下,Next.js 会缓存在动态函数使用之前的 fetch 请求,不会缓存任何动态函数之后的fetch 请求。而 fetchCache 允许你覆盖布局或者页面中所有的 fetch请求的默认 cache选项。

// layout.jsx | page.jsx | route.js
export const fetchCache = 'auto'
// 'auto' | 'default-cache' | 'only-cache'
// 'force-cache' | 'force-no-store' | 'default-no-store' | 'only-no-store'
  • 'auto'(默认):动态函数之前按照开发者设置的 cache 选项进行缓存,动态函数之后不缓存请求
  • 'default-cache':开发者可以自由设置 cache 选项,但如果开发者未设置 cache 选项,默认设置为 force-cache,这意味着即使是在动态函数之后的请求,也会被视为静态
  • 'only-cache':如果开发者未设置 cache 选项,默认设置为 force-cache,如果有请求设置成 cache: 'no-store',则会导致报错
  • 'force-cache':将所有请求的 cache 选项设置为 force-cache
  • 'default-no-store':开发者可以自由设置 cache 选项,但如果开发者未设置 cache 选项,默认设置为 no-store,这意味着即使是在动态函数之前的请求,也会被视为动态。
  • 'only-no-store':如果开发者未设置 cache 选项,默认设置为 no-store,如果有请求设置成 cache: 'force-cache',则会导致报错
  • 'force-no-store':将所有请求的 cache 选项设置为 no-store

一个路由可能有多个布局和一个页面,此时选项应该相互兼容:

  • 如何 'only-cache''force-cache' 同时提供,'force-cache' 获胜。如果 'only-no-store''force-no-store'同时提供,'force-no-store'获胜。带 force 的选项会更改整个路由的行为,并会阻止 'only-*' 引发的错误。
  • 'only-*'force-*'选项的作用就是确保整个路由要么是完全静态要么是完全动态,这意味着:
    • 在单个路由中不允许同时使用 'only-cache''only-no-store'
    • 在单个路由中不允许同时使用 'force-cache''force-no-store'
  • 如果子级提供了 'auto''*-cache',父级无法使用 'default-no-store',因为这会导致请求有不同的行为。

Next.js 建议共享的父布局使用 'auto',在子级中自定义不同的选项。

2.5. runtime

设置运行时环境,具体参考小册《渲染篇 | Streaming 和 Edge Runtime》

// layout.jsx | page.jsx | route.js
export const runtime = 'nodejs'
// 'edge' | 'nodejs'
  • nodejs(默认)
  • edge

2.6. preferredRegion

Vercel Serverless Functions 中使用,搭配 export const runtime = 'edge'; ,用于设置 Edge Functions 执行的区域,默认情况下,Edge Functions 在最接近传入请求的区域中执行,但如果你的函数比较依赖数据源,你会更希望它靠近数据源所在的位置以实现快速响应,那就可以设置 preferredRegion 指定一系列首选区域。

指定区域的时候,传入的是区域 ID,区域列表参考 Vercel 的 Region List 文档,其中 iad1 表示美国东部区域,参考位置美国华盛顿地区,sfo1 表示美国西部,参考位置美国旧金山。

// layout.jsx | page.jsx | route.js
export const preferredRegion = 'auto'
// 'auto' | 'global' | 'home' | ['iad1', 'sfo1']

2.7. maxDuration

Vercel Serverless Functions 中使用,用于配置 Vercel 函数的最大持续时间,所谓 Max duration,指的是函数在响应之前可以处理 HTTP 请求的最长时间。如果持续时间内没有响应,则会返回错误码。如果没有指定,根据不同的部署平台,默认时间会不同。

export const maxDuration = 5

2.8 generateStaticParams

与动态路由搭配使用,用于定义静态生成的路由段参数。具体内容参考小册《API 篇 | 路由相关的常用方法》

参考链接

  1. https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
  2. https://vercel.com/docs/functions/configuring-functions/region
© Copyright 2025 JackyLove 的技术人生. Powered with by CreativeDesignsGuru