2021 年 10 月 26 日,星期二
Next.js 12
发布者正如我们在 Next.js Conf上宣布的那样,Next.js 12 是我们有史以来最大的版本
- Rust 编译器:Fast Refresh 速度快约 3 倍,构建速度快约 5 倍
- 中间件 (beta 版):通过代码而非配置在 Next.js 中实现完全的灵活性
- React 18 支持:现在支持原生 Next.js API 以及 Suspense
<Image />
AVIF 支持:选择启用可使图像体积缩小 20%- Bot 感知 ISR 回退:针对网络爬虫优化 SEO
- 原生 ES 模块支持:与标准化的模块系统对齐
- URL 导入(alpha 版):从任何 URL 导入包,无需安装
- React 服务器组件(alpha 版):立即试用,包括 SSR 流式处理
立即运行 npm i next@latest
进行更新。
使用 Rust 编译器实现更快的构建和 Fast Refresh
我们希望使每个 Next.js 应用程序的生产环境构建速度更快,并在本地开发中获得即时反馈。Next.js 12 包含一个全新的 Rust 编译器,它利用了原生编译的优势。
我们的 Rust 编译器基于 SWC 构建,这是一个用于下一代快速工具的开放平台。我们优化了捆绑和编译,本地环境 Fast Refresh 速度快约 3 倍,生产环境构建速度快约 5 倍。其他改进和功能包括:

- 大型代码库的速度进一步提升: 我们已使用世界上一些最大的 Next.js 代码库验证了 Rust 编译器。
- 性能可观测性得到改进: Next.js 现在在控制台中输出客户端和服务器编译的 Fast Refresh 计时,包括编译的模块和文件数。
- 底层 webpack 改进: 我们对 webpack 进行了大量改进,包括优化 Fast Refresh 并使按需条目更可靠。
使用 Rust 进行编译比 Babel 快 17 倍,并且默认使用 Next.js 12 启用,取代了转换 JavaScript 和 TypeScript 文件。这意味着我们必须将 Next.js 中的 Babel 转换移植到 Rust,包括一个用于实现 styled-jsx
转换的全新的 Rust CSS 解析器。
新的 Rust 编译器是向后兼容的。如果您有现有的 Babel 配置,您将自动选择退出。我们计划很快移植对 styled-components
、emotion
和 relay
等常用库的解析。如果您正在使用自定义 Babel 设置,请分享您的配置。
您还可以选择启用 Rust 编译器进行代码压缩。这比 Terser 快 7 倍。代码压缩在彻底验证之前是选择启用的,因为它取代了多年的基础设施。
module.exports = {
swcMinify: true,
};
除了聘请 SWC 的创建者 DongYoon Kang 和 Maia Teegarden (Parcel 的贡献者)之外,我们还在继续投资 Rust 生态系统。如果您有 Rust 工作经验,请申请加入我们的团队。
有关更多信息,请观看 Next.js Conf 上的演示。
中间件介绍
中间件使您可以使用代码而不是配置。这使您在 Next.js 中具有完全的灵活性,因为您可以在请求完成之前运行代码。根据用户的传入请求,您可以通过重写、重定向、添加标头甚至流式传输 HTML 来修改响应。

中间件可用于任何为一组页面共享逻辑的功能,包括:
中间件使用严格的运行时,支持标准 Web API,如 fetch
。这可以在使用 next start
的情况下开箱即用,并且在像 Vercel 这样的边缘平台上也能开箱即用,Vercel 使用 Edge Middleware。
要在 Next.js 中使用中间件,您可以创建一个文件 pages/_middleware.js
。在此示例中,我们使用标准 Web API 响应 (MDN)
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 12 中通过实验性标志提供这些功能供您立即试用。
npm install react@alpha react-dom@alpha
服务器端流式处理
React 18 中的并发功能包括对服务器端 Suspense 和 SSR 流式处理支持的内置支持。这使您可以使用 HTTP 流式处理来服务器渲染页面。这是 Next.js 12 中的一项实验性功能,但一旦启用,SSR 将使用与中间件相同的严格运行时。
要启用,请使用实验性标志 concurrentFeatures: true
module.exports = {
experimental: {
concurrentFeatures: true,
},
};
React 服务器组件
React 服务器组件允许我们在服务器上渲染所有内容,包括组件本身。这与服务器端渲染(您在服务器上预先生成 HTML)从根本上不同。使用服务器组件,无需客户端 JavaScript,从而加快页面渲染速度。这改善了应用程序的用户体验,将服务器渲染的最佳部分与客户端交互性相结合。
module.exports = {
experimental: {
concurrentFeatures: true,
serverComponents: true,
},
};
Next.js 现在使您能够在组件级别执行数据获取,所有这些都表示为 JSX。通过使用 React 服务器组件,我们可以简化操作。不再需要像 getServerSideProps
或 getStaticProps
这样的特殊函数。这与 React Hooks 的模型(将数据获取与您的组件放在一起)保持一致。
您可以将任何 Next.js 页面重命名为 .server.js
以创建服务器组件,并将客户端组件直接导入到服务器组件中。这些客户端组件将进行 hydration 并变得可交互,因此您可以添加诸如点赞之类的功能。
我们目前正在 Next.js 中研究服务器端 Suspense、选择性 hydration 和流式渲染,并将在以后的博客文章中分享我们的进展。
特别感谢我们的合作者 Kara Erickson 和 Gerald Monaco (Google 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 前缀
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 感知 ISR 回退
目前,使用 fallback: true
的 增量静态再生 (ISR) 在首次请求尚未生成的页面时,会先渲染回退状态,然后再渲染页面内容。要阻止页面加载(服务器端渲染),您需要使用 fallback: 'blocking'
。
在 Next.js 12 中,网络爬虫(例如搜索引擎机器人) 将自动使用 fallback: true
服务器端渲染 ISR 页面,同时仍然为非爬虫 User-Agent 提供回退状态的先前行为。这可以防止爬虫索引加载状态。
使用 AVIF 的更小图像
内置的图像优化 API 现在支持 AVIF 图像,与 WebP 相比,图像尺寸缩小了 20%。
与 WebP 相比,AVIF 图像可能需要更长的时间来优化,因此我们使用 next.config.js
中的新 images.formats
属性使此功能成为可选功能
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
};
此格式列表用于根据请求的 Accept
标头按需确定优化的图像格式。由于 AVIF 排在第一位,如果浏览器支持 AVIF,则将提供 AVIF。如果不支持 AVIF,如果浏览器支持 WebP,则将提供 WebP。如果两种格式都不支持,则将提供原始图像格式。
输出文件追踪
在 Next.js 8 中,我们引入了 target
选项。这允许通过在构建期间使用 webpack 打包所有依赖项,将 Next.js 页面作为独立的 JavaScript 捆绑包输出。我们很快意识到这并不理想,因此创建了 @vercel/nft
。@vercel/nft
已在 Vercel 平台上的所有部署中使用了 2 年多。
现在,我们将这些改进直接引入到 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.js
或pages/_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, and @rgabs