Next.js 12 震撼发布!打造现代化前端框架
就在刚刚过去的 10 月 27 日,Next.js
团队官宣了 12 版本发布。
就像在 Next.js Conf
上宣布的那样,Next.js 12
是 Next.js
有史以来最大的版本,更新概览如下:
采用Rust 编译器:刷新速度提升 3 倍、构建速度提升约 5 倍的 Middleware (beta)
:通过配置代码在 Next.js 中实现完全的灵活性React 18 支持:支持 Suspense
、React Server Components
等新特性
支持:选择缩小 20% 的图像AVIF 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 倍,压缩是可选的:
// next.config.js
module.exports = {
swcMinify: true
}
值得注意的是,Next.js
的 Rust
编译器是基于 SWC
实现的。
swc 是一个用 Rust 写的高性能 TypeScript / JavaScript 转译器,类似于 babel。
为此,Next.js
还专门把 SWC
作者 DongYoon Kang
和 Parcel
的核心贡献者 Maia Teegarden
挖过去了。
Middleware
Next.js 12
在这个版本引入了中间件的概念,这就类似于 Koa 框架里面的中间件,它能让你通过代码来实现更灵活的操作,而不只是通过那些烦人的配置。
在中间件里,你可以拿到用户的完整请求,然后你就可以对请求进行重写、重定向、添加 Header 等操作。
中间件里也支持例如 fetch
这样的标准运行时 Web API
。
如果想要在 Next.js 中使用中间件,你可以创建一个 pages/_middleware.js
文件:
// pages/_middleware.js
export function middleware(req, ev) {
return new Response('Hello, world!')
}
React 18 支持
Next.js
团队一直在和 Facebook
团队保持着紧密的合作, 虽然现在 React 18
只发布了 alpha
版本,在 Next.js 12
中依然为它提供了支持。
npm install react@alpha react-dom@alpha
你只需要开启一些实验配置就可以使用 React 18
中的 Suspense
、全自动批处理、startTransition
这些 API。
流式服务端渲染
React 18
中的并发渲染包括对服务器端 Suspense
和 SSR
流式渲染的支持,你可以通过开启下面的配置启用:
// 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 都不能及时展示。共享组件可以同时在服务端与客户端运行
。
你可以通过下面的配置开启:
// next.config.js
module.exports = {
experimental: {
concurrentFeatures: true,
serverComponents: true
}
}
ES Modules
ES Modules
为 JavaScript
带来了官方的、标准化的模块系统。目前所有主流浏览器以及Node.js
都对它提供了支持。
使用 ES Modules
可以大大的减少模块依赖解析的时间,并且可以减小包体积。
从 Next.js 11.1
开始,Next
添加了对 ES Modules
优先于 CommonJS
模块的实验性支持。在 Next.js 12
中,默认开启,但是现在也仍然支持导入仅提供 CommonJS
的 NPM
包。
URL imports
从 Next.js 12
开始,我们可以直接通过 URL
导入任何一个包,Next.js
能够像处理本地依赖一样处理远程 HTTP(S)
资源。
import confetti from 'https://cdn.skypack.dev/canvas-confetti'
如果检测到 URL imports
,Next.js
会生成一个 next.lock
文件来跟踪远程资源。URL imports
导入的包会在本地缓存一份,所以我们也不用担心没有网不能用。
我们只需要将允许导入的 url 前缀添加到配置文件中就可以了:
module.exports = {
experimental: {
urlImports: ['https://cdn.skypack.dev']
}
}
支持 AVIF 图片
内置的图像优化 API
现在支持 AVIF
格式了,与 WebP
相比,图像会小 20%
。
与 WebP
相比,AVIF
格式可能需要更长的时间来优化,所以我们可以通过配置 next.config.js
的 images.formats
属性来进行选择性启用。
module.exports = {
images: {
formats: ['image/avif', 'image/webp']
}
}
另外,对于不同浏览器的兼容情况,Next.js
会根据浏览器的嗅探情况,自动选择用 AVIF
或 Webp
。
更多详情请关注 Next.js 官方博客:https://z.org/blog/next-12