跳到内容
返回博客

2022 年 10 月 25 日,星期二

Next.js 13

发布者

正如我们在 Next.js Conf 上宣布的那样,Next.js 13 (稳定版) 为不受限制的动态性奠定了基础

Next.js 13 和 pages 目录已稳定,可用于生产环境。立即运行以下命令更新:

终端
npm i next@latest react@latest react-dom@latest eslint-config-next@latest

新的 app 目录 (Beta 版)

今天,我们通过引入 app 目录,改进了 Next.js 中的路由和布局体验,并与 React 的未来发展方向保持一致。这是先前发布的 布局 RFC 的后续,旨在征求社区反馈。

app 目录目前处于 beta 版,我们不建议在生产环境中使用。您可以将 Next.js 13 与 pages 目录一起使用,其中包含改进的 next/imagenext/link 组件等稳定功能,并按照自己的节奏选择使用 app 目录。在可预见的未来,pages 目录将继续得到支持。

app 目录包括对以下内容的支持:

  • 布局: 轻松在路由之间共享 UI,同时保留状态并避免昂贵的重新渲染。
  • 服务端组件: 使服务端优先成为最动态应用程序的默认选择。
  • 流式处理: 显示即时加载状态,并在 UI 单元渲染时进行流式传输。
  • 数据获取支持: async 服务端组件和扩展的 fetch API 支持组件级别的数据获取。
The app directory can be incrementally adopted from your existing pages/ directory.
app 目录可以从现有的 pages/ 目录逐步采用。

布局

app/ 目录使您可以轻松布局复杂的界面,这些界面可以在导航之间保持状态,避免昂贵的重新渲染,并启用高级路由模式。此外,您可以嵌套布局,并将应用程序代码与您的路由放在一起,例如组件、测试和样式。

The app/ directory can be incrementally adopted from your existing pages/ directory.
app/ 目录可以从现有的 pages/ 目录逐步采用。

app/ 内创建路由需要单个文件,page.js

app/page.js
// This file maps to the index route (/)
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

然后,您可以通过文件系统定义布局。布局在多个页面之间共享 UI。在导航时,布局会保留状态、保持交互性,并且不会重新渲染。

app/blog/layout.js
export default function BlogLayout({ children }) {
  return <section>{children}</section>;
}

了解更多关于布局和页面的信息部署一个示例来试用一下

服务端组件

app/ 目录引入了对 React 全新的 服务端组件 架构的支持。服务端和 客户端组件 各司其职,充分利用服务端和客户端的优势 - 让您能够使用单一的编程模型构建快速、高度交互的应用程序,并提供出色的开发者体验。

借助服务端组件,我们正在为构建复杂界面奠定基础,同时减少发送到客户端的 JavaScript 数量,从而加快初始页面加载速度。

当加载路由时,将加载 Next.js 和 React 运行时,它们是可缓存的且大小可预测的。随着应用程序的增长,此运行时的大小不会增加。此外,运行时是异步加载的,从而使来自服务器的 HTML 能够在客户端上逐步增强。

了解更多关于服务端组件的信息部署一个示例来试用一下

流式处理

app/ 目录引入了逐步渲染和增量流式传输 UI 渲染单元到客户端的能力。

借助服务端组件和 Next.js 中的 嵌套布局,您可以立即渲染页面中不需要特定数据的部分,并为正在获取数据的页面部分显示加载状态。通过这种方法,用户无需等待整个页面加载完成即可开始与之交互。

You can colocate your application code, such as components, tests, and styles, with your routes.
您可以将应用程序代码(例如组件、测试和样式)与路由放在一起。

当部署到 Vercel 时,使用 app/ 目录的 Next.js 13 应用程序将在 Node.js 和 Edge 运行时中默认流式传输响应,以提高性能。

了解更多关于流式处理的信息部署一个示例来试用一下

数据获取

React 最近的 Promises RFC 支持 引入了一种强大的新方法,用于在组件内部获取数据和处理 Promise

app/page.js
async function getData() {
  const res = await fetch('https://api.example.com/...');
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.
  return res.json();
}
 
// This is an async Server Component
export default async function Page() {
  const data = await getData();
 
  return <main>{/* ... */}</main>;
}

原生的 fetch Web API 也在 React 和 Next.js 中得到了扩展。它 自动去重 fetch 请求,并提供了一种灵活的方式在组件级别获取、缓存和重新验证数据。这意味着静态站点生成 (SSG)、服务端渲染 (SSR) 和增量静态重新生成 (ISR) 的所有优势现在都可以通过一个 API 获得

// This request should be cached until manually invalidated.
// Similar to `getStaticProps`.
// `force-cache` is the default and can be omitted.
fetch(URL, { cache: 'force-cache' });
 
// This request should be refetched on every request.
// Similar to `getServerSideProps`.
fetch(URL, { cache: 'no-store' });
 
// This request should be cached with a lifetime of 10 seconds.
// Similar to `getStaticProps` with the `revalidate` option.
fetch(URL, { next: { revalidate: 10 } });

app 目录中,您可以在 布局、页面 和组件内部获取数据 - 包括对来自服务器的 流式响应 的支持。

我们正在实现符合人体工程学的方式来处理加载和错误状态,并在 UI 渲染时进行流式传输。在未来的版本中,我们还将改进和简化数据突变。

With the app/ directory, you can use a new special file loading.js to automatically create Instant Loading UI with Suspense boundaries.
使用 app/ 目录,您可以使用新的特殊文件 loading.js 通过 Suspense 边界自动创建即时加载 UI。

我们很高兴与开源社区、包维护者以及为 React 生态系统做出贡献的其他公司合作,为 React 和 Next.js 的新时代构建应用。将数据获取与组件放在一起以及减少向客户端发送 JavaScript 是我们很高兴在 app/ 目录中包含的两个重要的社区反馈。

了解更多关于数据获取的信息部署一个示例来试用一下

Turbopack 介绍 (Alpha 版)

Next.js 13 包含了 Turbopack,它是 Webpack 的全新 Rust 语言的继任者。

Webpack 的下载量已超过 30 亿次。虽然它一直是构建 Web 的重要组成部分,但我们已经触及了基于 JavaScript 的工具所能达到的最高性能的极限。

在 Next.js 12 中,我们开始了向原生 Rust 驱动的工具过渡。我们首先迁移远离 Babel,这使得转译速度提高了 17 倍。然后,我们替换了 Terser,这使得最小化速度提高了 6 倍。现在是时候全力投入原生捆绑了。

将 Turbopack alpha 与 Next.js 13 结合使用,可以实现:

  • 比 Webpack 快 700 倍 的更新速度
  • 比 Vite 快 10 倍 的更新速度
  • 比 Webpack 快 4 倍 的冷启动速度
Turbopack is our Rust-based successor to Webpack, with 700x faster HMR for large applications.
Turbopack 是我们基于 Rust 的 Webpack 继任者,对于大型应用程序,HMR 速度提高了 700 倍。

Turbopack 仅捆绑开发中所需的最小资源,因此启动时间非常快。在具有 3,000 个模块的应用程序上,Turbopack 启动需要 1.8 秒Vite 需要 11.4 秒,而 Webpack 需要 16.5 秒

Turbopack 开箱即用地支持服务端组件、TypeScript、JSX、CSS 等。在 alpha 版期间,许多功能 尚未支持。我们很乐意听取您关于使用 Turbopack 加速本地迭代的反馈。

注意: Next.js 中的 Turbopack 目前仅支持 next dev。查看 支持的功能。我们也在努力通过 Turbopack 添加对 next build 的支持。

立即通过 next dev --turbo 在 Next.js 13 中试用 Turbopack alpha 版。

next/image

Next.js 13 引入了一个强大的全新 Image 组件,使您可以轻松显示图像,而不会发生布局偏移,并按需优化文件以提高性能。

在 Next.js 社区调查中,70% 的受访者告诉我们他们在生产环境中使用 Next.js Image 组件,并且反过来,他们看到了 Core Web Vitals 的改进。在 Next.js 13 中,我们将进一步改进 next/image

新的 Image 组件具有以下优点:

  • 减少客户端 JavaScript 的传输量
  • 更易于样式化和配置
  • 更易于访问,默认情况下需要 alt 标签
  • 与 Web 平台对齐
  • 速度更快,因为原生懒加载不需要水合 (hydration)
app/page.js
import Image from 'next/image';
import avatar from './lee.png';
 
export default function Home() {
  // "alt" is now required for improved accessibility
  // optional: image files can be colocated inside the app/ directory
  return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}

了解更多关于 Image 组件的信息部署一个示例来试用一下

next/image 升级到 Next.js 13

旧的 Image 组件已重命名为 next/legacy/image。我们提供了一个 codemod,它将自动更新您现有的 next/image 用法为 next/legacy/image。例如,当从根目录运行时,此命令将在您的 ./pages 目录上运行 codemod

终端
npx @next/codemod next-image-to-legacy-image ./pages

了解更多关于 codemod 的信息.

@next/font

Next.js 13 引入了一个全新的字体系统,它具有以下优点:

  • 自动优化您的字体,包括自定义字体
  • 删除外部网络请求,以提高隐私和性能
  • 内置自动自托管,适用于任何字体文件
  • 使用 CSS size-adjust 属性自动实现零布局偏移

这个新的字体系统使您可以方便地使用所有 Google Fonts,同时兼顾性能和隐私。CSS 和字体文件在构建时下载,并与其余静态资源一起自托管。浏览器不会向 Google 发送任何请求。

app/layout.js / pages/_app.js
import { Inter } from '@next/font/google';
 
const inter = Inter();
 
<html className={inter.className}></html>;

还支持自定义字体,包括对字体文件的自动自托管、缓存和预加载的支持。

app/layout.js / pages/_app.js
import localFont from '@next/font/local';
 
const myFont = localFont({ src: './my-font.woff2' });
 
<html className={myFont.className}></html>;

您可以自定义字体加载体验的每个部分,同时仍然确保出色的性能和零布局偏移,包括 font-display、预加载、回退等。

了解更多关于新的 Font 组件的信息部署一个示例来试用一下

next/link 不再需要手动添加 <a> 作为子元素。

这在 12.2 中作为一个实验性选项添加,现在已成为默认设置。在 Next.js 13 中,<Link> 始终渲染一个 <a>,并允许您将 props 转发到底层标签。例如:

import Link from 'next/link'
 
// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  <a>About</a>
</Link>
 
// Next.js 13: `<Link>` always renders `<a>`
<Link href="/about">
  About
</Link>

了解更多关于改进的 Link 组件的信息部署一个示例来试用一下

为了将您的链接升级到 Next.js 13,我们提供了一个 codemod,它将自动更新您的代码库。例如,当从根目录运行时,此命令将在您的 ./pages 目录上运行 codemod

终端
npx @next/codemod new-link ./pages

了解更多关于 codemod 的信息 或查看文档。

OG 图像生成

社交卡片,也称为开放图谱图像,可以大幅提高内容点击的互动率,一些实验表明转化率提高了 40%。

静态社交卡片耗时、容易出错且难以维护。因此,社交卡片常常缺失甚至被跳过。直到今天,需要个性化和即时计算的动态社交卡片仍然困难且昂贵。

我们创建了一个新的库 @vercel/og,它可以与 Next.js 无缝协作,以生成动态社交卡片。

pages/api/og.jsx
import { ImageResponse } from '@vercel/og';
 
export const config = {
  runtime: 'experimental-edge',
};
 
export default function () {
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
        }}
      >
        Hello, World!
      </div>
    ),
  );
}

通过使用 Vercel Edge Functions、WebAssembly 以及一个用于将 HTML 和 CSS 转换为图像并利用 React 组件抽象的全新核心库,这种方法比现有解决方案快 5 倍

了解更多关于 OG 图像生成的信息部署一个示例来试用

中间件 API 更新

在 Next.js 12 中,我们引入了中间件,以实现 Next.js 路由器的完全灵活性。我们听取了您对初始 API 设计的反馈,并添加了一些功能来改善开发者体验并添加强大的新功能。

您现在可以更轻松地在请求上设置标头

middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
 
export function middleware(request: NextRequest) {
  // Clone the request headers and set a new header `x-version`
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-version', '13');
 
  // You can also set request headers in NextResponse.rewrite
  const response = NextResponse.next({
    request: {
      // New request headers
      headers: requestHeaders,
    },
  });
 
  // Set a new response header `x-version`
  response.headers.set('x-version', '13');
  return response;
}

现在您还可以直接从中间件提供响应,而无需 rewriteredirect

middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';
 
// Limit the middleware to paths starting with `/api/`
export const config = {
  matcher: '/api/:function*',
};
 
export function middleware(request: NextRequest) {
  // Call our authentication function to check the request
  if (!isAuthenticated(request)) {
    // Respond with JSON indicating an error message
    return NextResponse.json(
      {
        success: false,
        message: 'Auth failed',
      },
      {
        status: 401,
      },
    );
  }
}

目前,从中间件发送响应需要在 next.config.js 中启用 experimental.allowMiddlewareResponseBody 配置选项。

重大变更

  • 最低 React 版本已从 17.0.2 提升至 18.2.0。
  • 最低 Node.js 版本已从 12.22.0 提升至 14.6.0,因为 12.x 已达到生命周期终止 (PR)。
  • swcMinify 配置属性已从 false 更改为 true。有关更多信息,请参阅 Next.js Compiler
  • next/image 导入已重命名为 next/legacy/imagenext/future/image 导入已重命名为 next/image。有一个 codemod 可用于安全且自动地重命名您的导入。
  • next/link 的子元素不能再是 <a>。添加 legacyBehavior 属性以使用旧版行为,或删除 <a> 以进行升级。有一个 codemod 可用于自动升级您的代码。
  • 当 User-Agent 是机器人时,路由不再预取。
  • 已移除 next.config.js 中已弃用的 target 选项。
  • 支持的浏览器已更改为放弃 Internet Explorer 并面向现代浏览器。您仍然可以使用 Browserslist 更改目标浏览器。
    • Chrome 64+
    • Edge 79+
    • Firefox 67+
    • Opera 51+
    • Safari 12+

要了解更多信息,请查看升级指南

社区

六年前,我们向公众发布了 Next.js。我们着手构建一个零配置的 React 框架,以简化您的开发者体验。回顾过去,令人难以置信的是看到社区如何发展壮大,以及我们共同交付了什么。让我们继续前进。

Next.js 是超过 2,400 名个人开发者、谷歌和 Meta 等行业合作伙伴以及我们核心团队共同努力的成果。凭借每周超过 300 万次的 npm 下载量和 94,000 个 GitHub 星星,Next.js 是构建 Web 最受欢迎的方式之一。

特别感谢 Google Chrome 的 Aurora 团队,他们帮助进行了基础研究和实验,促成了这次发布。

本次发布由以下贡献者共同促成:@ijjk, @huozhi, @HaNdTriX, @iKethavel, @timneutkens, @shuding, @rishabhpoddar, @hanneslund, @balazsorban44, @devknoll, @anthonyshew, @TomerAberbach, @philippbosch, @styfle, @mauriciomutte, @hayitsdavid, @abdennor, @Kikobeats, @cjdunteman, @Mr-Afonso, @kdy1, @jaril, @abdallah-nour, @North15, @feedthejim, @brunocrosier, @Schniz, @sedlukha, @hashlash, @Ethan-Arrowood, @fireairforce, @migueloller, @leerob, @janicklas-ralph, @Trystanr, @atilafassina, @nramkissoon, @kasperadk, @valcosmos, @henriqueholtz, @nip10, @jesstelford, @lorensr, @AviAvinav, @SukkaW, @jaycedotbin, @saurabhburade, @notrab, @kwonoj, @sanruiz, @angeloashmore, @falsepopsky, @fmontes, @Gebov, @UltiRequiem, @p13lgst, @Simek, @mrkldshv, @thomasballinger, @kyliau, @AdarshKonchady, @endymion1818, @pedro757, @perkinsjr, @gnoff, @jridgewell, @silvioprog, @mabels, @nialexsan, @feugy, @jackromo888, @crazyurus, @EarlGeorge, @MariaSolOs, @lforst, @maximbaz, @maxam2017, @teobler, @Nutlope, @sunwoo0706, @WestonThayer, @Brooooooklyn, @Nsttt, @charlypoly, @aprendendofelipe, @sviridoff, @jackton1, @nuta, @Rpaudel379, @marcialca, @MarDi66, @ismaelrumzan, @javivelasco, @eltociear, and @hiro0218。