Next.js 12 发布!迄今以来最大更新!

2021-11-05 11:45:00 浏览数 (1)

就在刚刚过去的 10 月 27 日,Next.js 团队官宣了 12 版本发布。

就像在 Next.js Conf 上宣布的那样,Next.js 12Next.js 有史以来最大的版本,更新概览如下:

  • 采用Rust 编译器:刷新速度提升 3 倍、构建速度提升约 5 倍的
  • Middleware (beta):通过配置代码在 Next.js 中实现完全的灵活性
  • React 18 支持:支持 SuspenseReact Server Components 等新特性
  • <Image />AVIF 支持:选择缩小 20% 的图像
  • Bot-aware ISR Fallback:为网络爬虫优化 SEO
  • 原生 ES 模块支持:与标准化的模块系统保持一致
  • URL Imports (alpha):支持从任何 URL 导入包(比如CDN),无需通过npm安装

我们可以通过 npm i next@latest 安装最新版的 Next.js

Rust 编译器

Next.js 12 现在默认启用了 Rust 编译器,这使它大概提高了3倍的刷新速度和5倍的构建速度。

这其实也是 Rust 迈出的一大步,因为它的稳定性现在在世界上最大的代码库之一上面得到的验证。

在编译方便,使用 Rust 进行编译比 Babel 快了 17 倍,另外他们对 webpack 进行了大量的改进,包括优化快速刷新和按需引入。

Next.js 团队为了从 Babel 迁移到 Rust 费了不小的功夫,比如他们实现了一个新的 Rust CSS 解析器 styled-jsx

在压缩方面,Rust 编译器比 Terser 压缩的速度要快 7 倍,压缩是可选的:

代码语言:javascript复制
// next.config.js

module.exports = {
  swcMinify: true
}

值得注意的是,Next.jsRust 编译器是基于 SWC 实现的。

swc 是一个用 Rust 写的高性能 TypeScript / JavaScript 转译器,类似于 babel。

为此,Next.js 还专门把 SWC 作者 DongYoon KangParcel 的核心贡献者 Maia Teegarden 挖过去了。

Middleware

Next.js 12 在这个版本引入了中间件的概念,这就类似于 Koa 框架里面的中间件,它能让你通过代码来实现更灵活的操作,而不只是通过那些烦人的配置。

在中间件里,你可以拿到用户的完整请求,然后你就可以对请求进行重写、重定向、添加 Header 等操作。

中间件里也支持例如 fetch 这样的标准运行时 Web API

如果想要在 Next.js 中使用中间件,你可以创建一个 pages/_middleware.js 文件:

代码语言:javascript复制
// pages/_middleware.js

export function middleware(req, ev) {
  return new Response('Hello, world!')
}

React 18 支持

Next.js 团队一直在和 Facebook 团队保持着紧密的合作, 虽然现在 React 18 只发布了 alpha 版本,在 Next.js 12 中依然为它提供了支持。

代码语言:javascript复制
npm install react@alpha react-dom@alpha

你只需要开启一些实验配置就可以使用 React 18 中的 Suspense、全自动批处理、startTransition 这些 API。

流式服务端渲染

React 18 中的并发渲染包括对服务器端 SuspenseSSR 流式渲染的支持,你可以通过开启下面的配置启用:

代码语言:javascript复制
// next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true
  }
}
React Server Component

React Server Component 就是让组件拥有在服务端渲染的能力,从而解决 用户体验、可维护性、性能 这个不可能的三角问题。

Server Component 的主要两点如下:

  • 运行在服务端的组件只会返回 DSL 信息,而不包含其他任何依赖,因此 Server Component 的所有依赖 npm 包都不会被打包到客户端。
  • 可以访问服务端任何 API,也就是让组件拥有了 Nodejs 能拥有的能力,你理论上可以在前端组件里干任何服务端才能干的事情。
  • Server Component 与 Client Component 无缝集成,可以通过 Server Component 无缝调用 Client Component。
  • Server Component 会按需返回信息,在当前逻辑下,走不到的分支逻辑的所有引用都不会被客户端引入。比如 Server Component 虽然引用了一个巨大的 npm 包,但某个分支下没有用到这个包提供的函数,那客户端也不会下载这个巨大的 npm 包到本地。
  • 由于返回的不是 HTML,而是一个 DSL,所以服务端组件即便重新拉取,已经产生的 State 也会被维持住。比如说 A 是 ServerComponent,其子元素 B 是 Client Component,此时对 B 组件做了状态修改比如输入一些文字,此时触发 A 重新拉取 DSL 后,B 已经输入的文字还会保留。
  • 可以无缝与 Suspense 结合,并不会因为网络原因导致连 Suspense 的 loading 都不能及时展示。
  • 共享组件可以同时在服务端与客户端运行

你可以通过下面的配置开启:

代码语言:javascript复制
// next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
    serverComponents: true
  }
}

ES Modules

ES ModulesJavaScript 带来了官方的、标准化的模块系统。目前所有主流浏览器以及Node.js 都对它提供了支持。

使用 ES Modules 可以大大的减少模块依赖解析的时间,并且可以减小包体积。

Next.js 11.1 开始,Next 添加了对 ES Modules 优先于 CommonJS 模块的实验性支持。在 Next.js 12 中,默认开启,但是现在也仍然支持导入仅提供 CommonJSNPM 包。

URL imports

Next.js 12 开始,我们可以直接通过 URL 导入任何一个包,Next.js 能够像处理本地依赖一样处理远程 HTTP(S) 资源。

代码语言:javascript复制
import confetti from 'https://cdn.skypack.dev/canvas-confetti'

如果检测到 URL importsNext.js 会生成一个 next.lock 文件来跟踪远程资源。URL imports 导入的包会在本地缓存一份,所以我们也不用担心没有网不能用。

我们只需要将允许导入的 url 前缀添加到配置文件中就可以了:

代码语言:javascript复制
module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev']
  }
}

支持 AVIF 图片

内置的图像优化 API 现在支持 AVIF 格式了,与 WebP 相比,图像会小 20%

WebP 相比,AVIF 格式可能需要更长的时间来优化,所以我们可以通过配置 next.config.jsimages.formats 属性来进行选择性启用。

代码语言:javascript复制
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp']
  }
}

另外,对于不同浏览器的兼容情况,Next.js 会根据浏览器的嗅探情况,自动选择用 AVIFWebp

更多详情请关注 Next.js 官方博客:https://z.org/blog/next-12

抖音前端正急缺人才,如果你想加入我们,欢迎加我微信和我联系。另外如果你想加入高质量前端交流群,或者你有任何其他事情想和我交流也可以添加我的个人微信 ConardLi

文中如有错误,欢迎在后台和我留言,如果这篇文章帮助到了你,欢迎点赞、在看和关注。你的点赞、在看和关注是对我最大的支持!

0 人点赞