跳到内容
返回博客

2022 年 6 月 28 日,星期二

Next.js 12.2

发布者

我们正在为 Next.js 的未来奠定基础,版本号为 12.2

立即运行 npm i next@latest 更新。

中间件 (稳定版)

我们很高兴地宣布,中间件在 12.2 版本中已稳定,并且根据用户的反馈改进了 API。

中间件允许你在请求完成之前运行代码。根据传入的请求,你可以通过重写、重定向、添加标头或设置 Cookie 来修改响应。

middleware.ts
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 或电商平台中的数据发生更改时,这使得立即更新你的站点变得容易。这是社区最需要的功能之一,我们很高兴它现在已稳定。

pages/api/revalidate.js
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

pages/api/hello.js
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 中全局设置运行时,指定 nodejsexperimental-edge

next.config.js
module.exports = {
  experimental: {
    runtime: 'experimental-edge',
  },
};

更改默认页面运行时会影响所有页面,包括 SSR 流式处理服务器组件 功能。你还可以通过导出 runtime 配置来按页面覆盖此默认设置

pages/index.js
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 属性的支持
  • 删除了 layoutobjectFitobjectPosition 属性,转而使用 styleclassName
  • 删除了 IntersectionObserver 实现,转而使用 原生延迟加载
  • 删除了 loader 配置,转而使用 loader 属性
  • 注意:尚无 fill 模式,因此需要 widthheight 属性

这提高了性能,因为原生 loading="lazy" 不需要等待 React 水合和客户端 JavaScript。

有关更多信息,请查看文档

远程模式 (实验性)

next/image 现在支持实验性配置选项 remotePatterns,允许你在使用内置图像优化 API 时为远程图像指定通配符。这允许比现有的 images.domains 配置更强大的匹配,后者仅对域名执行精确匹配。

next.config.js
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 的所有实例禁用图像优化

next.config.js
module.exports = {
  experimental: {
    images: {
      unoptimized: true,
    },
  },
};

SWC 插件 (实验性)

Next.js 编译器使用 SWC 来转换和压缩你的生产环境 JavaScript 代码。SWC 在 Next.js 12.0 中引入,以提高本地开发和构建性能。

你现在可以添加插件(用 WebAssembly 编写)来自定义编译期间的 SWC 转换行为

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      ['css-variable/swc', { displayName: true, basePath: __dirname }],
    ],
  },
};

有关更多信息,请查看文档

React 18 支持改进

  • 改进了对 CSS-in-JS 库(如 styled-componentsemotion)的支持,提供了更流畅的升级体验,并且没有破坏性更改。
  • 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/imagenext/link 之类的组件。
  • next/link 不再需要手动添加 <a> 作为子元素。你现在可以选择加入此行为,以向后兼容的方式。
  • 我们通过修改 browsersList 添加了仅交付现代 JavaScript 的实验性支持。你可以通过在 next.config.jsexperimental 选项中设置 browsersListForSwc: truelegacyBrowsers: 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% 增量可采用: 没有破坏性更改,因此你可以逐步采用。
  • 高级路由约定: 屏幕外暂存、即时转换等等。

有关更多信息,请查看 RFC提供反馈

感谢贡献者们

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。