2022 年 6 月 28 日,星期二
Next.js 12.2
发布者我们正在为 Next.js 的未来奠定基础,版本号为 12.2
- 中间件 (稳定版): 为你的整个应用程序提供动态路由。
- 按需 ISR (稳定版): 无需重新部署即可更新内容。
- Edge API 路由 (实验性): 高性能 API 端点。
- Edge SSR (实验性): 在 Edge 端服务器渲染你的应用程序。
- 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 毫秒。
有关更多信息,请查看文档,或查看我们的演示,以查看按需重新验证的实际效果。
Edge API 路由 (实验性)
Next.js 现在还支持为 API 路由使用 Edge Runtime。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
。
有关更多信息,请查看文档。
Edge 服务器渲染 (实验性)
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 水合和客户端 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 模块,因此可以正确
import
诸如next/image
和next/link
之类的组件。 next/link
不再需要手动添加<a>
作为子元素。你现在可以选择加入此行为,以向后兼容的方式。- 我们通过修改
browsersList
添加了仅交付现代 JavaScript 的实验性支持。你可以通过在next.config.js
的experimental
选项中设置browsersListForSwc: true
和legacyBrowsers: false
来选择加入此行为。 - 新的
@swc/helpers
优化防止跨 bundle 重复,在最小配置中减少约2KB
的 bundle 大小,在较大的应用程序中减少更多 - 我们已显著减少了 Next.js 的安装大小。我们通过将我们的 monorepo 迁移到
pnpm
来实现这一点,这使我们可以在创建我们使用的预编译版本时删除重复的包。这导致安装大小减少了 14MB。 - 在我们不断努力改进 Next.js 自托管的过程中,我们正在将我们的实验性
outputStandalone: true
配置稳定为output: 'standalone'
。此配置通过仅包含必要的文件/资产来大幅减小部署大小,包括消除在构建的部署包中安装所有node_modules
的需要。可以在我们的with-docker
示例中看到此配置的实际应用。
布局 RFC & 高级路由支持
如果你错过了,上个月我们发布了 布局 RFC – 自 2016 年 Next.js 推出以来最大的更新,包括
- 嵌套布局: 使用嵌套路由构建复杂的应用程序。
- 专为服务器组件设计: 针对子树导航进行了优化。
- 改进的数据获取: 在布局中获取数据,同时避免瀑布流。
- 使用 React 18 功能: 流式处理、Transitions 和 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。