就在刚刚过去的 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等新特性 <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 倍,压缩是可选的:
// 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 官方博客: z.org/blog/next-1…
抖音前端正急缺人才,如果你想加入我们,欢迎加我微信和我联系。另外如果你想加入高质量前端交流群,或者你有任何其他事情想和我交流也可以添加我的个人微信
ConardLi。
文中如有错误,欢迎在后台和我留言,如果这篇文章帮助到了你,欢迎点赞、和关注。