跳至内容
返回博客

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,包括一个**全新的 Rust 编写的 CSS 解析器**,用于实现styled-jsx转换。

新的 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 等使用Edge 中间件的边缘平台上。

要在 Next.js 中使用中间件,您可以创建一个名为pages/_middleware.js的文件。在此示例中,我们使用标准的 Web API 响应(MDN

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

更多信息,请观看 Next.js Conf 上的演示视频以及查看文档

为 React 18 做准备

React 18将添加诸如 Suspense、更新的自动批处理、startTransition等 API 以及用于服务器渲染的新流式 API,并支持React.lazy

我们一直在与 Facebook 的 React 团队密切合作,为 React 18 准备 Next.js,因为它正朝着稳定版本迈进。我们正在使这些功能在 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、选择性水合和流式渲染,并将在一篇未来的博文中分享我们的进展。

特别感谢我们的合作者 Kara EricksonGerald MonacoGoogle Aurora 团队中为 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 上的演示,并查看文档

Bot-Aware ISR 回退

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

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

使用 AVIF 的更小图像

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

与 WebP 相比,AVIF 图像的优化可能需要更长的时间,因此我们使用 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 集成现在支持单文件 lintnext lint中使用--file标志。
  • 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 是超过 1800 名开发人员、谷歌和 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