Menu

如何升级到版本 16

从 15 升级到 16

使用 AI Agents 和 Next.js DevTools MCP

如果你正在使用支持 Model Context Protocol (MCP) 的 AI 编码助手,可以使用 Next.js DevTools MCP 来自动化升级过程和迁移任务。

设置

将以下配置添加到你的 MCP 客户端,例如:

{
  "mcpServers": {
    "next-devtools": {
      "command": "npx",
      "args": ["-y", "next-devtools-mcp@latest"]
    }
  }
}

有关更多信息,请访问 npm 上的 next-devtools-mcp 包,以配置你的 MCP 客户端。

注意: 使用 next-devtools-mcp@latest 可确保你的 MCP 客户端始终使用最新版本的 Next.js DevTools MCP 服务器。

示例提示

配置完成后,你可以使用自然语言提示来升级你的 Next.js 应用:

升级到 Next.js 16:

连接到你的编码代理,然后提示:

Next Devtools, help me upgrade my Next.js app to version 16

迁移到 Cache Components(升级到 v16 后):

连接到你的编码代理,然后提示:

Next Devtools, migrate my Next.js app to cache components

了解更多信息,请参阅文档 这里

使用 Codemod

要更新到 Next.js 版本 16,你可以使用 upgrade codemod

Terminal
npx @next/codemod@canary upgrade latest

codemod 能够:

  • 更新 next.config.js 以使用新的 turbopack 配置
  • next lint 迁移到 ESLint CLI
  • 从已弃用的 middleware 约定迁移到 proxy
  • 从稳定的 API 中删除 unstable_ 前缀
  • 从页面和布局中删除 experimental_ppr Route Segment Config

如果你更喜欢手动操作,请安装最新的 Next.js 和 React 版本:

Terminal
npm install next@latest react@latest react-dom@latest

如果你使用 TypeScript,请确保也将 @types/react@types/react-dom 升级到最新版本。

Node.js 运行时和浏览器支持

要求变更 / 详情
Node.js 20.9+最低版本现在是 20.9.0(LTS);不再支持 Node.js 18
TypeScript 5+最低版本现在是 5.1.0
浏览器Chrome 111+、Edge 111+、Firefox 111+、Safari 16.4+

默认使用 Turbopack

Next.js 16 开始,Turbopack 已稳定,并默认与 next devnext build 一起使用。

以前你必须使用 --turbopack--turbo 来启用 Turbopack。

package.json
{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build --turbopack",
    "start": "next start"
  }
}

这不再需要。你可以更新你的 package.json 脚本:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

如果你的项目有自定义 webpack 配置,并且你运行 next build(现在默认使用 Turbopack),构建将失败以防止配置错误问题。

你有几种不同的方法来解决这个问题:

  • 仍然使用 Turbopack: 使用 next build --turbopack 运行以使用 Turbopack 构建并忽略你的 webpack 配置。
  • 完全切换到 Turbopack: 将你的 webpack 配置迁移到 Turbopack 兼容的选项。
  • 继续使用 Webpack: 使用 --webpack 标志退出 Turbopack 并使用 Webpack 构建。

值得注意的是:如果你看到因为找到了 webpack 配置而导致构建失败,但你自己没有定义配置,很可能是某个插件添加了 webpack 选项

退出 Turbopack

如果你需要继续使用 Webpack,可以使用 --webpack 标志退出。例如,在开发中使用 Turbopack,但在生产构建中使用 Webpack:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build --webpack",
    "start": "next start"
  }
}

我们建议在开发和生产中都使用 Turbopack。如果你无法切换到 Turbopack,请在此讨论串中提交评论。

Turbopack 配置位置

experimental.turbopack 配置已不再是实验性的。

next.config.ts
import type { NextConfig } from 'next'
 
// Next.js 15 - experimental.turbopack
const nextConfig: NextConfig = {
  experimental: {
    turbopack: {
      // options
    },
  },
}
 
export default nextConfig

你可以将其用作顶级 turbopack 选项:

next.config.ts
import type { NextConfig } from 'next'
 
// Next.js 16 - turbopack 位于 nextConfig 的顶层
const nextConfig: NextConfig = {
  turbopack: {
    // options
  },
}
 
export default nextConfig

请务必查看 Turbopack 配置选项Next.js 16 引入了各种改进和新选项,例如:

Resolve alias fallback

在某些项目中,客户端代码可能会导入包含 Node.js 原生模块的文件。这将导致 Module not found: Can't resolve 'fs' 类型的错误。

发生这种情况时,你应该重构代码,使客户端包不引用这些 Node.js 原生模块。

但是,在某些情况下,这可能无法实现。在 Webpack 中,通常使用 resolve.fallback 选项来消除错误。Turbopack 提供了类似的选项,使用 turbopack.resolveAlias。在这种情况下,告诉 Turbopack 在浏览器请求 fs 时加载一个空模块。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  turbopack: {
    resolveAlias: {
      fs: {
        browser: './empty.ts', // 我们建议在使用此方法之前修复代码导入
      },
    },
  },
}
 
export default nextConfig

最好重构你的模块,使客户端代码永远不会从使用 Node.js 原生模块的模块导入。

Sass node_modules 导入

Turbopack 完全支持从 node_modules 导入 Sass 文件。请注意,虽然 Webpack 允许使用传统的波浪号(~)前缀,但 Turbopack 不支持此语法。

在 Webpack 中:

styles/globals.scss
@import '~bootstrap/dist/css/bootstrap.min.css';

在 Turbopack 中:

styles/globals.scss
@import 'bootstrap/dist/css/bootstrap.min.css';

如果无法更改导入,可以使用 turbopack.resolveAlias。例如:

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  turbopack: {
    resolveAlias: {
      '~*': '*',
    },
  },
}
 
export default nextConfig

Turbopack 文件系统缓存(beta)

Turbopack 现在支持开发中的文件系统缓存,在运行之间将编译器工件存储在磁盘上,以显著加快重启时的编译时间。

在你的配置中启用文件系统缓存:

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  experimental: {
    turbopackFileSystemCacheForDev: true,
  },
}
 
export default nextConfig

异步请求 API(破坏性变更)

版本 15 引入了异步请求 API 作为破坏性变更,并提供临时的同步兼容性。

Next.js 16 开始,同步访问完全删除。这些 API 只能异步访问。

使用 codemod 迁移到异步 Dynamic API。

迁移异步 Dynamic API 的类型

为了帮助迁移到异步 paramssearchParams,你可以运行 npx next typegen 来自动生成这些全局可用的类型辅助程序:

值得注意的是typegen 在 Next.js 15.5 中引入

这简化了对新异步 API 模式的类型安全迁移,并使你能够以完全的类型安全性更新组件,例如:

/app/blog/[slug]/page.tsx
export default async function Page(props: PageProps<'/blog/[slug]'>) {
  const { slug } = await props.params
  const query = await props.searchParams
  return <h1>Blog Post: {slug}</h1>
}

这种方法为你提供了对 props.params(包括 slug)和 searchParams 的完全类型安全访问,直接在你的页面中。

icon 和 open-graph Image 的异步参数(破坏性变更)

传递给 opengraph-imagetwitter-imageiconapple-icon 中图像生成函数的 props 现在是 Promise。

在以前的版本中,Image(图像生成函数)和 generateImageMetadata 都接收一个 params 对象。generateImageMetadata 返回的 id 作为字符串传递给图像生成函数。

app/shop/[slug]/opengraph-image.js
// Next.js 15 - 同步 params 访问
export function generateImageMetadata({ params }) {
  const { slug } = params
  return [{ id: '1' }, { id: '2' }]
}
 
// Next.js 15 - 同步 params 和 id 访问
export default function Image({ params, id }) {
  const slug = params.slug
  const imageId = id // string
  // ...
}

Next.js 16 开始,为了与异步请求 API 变更保持一致,这些也是异步的。

app/shop/[slug]/opengraph-image.js
// Next.js 16 - 异步 params 访问
export async function generateImageMetadata({ params }) {
  const { slug } = await params
  return [{ id: '1' }, { id: '2' }]
}
 
// Next.js 16 - 异步 params 和 id 访问
export default async function Image({ params, id }) {
  const { slug } = await params // params 现在是异步的
  const imageId = await id // 使用 generateImageMetadata 时,id 现在是 Promise<string>
  // ...
}

React 19.2

Next.js 16 中的 App Router 使用最新的 React Canary 版本,其中包括新发布的 React 19.2 功能和其他正在逐步稳定的功能。亮点包括:

  • View Transitions:为在 Transition 或导航中更新的元素添加动画
  • useEffectEvent:将非响应式逻辑从 Effect 中提取到可重用的 Effect Event 函数中
  • Activity:通过使用 display: none 隐藏 UI 同时保持状态并清理 Effect 来渲染"后台活动"

React 19.2 公告中了解更多信息。

React Compiler 支持

随着 React Compiler 1.0 版本的发布,Next.js 16 中对 React Compiler 的内置支持现在已稳定。React Compiler 会自动记忆组件,减少不必要的重新渲染,无需手动更改代码。

reactCompiler 配置选项已从 experimental 升级为稳定。它默认不启用,因为我们继续收集不同应用程序类型的构建性能数据。

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  reactCompiler: true,
}
 
export default nextConfig

安装最新版本的 React Compiler 插件:

Terminal
npm install -D babel-plugin-react-compiler

值得注意的是:启用此选项时,预计开发和构建期间的编译时间会更长,因为 React Compiler 依赖于 Babel。

缓存 API

revalidateTag

revalidateTag 有一个新的函数签名。你可以将 cacheLife 配置文件作为第二个参数传递。

app/actions.ts
TypeScript
'use server'
 
import { revalidateTag } from 'next/cache'
 
export async function updateArticle(articleId: string) {
  // 将文章数据标记为过时 - 文章读者在重新验证时看到过时数据
  revalidateTag(`article-${articleId}`, 'max')
}

对于更新略有延迟可以接受的内容(如博客文章、产品目录或文档),使用 revalidateTag。用户会在后台加载新数据时收到过时的内容。

updateTag

updateTag 是一个新的仅限 Server Actions 的 API,它提供读写一致性语义,用户进行更改后 UI 会立即显示更改,而不是过时数据。

它通过在同一请求中使数据过期并立即刷新来实现这一点。

app/actions.ts
TypeScript
'use server'
 
import { updateTag } from 'next/cache'
 
export async function updateUserProfile(userId: string, profile: Profile) {
  await db.users.update(userId, profile)
 
  // 使缓存过期并立即刷新 - 用户立即看到他们的更改
  updateTag(`user-${userId}`)
}

这确保交互功能立即反映更改。非常适合表单、用户设置以及用户期望立即看到其更新的任何工作流。

此处了解何时使用 updateTagrevalidateTag

refresh

refresh 允许你从 Server Action 中刷新客户端路由器。

app/actions.ts
TypeScript
'use server'
 
import { refresh } from 'next/cache'
 
export async function markNotificationAsRead(notificationId: string) {
  // 在数据库中更新通知
  await db.notifications.markAsRead(notificationId)
 
  // 刷新标题中显示的通知计数
  refresh()
}

当你需要在执行操作后刷新客户端路由器时使用它。

cacheLife 和 cacheTag

cacheLifecacheTag 现在已稳定。不再需要 unstable_ 前缀。

如果你有类似这样的别名导入:

import {
  unstable_cacheLife as cacheLife,
  unstable_cacheTag as cacheTag,
} from 'next/cache'

你可以将导入更新为:

import { cacheLife, cacheTag } from 'next/cache'

增强的路由和导航

Next.js 16 包括对路由和导航系统的完全改造,使页面转换更精简、更快速。这优化了 Next.js 预取和缓存导航数据的方式:

  • 布局去重:预取具有共享布局的多个 URL 时,布局只下载一次。
  • 增量预取:Next.js 仅预取缓存中尚未存在的部分,而不是整个页面。

这些更改无需代码修改,旨在提高所有应用的性能。

但是,你可能会看到更多单独的预取请求,但总传输大小要低得多。我们认为这对于几乎所有应用程序来说都是正确的权衡。

如果增加的请求数量导致问题,请通过创建 issuediscussion 项目告诉我们。

Partial Pre-Rendering (PPR)

Next.js 16 删除了实验性的 Partial Pre-Rendering (PPR) 标志和配置选项,包括路由级段 experimental_ppr

Next.js 16 开始,你可以使用 cacheComponents 配置选择加入 PPR。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  cacheComponents: true,
}
 
module.exports = nextConfig

Next.js 16 中的 PPR 与 Next.js 15 canary 中的工作方式不同。如果你今天正在使用 PPR,请保持在当前使用的 Next.js 15 canary 中。我们将跟进有关如何迁移到 Cache Components 的指南。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // 如果你今天正在使用 PPR
  // 请保持在当前的 Next.js 15 canary 中
  experimental: {
    ppr: true,
  },
}
 
module.exports = nextConfig

middlewareproxy

middleware 文件名已弃用,并已重命名为 proxy 以阐明网络边界和路由焦点。

proxy 支持 edge 运行时。proxy 运行时是 nodejs,且无法配置。如果你想继续使用 edge 运行时,请继续使用 middleware。我们将在小版本中跟进进一步的 edge 运行时说明。

Terminal
# 重命名你的 middleware 文件
mv middleware.ts proxy.ts
#
mv middleware.js proxy.js

命名导出 middleware 也已弃用。将你的函数重命名为 proxy

proxy.ts
TypeScript
export function proxy(request: Request) {}

我们建议将函数名称更改为 proxy,即使你使用的是默认导出。

包含 middleware 名称的配置标志也被重命名。例如,skipMiddlewareUrlNormalize 现在是 skipProxyUrlNormalize

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  skipProxyUrlNormalize: true,
}
 
export default nextConfig

版本 16 codemod 也能够更新这些标志。

next/image 变更

带查询字符串的本地图像(破坏性变更)

带查询字符串的本地图像源现在需要 images.localPatterns.search 配置以防止枚举攻击。

app/page.tsx
import Image from 'next/image'
 
export default function Page() {
  return <Image src="/assets/photo?v=1" alt="Photo" width="100" height="100" />
}

如果你需要在本地图像中使用查询字符串,请将模式添加到你的配置中:

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  images: {
    localPatterns: [
      {
        pathname: '/assets/**',
        search: '?v=1',
      },
    ],
  },
}
 
export default nextConfig

minimumCacheTTL 默认值(破坏性变更)

images.minimumCacheTTL 的默认值已从 60 秒 更改为 4 小时(14400 秒)。这减少了没有 cache-control 头的图像的重新验证成本。

对于一些 Next.js 用户来说,图像重新验证频繁发生,通常是因为上游源图像缺少 cache-control 头。这导致每 60 秒发生一次重新验证,增加了 CPU 使用率和成本。

由于大多数图像不经常更改,这个短间隔并不理想。将默认值设置为 4 小时默认提供更持久的缓存,同时仍然允许图像在需要时每天更新几次。

如果你需要以前的行为,请将 minimumCacheTTL 更改为较低的值,例如改回 60 秒:

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  images: {
    minimumCacheTTL: 60,
  },
}
 
export default nextConfig

imageSizes 默认值(破坏性变更)

16 已从默认的 images.imageSizes 数组中删除。

我们查看了请求分析,发现很少有项目提供 16 像素宽度的图像。删除此设置可减少 next/image 传送到浏览器的 srcset 属性的大小。

如果你需要支持 16px 图像:

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}
 
export default nextConfig

我们认为 16 像素宽度的图像变得不那么常见,而不是缺乏开发者使用,因为 devicePixelRatio: 2 实际上会获取 32px 图像以防止在视网膜显示器中出现模糊。

qualities 默认值(破坏性变更)

images.qualities 的默认值已从允许所有质量更改为仅 [75]

如果你需要支持多个质量级别:

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  images: {
    qualities: [50, 75, 100],
  },
}
 
export default nextConfig

如果你指定的 quality prop 不包含在 image.qualities 数组中,质量将被强制转换为 images.qualities 中最接近的值。例如,给定上述配置,quality prop 为 80 时,会被强制转换为 75。

本地 IP 限制(破坏性变更)

新的安全限制默认阻止本地 IP 优化。仅对私有网络将 images.dangerouslyAllowLocalIP 设置为 true

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  images: {
    dangerouslyAllowLocalIP: true, // 仅适用于私有网络
  },
}
 
export default nextConfig

最大重定向次数(破坏性变更)

images.maximumRedirects 的默认值已从无限制更改为最多 3 次重定向。

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  images: {
    maximumRedirects: 0, // 禁用重定向
    //
    maximumRedirects: 5, // 增加以应对边缘情况
  },
}
 
export default nextConfig

next/legacy/image 组件(已弃用)

next/legacy/image 组件已弃用。请改用 next/image

// 之前
import Image from 'next/legacy/image'
 
// 之后
import Image from 'next/image'

images.domains 配置(已弃用)

images.domains 配置已弃用。

next.config.js
// image.domains 已弃用
module.exports = {
  images: {
    domains: ['example.com'],
  },
}

请改用 images.remotePatterns 以提高安全性:

next.config.js
// 请改用 image.remotePatterns
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
      },
    ],
  },
}

并发 devbuild

next devnext build 现在使用单独的输出目录,可以并发执行。next dev 命令输出到 .next/dev。这是新的默认行为,由 isolatedDevBuild 控制。

此外,锁文件机制可防止在同一项目上运行多个 next devnext build 实例。

由于开发服务器输出到 .next/devTurbopack 跟踪命令应该是:

npx next internal trace .next/dev/trace-turbopack

Parallel Routes default.js 要求

所有 parallel route 插槽现在都需要显式的 default.js 文件。没有它们构建将失败。

要保持以前的行为,请创建一个调用 notFound() 或返回 nulldefault.js 文件。

app/@modal/default.tsx
import { notFound } from 'next/navigation'
 
export default function Default() {
  notFound()
}

或返回 null

app/@modal/default.tsx
export default function Default() {
  return null
}

ESLint Flat Config

@next/eslint-plugin-next 现在默认为 ESLint Flat Config 格式,与 ESLint v10 保持一致,后者将放弃对旧版配置的支持。

请务必查看我们的 @next/eslint-plugin-next 插件 API 参考。

如果你使用的是旧版 .eslintrc 格式,请考虑迁移到 flat config 格式。有关详细信息,请参阅 ESLint 迁移指南

滚动行为覆盖

Next.js 的以前版本中,如果你通过 CSS 在 <html> 元素上全局设置了 scroll-behavior: smooth,Next.js 会在 SPA 路由转换期间覆盖它,如下所示:

  1. 暂时将 scroll-behavior 设置为 auto
  2. 执行导航(导致立即滚动到顶部)
  3. 恢复原始的 scroll-behavior

这确保即使你为页面内导航启用了平滑滚动,页面导航也始终感觉迅速和即时。但是,这种操作可能会很昂贵,特别是在每次导航开始时。

Next.js 16 中,此行为已更改。默认情况下,Next.js 将不再覆盖你在导航期间的 scroll-behavior 设置。

如果你希望 Next.js 执行此覆盖(以前的默认行为),请将 data-scroll-behavior="smooth" 属性添加到你的 <html> 元素:

app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="en" data-scroll-behavior="smooth">
      <body>{children}</body>
    </html>
  )
}

性能改进

next devnext start 命令进行了重大性能优化,以及改进的终端输出,包括更清晰的格式、更好的错误消息和改进的性能指标。

Next.js 16next build 输出中删除了 sizeFirst Load JS 指标。我们发现这些在使用 React Server Components 的服务器驱动架构中不准确。我们的 Turbopack 和 Webpack 实现都存在问题,并且在如何计算 Client Components 有效负载方面存在分歧。

衡量实际路由性能的最有效方法是使用 Chrome Lighthouse 或 Vercel Analytics 等工具,这些工具专注于 Core Web Vitals 和下载的资源大小。

next dev 配置加载

在以前的版本中,Next 配置文件在开发期间加载了两次:

  • 运行 next dev 命令时
  • next dev 命令启动 Next.js 服务器时

这效率低下,因为 next dev 命令不需要配置文件来启动 Next.js 服务器。

此更改的结果是,在 Next.js 配置文件中运行 next dev 检查 process.argv 是否包含 'dev' 时,将返回 false

值得注意的是typegenbuild 命令在 process.argv 中仍然可见。

这对于在 next dev 上触发副作用的插件尤其重要。如果是这种情况,检查 NODE_ENV 是否设置为 development 可能就足够了。

next.config.js
import { startServer } from 'docs-lib/dev-server'
 
const isDev = process.env.NODE_ENV === 'development'
 
if (isDev) {
  startServer()
}
 
const nextConfig = {
  /* Your config options */
}
 
module.exports = nextConfig

或者,使用加载配置的 phase

Build Adapters API(alpha)

Build Adapters RFC 之后,Build Adapters API 的第一个 alpha 版本现已可用。

Build Adapters 允许你创建挂钩到构建过程的自定义适配器,使部署平台和自定义构建集成能够修改 Next.js 配置或处理构建输出。

next.config.js
const nextConfig = {
  experimental: {
    adapterPath: require.resolve('./my-adapter.js'),
  },
}
 
module.exports = nextConfig

RFC 讨论中分享你的反馈。

Modern Sass API

sass-loader 已升级到 v16,支持现代 Sass 语法和新功能。

删除

这些功能之前已弃用,现在已删除:

AMP 支持

AMP 的采用率显著下降,维护此功能会增加框架的复杂性。所有 AMP API 和配置都已删除:

  • 从 Next 配置文件中删除 amp 配置
  • next/amp 钩子导入和使用(useAmp
// 已删除
import { useAmp } from 'next/amp'
 
// 已删除
export const config = { amp: true }
  • 从页面中删除 export const config = { amp: true }
next.config.js
const nextConfig = {
  // 已删除
  amp: {
    canonicalBase: 'https://example.com',
  },
}
 
export default nextConfig

评估 AMP 是否仍然对你的用例必要。现在可以通过 Next.js 的内置优化和现代 Web 标准实现大多数性能优势。

next lint 命令

next lint 命令已删除。直接使用 Biome 或 ESLint。next build 不再运行 linting。

可使用 codemod 来自动化迁移:

Terminal
npx @next/codemod@canary next-lint-to-eslint-cli .

Next.js 配置文件中的 eslint 选项也已删除。

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  // 不再支持
  // eslint: {},
}
 
export default nextConfig

运行时配置

serverRuntimeConfigpublicRuntimeConfig 已删除。请改用环境变量。

之前(Next.js 15):

next.config.js
module.exports = {
  serverRuntimeConfig: {
    dbUrl: process.env.DATABASE_URL,
  },
  publicRuntimeConfig: {
    apiUrl: '/api',
  },
}
pages/index.tsx
import getConfig from 'next/config'
 
export default function Page() {
  const { publicRuntimeConfig } = getConfig()
  return <p>API URL: {publicRuntimeConfig.apiUrl}</p>
}

之后(Next.js 16):

对于仅服务器的值,直接在 Server Components 中访问环境变量:

app/page.tsx
async function fetchData() {
  const dbUrl = process.env.DATABASE_URL
  // 仅用于服务器端操作
  return await db.query(dbUrl, 'SELECT * FROM users')
}
 
export default async function Page() {
  const data = await fetchData()
  return <div>{/* render data */}</div>
}

值得注意的是:使用 taint API 防止意外地将敏感的服务器值传递给 Client Components。

对于客户端可访问的值,使用 NEXT_PUBLIC_ 前缀:

.env.local
NEXT_PUBLIC_API_URL="/api"
app/components/client-component.tsx
'use client'
 
export default function ClientComponent() {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL
  return <p>API URL: {apiUrl}</p>
}

要确保在运行时读取环境变量(而不是在构建时捆绑),请在从 process.env 读取之前使用 connection() 函数:

app/page.tsx
import { connection } from 'next/server'
 
export default async function Page() {
  await connection()
  const config = process.env.RUNTIME_CONFIG
  return <p>{config}</p>
}

了解更多关于环境变量的信息。

devIndicators 选项

以下选项已从 devIndicators 中删除:

  • appIsrStatus
  • buildActivity
  • buildActivityPosition

指示器本身仍然可用。

experimental.dynamicIO

experimental.dynamicIO 标志已重命名为 cacheComponents

更新你的 Next 配置文件,删除 dynamicIO 标志。

next.config.js
// Next.js 15 - experimental.dynamicIO 现已删除
module.exports = {
  experimental: {
    dynamicIO: true,
  },
}

添加设置为 true 的 cacheComponents 标志。

next.config.js
// Next.js 16 - 请改用 cacheComponents
module.exports = {
  cacheComponents: true,
}

unstable_rootParams

unstable_rootParams 函数已删除。我们正在开发一个替代 API,将在即将发布的小版本中提供。