跳至内容
返回博客

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) 允许您更新网站上的内容,而无需重新部署。这使得当您的无头 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 构建 API (next build) 的任何提供商。当部署到 Vercel 时,当将页面推送到边缘时,按需重新验证会在约 300 毫秒内全局传播。

更多信息,请 查看文档查看我们的演示 以了解按需重新验证的实际应用。

边缘 API 路由 (实验性)

Next.js 现在也支持将 边缘运行时 用于 API 路由。边缘运行时比 Node.js 更轻量级,可提供快速启动以实现低延迟。此外,边缘 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',
};

由于边缘运行时是轻量级的,因此它有一些限制以适应快速启动,例如,它不支持 Node.js 特定的 API,如 fs。因此,API 路由的默认运行时仍然是 nodejs

更多信息,请 查看文档

边缘服务器端渲染 (实验性)

Next.js 现在支持将 边缘运行时 用于服务器端渲染。

如上所述,边缘运行时比 Node.js 更轻量级,可提供快速启动以实现低延迟。当与 React 18 一起使用时,它可以为页面启用流式服务器端渲染。

Next.js 使用 Node.js 作为服务器端渲染页面的默认运行时。从 12.2 开始,如果您使用的是 React 18,则可以选择使用边缘运行时。

您可以在 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 支持改进

  • 改进了对 styled-componentsemotion 等 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/imagenext/link 这样的组件可以正确地被 import
  • next/link 不再需要手动添加 <a> 作为子元素。您现在可以选择使用此行为,并保持向后兼容。
  • 我们添加了实验性支持,通过修改 browsersList 来仅交付现代 JavaScript。您可以在 next.config.jsexperimental 选项中设置 browsersListForSwc: truelegacyBrowsers: 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% 增量可采用:没有重大更改,因此您可以逐步采用。
  • 高级路由约定:屏幕外存储、即时过渡等。

更多信息,请查看 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。