2022年6月28日,星期二
Next.js 12.2
发布者我们正在为 Next.js 的未来奠定基础,12.2 版本正是这一努力的体现。
- 中间件 (稳定版): 为您的整个应用程序提供动态路由。
- 按需增量静态再生 (稳定版): 更新内容无需重新部署。
- 边缘 API 路由 (实验性): 高性能 API 端点。
- 边缘服务器端渲染 (实验性): 在边缘服务器端渲染您的应用程序。
- 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) 允许您更新网站上的内容,而无需重新部署。这使得当您的无头 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 构建 API (next build
) 的任何提供商。当部署到 Vercel 时,当将页面推送到边缘时,按需重新验证会在约 300 毫秒内全局传播。
更多信息,请 查看文档 或 查看我们的演示 以了解按需重新验证的实际应用。
边缘 API 路由 (实验性)
Next.js 现在也支持将 边缘运行时 用于 API 路由。边缘运行时比 Node.js 更轻量级,可提供快速启动以实现低延迟。此外,边缘 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',
};
由于边缘运行时是轻量级的,因此它有一些限制以适应快速启动,例如,它不支持 Node.js 特定的 API,如 fs
。因此,API 路由的默认运行时仍然是 nodejs
。
更多信息,请 查看文档。
边缘服务器端渲染 (实验性)
Next.js 现在支持将 边缘运行时 用于服务器端渲染。
如上所述,边缘运行时比 Node.js 更轻量级,可提供快速启动以实现低延迟。当与 React 18 一起使用时,它可以为页面启用流式服务器端渲染。
Next.js 使用 Node.js 作为服务器端渲染页面的默认运行时。从 12.2 开始,如果您使用的是 React 18,则可以选择使用边缘运行时。
您可以在 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 客户端渲染和客户端 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 支持改进
- 改进了对
styled-components
和emotion
等 CSS-in-JS 库的支持,提供了更流畅的升级体验,并且没有重大更改。 - 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 模块,因此像
next/image
和next/link
这样的组件可以正确地被import
。 next/link
不再需要手动添加<a>
作为子元素。您现在可以选择使用此行为,并保持向后兼容。- 我们添加了实验性支持,通过修改
browsersList
来仅交付现代 JavaScript。您可以在next.config.js
的experimental
选项中设置browsersListForSwc: true
和legacyBrowsers: false
来选择使用此行为。 - 新的
@swc/helpers
优化可以防止捆绑包中的重复,在最小配置中减少捆绑包大小约2KB
,在更大的应用程序中减少更多。 - 我们显著减少了 Next.js 的安装大小。我们通过将我们的单体仓库迁移到
pnpm
来做到这一点,这使我们能够在创建预编译版本时移除重复的包。这导致安装大小减少了 14MB。 - 在我们持续改进 Next.js 自托管的努力中,我们正在将实验性的
outputStandalone: true
配置稳定到output: 'standalone'
。此配置通过仅包含必要的文件/资产来大幅减少部署大小,包括无需在构建的部署包中安装所有node_modules
。您可以在我们的with-docker
示例中看到此配置的实际应用。
布局 RFC 和高级路由支持
如果您错过了,上个月我们宣布了布局 RFC——自 2016 年推出以来 Next.js 最大的更新,其中包括
- 嵌套布局:使用嵌套路由构建复杂的应用程序。
- 专为服务器组件设计:针对子树导航进行了优化。
- 改进的数据获取:在布局中获取数据,同时避免瀑布效应。
- 使用 React 18 功能:流式传输、过渡和 Suspense。
- 客户端和服务器路由:以类似 SPA的行为进行服务器端路由。
- 100% 增量可采用:没有重大更改,因此您可以逐步采用。
- 高级路由约定:屏幕外存储、即时过渡等。
感谢贡献者
Next.js 是超过 2000 位独立开发者、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。