2022 年 6 月 28 日,星期二
Next.js 12.2
发布者我们正在为 Next.js 的未来奠定基础,推出 12.2 版本
- 中间件 (稳定版): 为您的整个应用程序提供动态路由。
- 按需增量静态再生 (稳定版): 无需重新部署即可更新内容。
- 边缘 API 路由 (实验性): 高性能 API 端点。
- 边缘 SSR (实验性): 在边缘服务器渲染您的应用。
- SWC 插件 (实验性): 使用您自己的插件扩展编译。
next/image
的改进: 包括新的next/future/image
组件。
立即运行 npm i next@latest
进行更新。
中间件 (稳定版)
我们很高兴地宣布,中间件在 12.2 版本中已稳定,并根据用户的反馈改进了 API。
中间件允许您在请求完成之前运行代码。根据传入的请求,您可以通过重写、重定向、添加标头或设置 Cookie 来修改响应。
import { NextRequest, NextResponse } from 'next/server';
// If the incoming request has the "beta" cookie
// then we'll rewrite the request to /beta
export function middleware(req: NextRequest) {
const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
req.nextUrl.pathname = isInBeta ? '/beta' : '/';
return NextResponse.rewrite(req.nextUrl);
}
// Supports both a single value or an array of matches
export const config = {
matcher: '/',
};
要更新到中间件的最新 API 更改,请参阅迁移指南。
在 Vercel 上免费试用中间件,或在使用 next start
进行自托管时使用。
按需增量静态再生 (稳定版)
按需增量静态再生 (ISR) 允许您在无需重新部署的情况下更新站点上的内容。当您的 headless CMS 或商务平台中的数据发生更改时,这使得立即更新您的站点变得容易。这是社区最需要的功能之一,我们很高兴它现在已稳定。
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' });
}
try {
await res.revalidate('/path-to-revalidate');
return res.json({ revalidated: true });
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating');
}
}
增量静态再生适用于任何支持 Next.js Build API (next build
) 的提供商。当部署到 Vercel 时,按需重新验证会在将页面推送到边缘时在全球范围内以约 300 毫秒的速度传播。
有关更多信息,请查看文档 或 查看我们的演示,以查看按需重新验证的实际效果。
边缘 API 路由 (实验性)
Next.js 现在还支持将 Edge Runtime 用于 API 路由。Edge Runtime 是比 Node.js 更轻量级的运行时,可为低延迟提供快速启动。此外,Edge API 路由支持来自服务器的流式响应。
您可以在 config
中设置 API 路由的运行时,指定 nodejs
(默认) 或 experimental-edge
import type { NextRequest } from 'next/server';
export default (req: NextRequest) => {
return new Response(`Hello, from ${req.url} I'm now an Edge API Route!`);
};
export const config = {
runtime: 'experimental-edge',
};
由于 Edge Runtime 是轻量级的,因此它在容纳快速启动方面存在限制 — 例如,它不支持特定于 Node.js 的 API,如 fs
。因此,API 路由的默认运行时仍然是 nodejs
。
有关更多信息,请查看文档。
边缘服务器渲染 (实验性)
Next.js 现在支持将 Edge Runtime 用于服务器渲染。
如上所述,Edge Runtime 是比 Node.js 更轻量级的运行时,可为低延迟提供快速启动。与 React 18 一起使用时,它可以为页面启用流式服务器渲染。
Next.js 使用 Node.js 作为服务器端渲染页面的默认运行时。从 12.2 版本开始,如果您正在使用 React 18,您可以选择使用 Edge Runtime。
您可以在 next.config.js
中全局设置运行时,指定 nodejs
或 experimental-edge
module.exports = {
experimental: {
runtime: 'experimental-edge',
},
};
更改默认页面运行时会影响所有页面,包括 SSR 流式处理 和 服务器组件 功能。您也可以通过导出 runtime
配置来按页面覆盖此默认值
export const config = {
runtime: 'nodejs',
};
export default function Home() {}
您可以通过在运行时查看 process.env.NEXT_RUNTIME
环境变量,以及在 webpack 编译期间检查 options.nextRuntime
变量来检测您正在使用的运行时。
有关更多信息,请查看文档。
next/image
的改进
next/future/image
组件 (实验性)
我们听取了您对当前 Image 组件的反馈,并很高兴分享新的 next/image
的早期预览。这个新的改进的图像组件需要更少的客户端 JavaScript,并简化了您样式化图像的方式
- 渲染单个
<img>
,没有<div>
或<span>
包装器 - 添加了对规范
style
属性的支持 - 移除了
layout
、objectFit
和objectPosition
属性,转而使用style
或className
- 移除了
IntersectionObserver
实现,转而使用 原生惰性加载 - 移除了
loader
配置,转而使用loader
属性 - 注意:尚无
fill
模式,因此需要width
和height
属性
这提高了性能,因为原生 loading="lazy"
不需要等待 React hydration 和客户端 JavaScript。
有关更多信息,请查看文档。
远程模式 (实验性)
next/image
现在支持实验性配置选项 remotePatterns
,当使用内置图像优化 API 时,它允许您为远程图像指定通配符。这允许比现有的 images.domains
配置更强大的匹配,后者仅对域名执行精确匹配。
module.exports = {
experimental: {
images: {
remotePatterns: [
{
// The `src` property hostname must end with `.example.com`,
// otherwise this will respond with 400 Bad Request.
protocol: 'https',
hostname: '**.example.com',
},
],
},
},
};
有关更多信息,请查看文档。
禁用图像优化
零配置图像优化 API 阻止使用 next export
,因为它需要服务器在按需请求时优化图像。直到今天,以 next export
为目标的用户需要配置 loader
以使用第三方图像优化提供商,但如果没有可用的提供商,则没有明确的解决方案。从今天开始,next export
用户可以使用新的配置属性为 next/image
的所有实例禁用图像优化
module.exports = {
experimental: {
images: {
unoptimized: true,
},
},
};
SWC 插件 (实验性)
Next.js 编译器 使用 SWC 来转换和压缩您的生产环境 JavaScript 代码。SWC 在 Next.js 12.0 中引入,以提高本地开发和构建性能。
您现在可以添加插件(用 WebAssembly 编写)以自定义编译期间的 SWC 转换行为
module.exports = {
experimental: {
swcPlugins: [
['css-variable/swc', { displayName: true, basePath: __dirname }],
],
},
};
有关更多信息,请查看文档。
React 18 支持改进
- 改进了对 CSS-in-JS 库(如
styled-components
和emotion
)的支持,提供更流畅的升级体验,并且没有破坏性更改。 - AMP 和 HTML 后优化(CSS、字体优化)现在已得到正确支持。
next/head
现在支持 React 18。- Next.js 的路由播报器(用于正确地向屏幕阅读器和其他辅助技术播报页面过渡)现在支持 React 18。
其他改进
- 在 Next.js 编译器中支持 Emotion 转换。现在支持
@emotion/babel-plugin
的大多数功能,除非您正在使用importMap
,否则可以将其删除。有关更多信息,请查看文档。 - 通过允许自定义默认选项(包括
cssProp
选项),更好地支持 Next.js 编译器中的styled-components
转换。有关更多信息,请查看文档。 - 更好地支持 JavaScript ES Modules,因此可以正确
import
诸如next/image
和next/link
之类的组件。 next/link
不再需要手动添加<a>
作为子元素。您现在可以 选择加入此行为,并向后兼容。- 我们通过修改
browsersList
添加了对仅发布现代 JavaScript 的实验性支持。您可以通过在next.config.js
的experimental
选项中设置browsersListForSwc: true
和legacyBrowsers: false
来选择加入此行为。 - 新的
@swc/helpers
优化可防止跨包重复,从而在最小配置中减少约2KB
的包大小,在更大的应用程序中减少更多 - 我们已显著减小 Next.js 的安装大小。我们通过将 monorepo 迁移到
pnpm
来实现这一点,这使我们能够在创建我们使用的预编译版本时删除重复的包。这导致安装大小减少了 14MB。 - 在我们不断努力改进 Next.js 自托管的过程中,我们将稳定我们的实验性
outputStandalone: true
配置为output: 'standalone'
。此配置通过仅包含必要的文件/资产来大幅减小部署大小,包括消除在构建的部署包中安装所有node_modules
的需求。可以在我们的with-docker
示例中看到此配置的实际应用。
布局 RFC 和高级路由支持
如果您错过了,上个月我们宣布了 布局 RFC – 这是自 2016 年引入 Next.js 以来最大的更新,包括
- 嵌套布局: 使用嵌套路由构建复杂的应用程序。
- 专为服务器组件设计: 针对子树导航进行了优化。
- 改进的数据获取: 在布局中获取数据,同时避免瀑布流。
- 使用 React 18 功能: 流式处理、过渡和 Suspense。
- 客户端和服务器路由: 以服务器为中心的路由,具有类似 SPA 的行为。
- 100% 增量可采用:没有破坏性更改,因此您可以逐步采用。
- 高级路由约定:屏幕外暂存、即时过渡等等。
感谢贡献者们
Next.js 是 超过 2,000 名个人开发者、Google Chrome 和 Meta 等行业合作伙伴以及我们在 Vercel 的核心团队共同努力的成果。
本次发布由以下贡献者促成:@huozhi, @ijjk, @kwonoj, @ViolanteCodes, @akrabdev, @timneutkens, @jpveilleux, @stigkj, @jgoping, @oof2win2, @Brooooooklyn, @CGamesPlay, @lfades, @molebox, @steven-tey, @SukkaW, @Kikobeats, @balazsorban44, @erikbrinkman, @therealmarzouq, @remcohaszing, @perkinsjr, @shuding, @hanneslund, @housseindjirdeh, @RobertKeyser, @styfle, @htunnicliff, @lukeshumard, @sagnik3, @pixelass, @JoshuaKGoldberg, @rishabhpoddar, @nguyenyou, @kdy1, @sidwebworks, @gnoff, @gaspar09, @feugy, @mfix-stripe, @javivelasco, @Chastrlove, @goncharov-vlad, @NaveenDA, @Firfi, @idkwhojamesis, @FLCN-16, @icyJoseph, @ElijahPepe, @elskwid, @irvile, @Munawwar, @ykolbin, @hulufei, @baruchadi, @imadatyatalah, @await-ovo, @menosprezzi, @gazs, @Exortions, @rubens-lopes, @woochul2, @stefee, @stmtk1, @jlarmstrongiv, @MaedahBatool, @jameshfisher, @fabienheureux, @TxHawks, @mattbrandlysonos, @iggyzap, @src200, @AkifumiSato, @hermanskurichin, @kamilogorek, @ben-xD, @dawsonbooth, @Josehower, @crutchcorn, @ericmatthys, @CharlesStover, @charlypoly, @apmatthews, @naingaungphyo, @alexandrutasica, @stefanprobst, @dc7290, @DilwoarH, @tommarshall, @stanhong, @leerob, @appsbytom, @sshyam-gupta, @saulloalmeida, @indicozy, @ArianHamdi, @Clariity, @sebastianbenz, @7iomka, @gr-qft, @Schniz, @dgagn, @sokra, @okbel, @tbvjaos510, @dmvjs, @PepijnSenders, @JohnPhamous, @kyliau, @eric-burel, @alabhyajindal, @jsjoeio, @vorcigernix, @clearlyTHUYDOAN, @splatterxl, @manovotny, @maxproske, @nvh95, @frankievalentine, @nuta, @bagpyp, @dfelsie, @qqpann, @atcastle, @jsimonrichard, @mass2527, @ekamkohli, @Yuddomack, @tonyspiro, @saurabhmehta1601, @banner4422, @falsepopsky, @jantimon, @henriqueholtz, @ilfa, @matteobruni, @ryscheng, @hoonoh, @ForsakenHarmony, @william-keller, @AleksaC, @Miikis, @zakiego, @radunemerenco, @AliYusuf95, 和 @dominiksipowicz。