跳到内容
返回博客

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 毫秒的速度传播。

有关更多信息,请查看文档查看我们的演示,以查看按需重新验证的实际效果。

边缘 API 路由 (实验性)

Next.js 现在还支持将 Edge Runtime 用于 API 路由。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

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

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

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 hydration 和客户端 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 Modules,因此可以正确 import 诸如 next/imagenext/link 之类的组件。
  • next/link 不再需要手动添加 <a> 作为子元素。您现在可以 选择加入此行为,并向后兼容。
  • 我们通过修改 browsersList 添加了对仅发布现代 JavaScript 的实验性支持。您可以通过在 next.config.jsexperimental 选项中设置 browsersListForSwc: truelegacyBrowsers: 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% 增量可采用:没有破坏性更改,因此您可以逐步采用。
  • 高级路由约定:屏幕外暂存、即时过渡等等。

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

感谢贡献者们

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。