Next.js 15 候选发布版 (RC) 现已推出

2,734 阅读9分钟

原文链接

Next.js 15 候选发布版 (RC) 现已推出。此早期版本允许您在即将发布的稳定版本之前测试最新功能。

React: 支持 React 19 RC、React 编译器(实验性)和水合错误改进

缓存:fetch 请求、GET 路由处理程序和客户端导航默认不再缓存

部分预渲染(实验性):新的布局和页面配置选项以便逐步采用

next/after(实验性):新的 API 用于在响应完成流式传输后执行代码

create-next-app: 更新了设计并增加了一个新标志以在本地开发中启用 Turbopack

打包外部包(稳定):为 App 和 Pages 路由器提供新的配置选项

立即尝试 Next.js 15 RC:

npm install next@rc react@rc react-dom@rc

注意:您可以在 rc.nextjs.org/docs 查看 Next.js 15 RC 文档,直到 Next.js 15 GA 发布。

React 19 RC

Next.js 应用路由器构建在 React 框架的 canary 通道上,这使得开发者可以在 v19 发布之前使用并反馈这些新的 React API。

Next.js 15 RC 现在支持 React 19 RC,包括客户端和服务器的新功能,如 Actions。

阅读 Next.js 15 升级指南、React 19 升级指南,并观看 React Conf 主题演讲以了解更多信息。

注意:某些第三方库可能尚不兼容 React 19。

React 编译器(实验性)

React 编译器是 Meta 的 React 团队创建的新实验性编译器。该编译器通过理解纯 JavaScript 语义和 React 规则,能够深度理解您的代码,从而为您的代码添加自动优化。编译器减少了开发者通过 useMemo 和 useCallback 等 API 进行手动记忆化的数量,使代码更简单、更易维护且更少出错。

在 Next.js 15 中,我们增加了对 React 编译器的支持。

安装 babel-plugin-react-compiler:

终端

npm install babel-plugin-react-compiler

然后,在 next.config.js 中添加 experimental.reactCompiler 选项:

const nextConfig = {
  experimental: {
    reactCompiler: true,
  },
};

module.exports = nextConfig;

可选地,您可以将编译器配置为“选择加入”模式,如下所示:

const nextConfig = {
  experimental: {
    reactCompiler: {
      compilationMode: 'annotation',
    },
  },
};

module.exports = nextConfig;

注意:目前只能通过 Babel 插件在 Next.js 中使用 React 编译器,这可能会导致构建时间变慢。

了解更多关于 React 编译器和可用的 Next.js 配置选项的信息。

水合错误改进

Next.js 14.1 对错误消息和水合错误进行了改进。Next.js 15 在此基础上增加了改进的水合错误视图。水合错误现在显示错误的源代码,并提供解决问题的建议。

例如,这是 Next.js 14.1 中的一个水合错误消息:

https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-before-dark.png&w=3840&q=75

Next.js 15 RC 将其改进为:

https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-after-dark.png&w=3840&q=75

缓存更新

Next.js 应用路由器推出了有主见的缓存默认设置。这些设置旨在提供默认情况下最具性能的选项,并在需要时可以选择退出。

根据您的反馈,我们重新评估了缓存启发式方法以及它们如何与部分预渲染(PPR)和使用 fetch 的第三方库交互。

在 Next.js 15 中,我们将 fetch 请求、GET 路由处理程序和客户端路由器缓存的默认缓存从默认缓存更改为默认不缓存。如果您想保留先前的行为,可以继续选择加入缓存。

我们将在接下来的几个月中继续改进 Next.js 中的缓存,并将在 Next.js 15 GA 公告中分享更多详细信息。

fetch 请求默认不再缓存

Next.js 使用 Web fetch API 缓存选项来配置服务器端 fetch 请求如何与框架的持久 HTTP 缓存交互:

fetch('https://...', { cache: 'force-cache' | 'no-store' });
  • no-store - 每次请求都从远程服务器获取资源,并且不更新缓存

  • force-cache - 从缓存(如果存在)或远程服务器获取资源并更新缓存

在 Next.js 14 中,如果未提供缓存选项,默认使用 force-cache,除非使用动态函数或动态配置选项。

在 Next.js 15 中,如果未提供缓存选项,默认使用 no-store。这意味着 fetch 请求默认不缓存。

您仍然可以通过以下方式选择缓存 fetch 请求:

  • 在单个 fetch 调用中将缓存选项设置为 force-cache

  • 为单个路由将动态路由配置选项设置为 force-static

  • 将 fetchCache 路由配置选项设置为 default-cache,以覆盖布局或页面中的所有 fetch 请求,使其使用 force-cache,除非它们明确指定自己的缓存选项

GET 路由处理程序默认不再缓存

在 Next 14 中,使用 GET HTTP 方法的路由处理程序默认缓存,除非它们使用动态函数或动态配置选项。在 Next.js 15 中,GET 函数默认不缓存。

您仍然可以通过使用静态路由配置选项(如 export dynamic = 'force-static')选择缓存。

特殊路由处理程序如 sitemap.ts、opengraph-image.tsx 和 icon.tsx 以及其他元数据文件默认保持静态,除非它们使用动态函数或动态配置选项。

客户端路由器缓存默认不再缓存页面组件

在 Next.js 14.2.0 中,我们引入了一个实验性的 staleTimes 标志,允许自定义路由器缓存的配置。

在 Next.js 15 中,此标志仍然可访问,但我们将默认行为更改为页面段的 staleTime 为 0。这意味着在您的应用程序中导航时,客户端将始终反映页面组件的最新数据。然而,仍然有一些重要行为保持不变:

  • 共享布局数据不会从服务器重新获取,以继续支持部分渲染。

  • 后退/前进导航仍将从缓存恢复,以确保浏览器可以恢复滚动位置。

  • Loading.js 将缓存 5 分钟(或 staleTimes.static 配置的值)。

您可以通过设置以下配置选择先前的客户端路由器缓存行为:

next.config.ts

const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
    },
  },
};

module.exports = nextConfig;

部分预渲染的增量采用(实验性)

在 Next.js 14 中,我们引入了部分预渲染(PPR) - 一种在同一页面上结合静态和动态渲染的优化。

Next.js 目前默认静态渲染,除非您使用动态函数如 cookies()headers() 和未缓存的数据请求。这些 API 将整个路由选为动态渲染。通过 PPR,您可以在 Suspense 边界内包装任何动态 UI。当有新请求进来时,Next.js 将立即提供静态 HTML 壳,然后在同一 HTTP 请求中渲染并流式传输动态部分。

为了允许增量采用,我们添加了一个 experimental_ppr 路由配置选项,用于将特定布局和页面选为 PPR:

app/page.jsx

import { Suspense } from "react";
import { StaticComponent, DynamicComponent } from "@/app/ui";

export const experimental_ppr = true;

export default function Page() {
  return (
    <>
      <StaticComponent />
      <Suspense fallback={...}>
        <DynamicComponent />
      </Suspense>
    </>
  );
}

要使用新选项,您需要在 next.config.js 文件中将 experimental.ppr 配置设置为 'incremental':

next.config.ts

const nextConfig = {
  experimental: {
    ppr: 'incremental',
  },
};

module.exports = nextConfig;

一旦所有段都启用了 PPR,您将可以将 ppr 值设置为 true,并为整个应用程序和所有未来的路由启用它。

我们将在 Next.js 15 GA 博客文章中分享更多关于 PPR 路线图的信息。

了解更多关于部分预渲染的信息。

使用 next/after 在响应后执行代码(实验性)

在处理用户请求时,服务器通常执行与计算响应直接相关的任务。然而,您可能需要执行日志记录、分析和其他外部系统同步等任务。

由于这些任务与响应不直接相关,用户不应等待它们完成。响应用户后推迟工作存在挑战,因为无服务器函数在响应关闭后立即停止计算。

after() 是一个新的实验性 API,允许您在响应完成流式传输后安排工作处理,从而使次要任务在不阻塞主要响应的情况下运行。

要使用它,请在 next.config.js 中添加 experimental.after:

const nextConfig = {
  experimental: {
    after: true,
  },
};

module.exports = nextConfig;

然后,在服务器组件、服务器操作、路由处理程序或中间件中导入函数:

import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';

export default function Layout({ children }) {
  // 次要任务
  after(() => {
    log();
  });

  // 主要任务
  return <>{children}</>;
}

了解更多关于 next/after 的信息。

create-next-app 更新

对于 Next.js 15,我们更新了 create-next-app 的设计。

Next.js 15 RC 中 create-next-app 的新设计

运行 create-next-app 时,会有一个新提示询问您是否要在本地开发中启用 Turbopack(默认不启用)。

终端

✔ Would you like to use Turbopack for next dev? … No / Yes

可以使用 --turbo 标志启用 Turbopack。

终端

npx create-next-app@rc --turbo

为了使新项目的入门更容易,CLI 中新增了一个 --empty 标志。这将移除任何多余的文件和样式,生成一个最小的“hello world”页面。

终端

npx create-next-app@rc --empty

优化外部包的打包(稳定)

打包外部包可以提高应用程序的冷启动性能。在 App 路由器中,外部包默认打包,您可以使用新的 serverExternalPackages 配置选项选择退出特定包。

在 Pages 路由器中,外部包默认不打包,但您可以使用现有的 transpilePackages 选项提供要打包的包列表。使用此配置选项,您需要指定每个包。

为了统一 App 和 Pages 路由器之间的配置,我们引入了一个新选项 bundlePagesRouterDependencies,以匹配 App 路由器的默认自动打包。然后,您可以使用 serverExternalPackages 选择退出特定包(如果需要)。

next.config.ts

const nextConfig = {
  // 自动打包 Pages 路由器中的外部包:
  bundlePagesRouterDependencies: true,
  // 为 App 和 Pages 路由器选择退出特定包的打包:
  serverExternalPackages: ['package-name'],
};

module.exports = nextConfig;

了解更多关于优化外部包的信息。

其他更改

[Breaking] 最低 React 版本现在是 19 RC

[Breaking] next/image: 移除 squoosh,改为使用 sharp 作为可选依赖(PR)

[Breaking] next/image: 将默认 Content-Disposition 更改为 attachment(PR)

[Breaking] next/image: src 有前导或尾随空格时出错(PR)

[Breaking] 中间件:应用 react-server 条件以限制不推荐的 React API 导入(PR)

[Breaking] next/font: 移除对外部 @next/font 包的支持(PR)

[Breaking] next/font: 移除 font-family 哈希(PR)

[Breaking] 缓存:force-dynamic 现在将 fetch 缓存的默认值设置为 no-store(PR)

[Breaking] 配置:默认启用 swcMinify(PR)、missingSuspenseWithCSRBailout(PR)和 outputFileTracing(PR)行为,并移除已弃用选项

[Breaking] 移除 Speed Insights 的自动检测(现在必须使用专用的 @vercel/speed-insights 包)(PR)

[Improvement] 对齐开发和生产中的 sitemap URL(PR)

[Improvement] 元数据:更新在 Vercel 上托管时的元数据基础环境变量回退(PR)

[Improvement] 修复 optimizePackageImports 中混合命名空间和命名导入的 tree-shaking(PR)

[Improvement] 并行路由:为未匹配的 catch-all 路由提供所有已知参数(PR)

[Improvement] 配置 bundlePagesExternals 现在稳定并重命名为 bundlePagesRouterDependencies

[Improvement] 配置 serverComponentsExternalPackages 现在稳定并重命名为 serverExternalPackages

[Improvement] create-next-app:新项目默认忽略所有 .env 文件(PR)

[Docs] 改进认证文档(PR)

[Docs] @next/env 包(PR)

了解更多,请查看升级指南。