跳到内容
返回博客

2021年10月26日星期二

Next.js 12

发布者

正如我们在 Next.js Conf 上宣布的,Next.js 12 是我们有史以来最大的版本发布

立即运行 npm i next@latest 进行更新。

使用 Rust 编译器实现更快的构建和快速刷新

我们希望让每个 Next.js 应用程序更快地进行生产构建,并在本地开发中获得即时反馈。Next.js 12 包含一个全新的 Rust 编译器,利用原生编译的优势。

我们的 Rust 编译器基于 SWC,一个面向下一代快速工具的开放平台。我们通过将本地刷新速度提高约 3 倍,生产构建速度提高约 5 倍,从而优化了打包和编译。其他改进和功能包括:

Results from using the new Rust compiler with large Next.js codebases.
使用新的 Rust 编译器处理大型 Next.js 代码库的结果。
  • 大型代码库的进一步速度提升: 我们已经使用世界上一些最大的 Next.js 代码库验证了 Rust 编译器。
  • 提高了性能可观察性: Next.js 现在在控制台中输出客户端和服务器编译的快速刷新时间,包括编译的模块和文件数量。
  • 底层 webpack 改进: 我们对 webpack 进行了多项改进,包括优化快速刷新和使按需入口更可靠。

使用 Rust 进行编译比 Babel 快 17 倍,并且在 Next.js 12 中默认启用,取代了 JavaScript 和 TypeScript 文件的转换。这意味着我们必须将 Next.js 中的 Babel 转换移植到 Rust,包括用于实现 styled-jsx 转换的全新 Rust CSS 解析器

新的 Rust 编译器向后兼容。如果您有现有的 Babel 配置,您将自动选择退出。我们计划很快移植对流行库(如 styled-componentsemotionrelay)的解析。如果您正在使用自定义 Babel 设置,请分享您的配置

您还可以选择使用 Rust 编译器进行压缩。这比 Terser 快 7 倍。压缩是选择性加入的,直到它被彻底验证,因为它取代了多年的基础设施。

next.config.js
module.exports = {
  swcMinify: true,
};

除了聘请 SWC 的创建者 DongYoon KangParcel 的贡献者 Maia Teegarden 之外,我们还在继续投资 Rust 生态系统。如果您有 Rust 的工作经验,请申请加入我们的团队

欲了解更多信息,请观看我们在 Next.js Conf 上的演示

介绍中间件

中间件让您可以使用代码而非配置。这为 Next.js 提供了完全的灵活性,因为您可以在请求完成之前运行代码。根据用户的传入请求,您可以通过重写、重定向、添加标头甚至流式传输 HTML 来修改响应。

Middleware gives you complete flexibility inside Next.js.
中间件为您提供了 Next.js 内部的完全灵活性。

中间件可用于为一组页面共享逻辑的任何事情,包括:

中间件使用支持标准 Web API(如 fetch)的严格运行时。这可以通过 next start 开箱即用,也可以在 Vercel 等边缘平台上使用,这些平台使用 边缘中间件

要在 Next.js 中使用中间件,您可以创建文件 pages/_middleware.js。在此示例中,我们使用标准 Web API Response (MDN)

pages/_middleware.js
export function middleware(req, ev) {
  return new Response('Hello, world!');
}

欲了解更多信息,请观看我们在 Next.js Conf 上的演示查看文档

为 React 18 做准备

React 18 将增加 Suspense、更新自动批处理、startTransition 等 API,以及支持 React.lazy 的服务器渲染新流式 API 等功能。

我们一直与 Facebook 的 React 团队紧密合作,为 Next.js 18 稳定版发布做准备。我们正在 Next.js 12 中通过实验性标志提供这些功能,供您今天试用。

终端
npm install react@alpha react-dom@alpha

服务器端流式传输

React 18 中的并发功能包括对服务器端 Suspense 和 SSR 流式传输的原生支持。这允许您使用 HTTP 流式传输服务器渲染页面。这是 Next.js 12 中的一项实验性功能,但一旦启用,SSR 将使用与中间件相同的严格运行时。

要启用,请使用实验性标志 concurrentFeatures: true

next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
  },
};

React 服务器组件

React 服务器组件允许我们在服务器上渲染所有内容,包括组件本身。这与在服务器上预生成 HTML 的服务器端渲染根本不同。使用服务器组件,无需客户端 JavaScript,从而加快页面渲染速度。这通过将服务器渲染的最佳部分与客户端交互性相结合,改善了您应用程序的用户体验。

next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
    serverComponents: true,
  },
};

Next.js 现在允许您在组件级别进行数据获取,所有这些都以 JSX 表达。通过使用 React 服务器组件,我们可以简化事情。不再需要 getServerSidePropsgetStaticProps 等特殊函数。这与 React Hooks 将数据获取与组件共同定位的模型保持一致。

您可以将任何 Next.js 页面重命名为 .server.js 以创建服务器组件,并直接在您的服务器组件中导入客户端组件。这些客户端组件将进行水合并变得可交互,因此您可以添加点赞等功能。

我们目前正在 Next.js 中研究服务器端 Suspense、选择性水合和流式渲染,并将​​在未来的博客文章中分享我们的进展。

特别感谢我们在 Google Aurora 团队的合作者 Kara EricksonGerald Monaco 对 React 18 和服务器组件所做的工作。

欲了解更多信息,请观看我们在 Next.js Conf 上的演示查看文档

ES 模块支持和 URL 导入

ES 模块为 JavaScript 带来了官方的标准化模块系统。它们受到所有主要浏览器和 Node.js 的支持。

该标准通过实现更小的包大小和 JavaScript 包,最终带来更好的用户体验,从而推动 Web 生态系统向前发展。随着 JavaScript 生态系统从 Common JS(旧标准)过渡到 ES 模块,我们致力于帮助开发人员逐步采用这些改进,而无需不必要的破坏性更改。

Next.js 11.1 开始,我们增加了对 ES 模块 优先于 CommonJS 模块的实验性支持。在 Next.js 12 中,这现在是默认设置。仍然支持导入仅提供 CommonJS 的 NPM 模块。

URL 导入

Next.js 12 包含了通过 URL 导入 ES 模块的实验性支持,无需安装或单独的构建步骤。

URL 导入允许您直接通过 URL 使用任何包。这使得 Next.js 能够像处理本地依赖项一样处理远程 HTTP(S) 资源。

如果检测到 URL 导入,Next.js 将生成 next.lock 文件来跟踪远程资源。URL 导入会在本地缓存,以确保您仍然可以离线工作。Next.js 支持客户端和服务器 URL 导入。

要选择启用,请在 next.config.js 中添加允许的 URL 前缀

next.config.js
module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev'],
  },
};

然后,您可以直接从 URL 导入模块

import confetti from 'https://cdn.skypack.dev/canvas-confetti';

任何提供 ES 模块的 CDN 都将起作用,包括无代码和设计工具,如 Framer

欲了解更多信息,请观看我们在 Next.js Conf 上的演示查看文档

支持机器人的 ISR 回退

目前,使用 fallback: true增量静态生成 会在渲染尚未生成的页面内容之前渲染回退状态。要阻止页面加载(服务器渲染),您需要使用 fallback: 'blocking'

在 Next.js 12 中,网络爬虫(例如,搜索引擎机器人) 将使用 fallback: true 自动服务器渲染 ISR 页面,同时仍向非爬虫用户代理提供回退状态的先前行为。这可以防止爬虫索引加载状态。

使用 AVIF 缩小图像

内置图像优化 API 现在支持 AVIF 图像,与 WebP 相比,可将图像缩小 20%。

AVIF 图像的优化时间可能比 WebP 长,因此我们通过 next.config.js 中新的 images.formats 属性使此功能可选

next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
};

此格式列表用于根据请求的 Accept 标头按需确定优化的图像格式。由于 AVIF 是首选,如果浏览器支持 AVIF,则将提供 AVIF。否则,如果浏览器支持 WebP,则将提供 WebP。如果两种格式都不支持,则将提供原始图像格式。

输出文件跟踪

在 Next.js 8 中,我们引入了 target 选项。这允许通过在构建过程中使用 webpack 打包所有依赖项,将 Next.js 页面输出为独立的 JavaScript 包。我们很快意识到这并不理想,因此创建了 @vercel/nft@vercel/nft 已在 Vercel 平台上所有部署中使用了两年多。

现在,我们将这些改进默认直接引入 Next.js 框架,适用于所有部署平台,提供了一种比 target 选项显著改进的方法。

Next.js 12 自动使用 @vercel/nft 跟踪每个页面和 API 路由所需的文件,并将这些跟踪结果输出到 next build 输出旁边,允许集成商自动利用 Next.js 提供的跟踪。

这些更改还优化了使用 Docker 等工具通过 next start 进行部署的应用程序。通过利用 @vercel/nft,我们将来能够使 Next.js 输出独立。运行应用程序将不需要安装任何依赖项,从而大大减小 Docker 镜像的大小。

@vercel/nft 引入 Next.js 取代了 target 方法,使得 target 在 Next.js 12 中已弃用。查看文档了解更多信息。

其他改进

  • 现在,将 pages/_app.jspages/_document.js 添加到您的应用程序会自动替换内置版本,而无需重新启动 Next.js CLI。
  • ESLint 集成现在支持在 next lint 中使用 --file 标志进行单文件 linting
  • Next.js 12 现在支持设置自定义 tsconfig.json 路径。
  • 现在支持 next.config.mjs 用于将配置编写为 ES 模块。
  • 正在进行的请求现在为 getStaticProps 进行了去重。
  • 现在使用共享工作池运行静态页面检查。
  • 快速刷新现在使用 WebSocket 连接而不是 EventSource 连接。

重大变更

  • Next.js 11 中将 webpack 5 设为默认后,我们现在已正式移除 webpack 4。我们与社区紧密合作,以确保平稳过渡到 webpack 5。
  • next.config.js 中的 target 不再需要。
  • next/image 现在使用 span 作为包装元素而不是 div
  • 最低 Node.js 版本已从 12.0.0 提升到 12.22.0,这是第一个原生支持 ES 模块的 Node.js 版本。

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

社区

五年前,我们向公众发布了 Next.js。我们致力于构建一个零配置的 React 框架,以简化您的开发体验。回顾过去,看到社区的成长以及我们共同取得的成就令人难以置信。让我们继续前进。

Next.js 是 1,800 多名独立开发者、Google 和 Facebook 等行业合作伙伴以及我们核心团队共同努力的成果。

此版本由以下贡献者提供:@ka2n, @housseindjirdeh, @rojserbest, @lobsterkatie, @thibautsabot, @javivelasco, @sokra, @rishabhpoddar, @kdy1, @huozhi, @georgegach, @ionut-botizan, @paul-creates, @TimBarley, @kimizuy, @devknoll, @matamatanot, @christianvuerings, @pgrodrigues, @mohamedbhy, @AlfonzAlfonz, @kara, @molebox, @angelopoole, @oste, @genetschneider, @jantimon, @kyliau, @mxschmitt, @PhattOZ, @finn-orsini, @kriswuollett, @harryheman, @GustavoEdinger, @AryanBeezadhur, @Blevs, @colevscode, @atcastle, @ijjk, @velocity23, @jonowu, @timneutkens, @whitep4nth3r, @micro-chipset, @TyMick, @padmaia, @arthurdenner, @vitorbal, @zNeb, @jacksonhardaker, @shuding, @kylemh, @Bundy-Mundi, @ctjlewis, @thien-do, @leerob, @Dev-CasperTheGhost, @janicklas-ralph, @rezathematic, @KonstHardy, @fracture91, @lorensr, @Sheraff, @HaNdTriX, @emilio, @oluan, @ddzieduch, @colinclerk, @x4th, @volcareso, @oiva, @sinchang, @scottrepreneur, @smakosh, @catnose99, @adrienharnay, @donsn, @andersonleite, @msp5382, @tim-hanssen, @appsplash99, @alexvilchis, @RobEasthope, @royal, @Perry-Olsson, @well-balanced, @mrmckeb, @buraksakalli, @espipj, @prateekbh, @AleksaC, @eungyeole, 和 @rgabs