跳到内容
返回博客

2024 年 1 月 18 日,星期四

Next.js 14.1

发布者

Next.js 14.1 包括开发者体验改进,其中包括

立即升级或开始使用

终端
npx create-next-app@latest

改进的自托管

我们听取了您关于如何使用 Node.js 服务器、Docker 容器或静态导出自托管 Next.js 的反馈,以提高清晰度。我们已经彻底修改了关于以下方面的自托管文档:

在 Next.js 14.1 中,我们还稳定了为增量静态再生和更精细的应用路由数据缓存提供自定义缓存处理程序的功能

next.config.js
module.exports = {
  cacheHandler: require.resolve('./cache-handler.js'),
  cacheMaxMemorySize: 0, // disable default in-memory caching
};

当使用 Kubernetes 等容器编排平台进行自托管时,使用此配置非常重要,在 Kubernetes 中,每个 pod 都将拥有缓存的副本。使用自定义缓存处理程序将允许您确保 Next.js 应用程序托管的所有 pod 之间的一致性。

例如,您可以将缓存的值保存在任何地方,例如 Redis 或 Memcached。我们要感谢 @neshca 提供的 Redis 缓存处理程序适配器 和示例。

Turbopack 改进

我们将继续专注于本地 Next.js 开发的可靠性和性能

  • 可靠性: Turbopack 通过了整个 Next.js 开发测试套件,并在 Vercel 的应用程序上进行了内部测试
  • 性能: 改进 Turbopack 初始编译时间和快速刷新时间
  • 内存使用: 改进 Turbopack 内存使用

我们计划在即将发布的版本中稳定 next dev --turbo,它仍然是可选的。

可靠性

使用 Turbopack 的 Next.js 现在通过了 5,600 个开发测试(94%),比上次更新增加了 600 个。您可以在 areweturboyet.com 上关注进度。

我们继续在 Vercel 的所有 Next.js 应用程序上进行 next dev --turbo 的内部测试,包括 vercel.comv0.dev。所有从事这些应用程序的工程师都在日常使用 Turbopack。

我们已经发现并修复了许多使用 Turbopack 的超大型 Next.js 应用程序的问题。对于这些修复,我们在 Next.js 中现有的开发测试套件中添加了新的测试。

性能

对于 vercel.com,一个大型 Next.js 应用程序,我们已经看到:

  • 本地服务器启动速度提高 76.7%
  • 使用快速刷新进行代码更新的速度提高 96.3%
  • 在没有缓存的情况下,初始路由编译速度提高 45.8%(Turbopack 尚不具备磁盘缓存)

v0.dev 中,我们发现了一个优化 Turbopack 中 React 客户端组件的发现和打包方式的机会,从而使初始编译时间加快了 高达 61.5%。在 vercel.com 中也观察到了这种性能提升。

未来改进

Turbopack 目前具有内存缓存,这提高了快速刷新的增量编译时间。

但是,在重新启动 Next.js 开发服务器时,当前不会保留缓存。Turbopack 性能的下一个重大步骤是磁盘缓存,这将允许在重新启动开发服务器时保留缓存。

开发者体验改进

改进的错误消息和快速刷新

我们知道清晰的错误消息对您的本地开发体验至关重要。我们已经进行了一些修复,以提高您在运行 next dev 时看到的堆栈跟踪和错误消息的质量。

  • 以前显示捆绑器错误(如 webpack-internal)的错误现在可以正确显示错误源代码和受影响的文件。
  • 在客户端组件中看到错误,然后在编辑器中修复错误后,快速刷新未清除错误屏幕。它需要硬重新加载。我们已经修复了许多此类实例。例如,尝试从客户端组件导出 metadata

例如,这是之前的错误消息

An example of an error from a fetch call in Next.js 14.
Next.js 14 中 fetch 调用错误的示例。

Next.js 14.1 对此进行了改进,变为:

Errors from fetch calls during rendering now display the source code of the error and the affected file.
渲染期间来自 fetch 调用的错误现在显示错误源代码和受影响的文件。

window.history.pushStatewindow.history.replaceState

应用路由器现在允许使用原生 pushStatereplaceState 方法来更新浏览器的历史记录堆栈,而无需重新加载页面。

pushStatereplaceState 调用集成到 Next.js 应用路由器中,允许您与 usePathnameuseSearchParams 同步。

当需要立即更新 URL 以保存状态(如过滤器、排序顺序或其他希望在重新加载后持久存在的信息)时,这非常有用。

'use client';
 
import { useSearchParams } from 'next/navigation';
 
export default function SortProducts() {
  const searchParams = useSearchParams();
 
  function updateSorting(sortOrder: string) {
    const params = new URLSearchParams(searchParams.toString());
    params.set('sort', sortOrder);
    window.history.pushState(null, '', `?${params.toString()}`);
  }
 
  return (
    <>
      <button onClick={() => updateSorting('asc')}>Sort Ascending</button>
      <button onClick={() => updateSorting('desc')}>Sort Descending</button>
    </>
  );
}

了解更多关于在 Next.js 中使用原生 History API的信息。

数据缓存日志记录

为了改进在运行 next dev 时 Next.js 应用程序中缓存数据的可观察性,我们对 logging 配置选项 进行了一些改进。

您现在可以显示是否存在缓存 HITSKIP 以及请求的完整 URL

终端
GET / 200 in 48ms
  Compiled /fetch-cache in 117ms
 GET /fetch-cache 200 in 165ms
   GET https://api.vercel.app/products/1 200 in 14ms (cache: HIT)
  Compiled /fetch-no-store in 150ms
 GET /fetch-no-store 200 in 548ms
   GET https://api.vercel.app/products/1 200 in 345ms (cache: SKIP)
      Cache missed reason: (cache: no-store)

可以通过 next.config.js 启用此功能

next.config.js
module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
};

next/image 支持 <picture> 和艺术指导

Next.js Image 组件现在通过 getImageProps()(稳定版)支持更高级的用例,这些用例不需要直接使用 <Image>。这包括:

import { getImageProps } from 'next/image';
 
export default function Page() {
  const common = { alt: 'Hero', width: 800, height: 400 };
  const {
    props: { srcSet: dark },
  } = getImageProps({ ...common, src: '/dark.png' });
  const {
    props: { srcSet: light, ...rest },
  } = getImageProps({ ...common, src: '/light.png' });
 
  return (
    <picture>
      <source media="(prefers-color-scheme: dark)" srcSet={dark} />
      <source media="(prefers-color-scheme: light)" srcSet={light} />
      <img {...rest} />
    </picture>
  );
}

了解更多关于 getImageProps() 的信息。

并行 & 拦截路由

在 Next.js 14.1 中,我们对并行 & 拦截路由进行了 20 项改进

在过去的两个版本中,我们一直专注于提高 Next.js 的性能和可靠性。现在我们已经能够根据您的反馈对 并行路由拦截路由 进行许多改进。值得注意的是,我们增加了对 catch-all 路由和服务器操作的支持。

  • 并行路由 允许您在同一布局中同时或有条件地渲染一个或多个页面。对于应用程序的高度动态部分,例如社交网站上的仪表板和 feed,并行路由可用于实现复杂的路由模式。
  • 拦截路由 允许您在当前布局中从应用程序的另一部分加载路由。例如,当单击 feed 中的照片时,您可以在模态窗口中显示照片,覆盖 feed。在这种情况下,Next.js 拦截 /photo/123 路由,屏蔽 URL,并将其覆盖在 /feed 之上。

了解更多关于 并行路由拦截路由,或 查看示例

其他改进

14.0 以来,我们修复了社区中一些高票数的错误。

我们最近还发布了一些视频,解释缓存 和一些您可能会觉得有用的 应用路由器的常见错误

  • [文档] 关于 重定向 的新文档
  • [文档] 关于 测试 的新文档
  • [文档] 包含 生产环境清单 的新文档
  • [功能]next/third-parties 添加 <GoogleAnalytics /> 组件 (文档)
  • [改进] create-next-app 现在更小,安装速度更快 (PR)
  • [改进] 嵌套路由抛出错误时仍可被 global-error 捕获 (PR)
  • [改进] 在服务器操作中使用 redirect 时,现在会考虑 basePath (PR)
  • [改进] 修复了 next/scriptbeforeInteractive 与应用路由器的使用问题 (PR)
  • [改进] 自动转译 @aws-sdklodash 以加快路由启动速度 (PR)
  • [改进] 修复了 next devnext/font 的未样式化内容闪烁问题 (PR)
  • [改进]notFound 错误传播到超出段错误的边界 (PR)
  • [改进] 修复了 Pages Router i18n 在区域设置域中提供公共文件的问题 (PR)
  • [改进] 如果传递了无效的 revalidate 值,则会报错 (PR)
  • [改进] 修复了在 Windows 上创建的构建在 Linux 机器上的路径问题 (PR)
  • [改进] 修复了在使用带有 basePath 的多区域应用程序时,快速刷新/HMR 的问题 (PR)
  • [改进] 改进了来自终止信号的优雅关闭 (PR)
  • [改进] 从不同路由拦截时,模态路由冲突 (PR)
  • [改进] 修复了使用 basePath 配置时拦截路由的问题 (PR)
  • [改进] 在缺少并行槽导致 404 时显示警告 (PR)
  • [改进] 改进了与 catch-all 路由一起使用时的拦截路由 (PR)
  • [改进] 改进了与 revalidatePath 一起使用时的拦截路由 (PR)
  • [改进] 修复了 @children 插槽与并行路由的用法 (PR)
  • [改进] 修复了将参数与并行路由一起使用时出现的 TypeError (PR)
  • [改进] 修复默认并行路由的通配符路由规范化问题 (PR)
  • [改进] 修复 next build 摘要中并行路由的显示问题 (PR)
  • [改进] 修复使用拦截路由时的路由参数问题 (PR)
  • [改进] 改进深度嵌套的并行/拦截路由 (PR)
  • [改进] 修复与路由组结合的拦截路由的 404 错误 (PR)
  • [改进] 修复带有服务器操作/重新验证路由器缓存的并行路由问题 (PR)
  • [改进] 修复将 rewrites 与拦截路由一起使用的问题 (PR)
  • [改进] 服务器操作现在起作用了,可以从第三方库中使用 (PR)
  • [改进] Next.js 现在可以在 ESM 包中使用 (PR)
  • [改进] 类似于 Material UI 的库的桶文件优化 (PR)
  • [改进] 构建现在会因为不正确地使用不带 SuspenseuseSearchParams 而失败 (PR)

贡献者

Next.js 是超过 3,000 名个人开发者、行业合作伙伴(如 Google 和 Meta)以及 Vercel 核心团队共同努力的成果。在 GitHub DiscussionsRedditDiscord 上加入社区。

此版本由以下团队推出

以及以下贡献者的贡献:@OlehDutchenko, @eps1lon, @ebidel, @janicklas-ralph, @JohnPhamous, @chentsulin, @akawalsky, @BlankParticle, @dvoytenko, @smaeda-ks, @kenji-webdev, @rv-david, @icyJoseph, @dijonmusters, @A7med3bdulBaset, @jenewland1999, @mknichel, @kdy1, @housseindjirdeh, @max-programming, @redbmk, @SSakibHossain10, @jamesmillerburgess, @minaelee, @officialrajdeepsingh, @LorisSigrist, @yesl-kim, @StevenKamwaza, @manovotny, @mcexit, @remcohaszing, @ryo-manba, @TranquilMarmot, @vinaykulk621, @haritssr, @divquan, @IgorVaryvoda, @LukeSchlangen, @RiskyMH, @ash2048, @ManuWeb3, @msgadi, @dhayab, @ShahriarKh, @jvandenaardweg, @DestroyerXyz, @SwitchBladeAK, @ianmacartney, @justinh00k, @tiborsaas, @ArianHamdi, @li-jia-nan, @aramikuto, @jquinc30, @samcx, @Haosik, @AkifumiSato, @arnabsen, @nfroidure, @clbn, @siddtheone, @zbauman3, @anthonyshew, @alexfradiani, @CalebBarnes, @adk96r, @pacexy, @hichemfantar, @michaldudak, @redonkulus, @k-taro56, @mhughdo, @tknickman, @shumakmanohar, @vordgi, @hamirmahal, @gaspar09, @JCharante, @sjoerdvanBommel, @mass2527, @N-Ziermann, @tordans, @davidthorand, @rmathew8-gh, @chriskrogh, @shogunsea, @auipga, @SukkaW, @agustints, @OXXD, @clarencepenz, @better-salmon, @808vita, @coltonehrman, @tksst, @hugo-syn, @JakobJingleheimer, @Willem-Jaap, @brandonnorsworthy, @jaehunn, @jridgewell, @gtjamesa, @mugi-uno, @kentobento, @vivianyentran, @empflow, @samennis1, @mkcy3, @suhaotian, @imevanc, @d3lm, @amannn, @hallatore, @Dylan700, @mpsq, @mdio, @christianvuerings, @karlhorky, @simonhaenisch, @olci34, @zce, @LavaToaster, @rishabhpoddar, @jirihofman, @codercor, @devjiwonchoi, @JackieLi565, @thoushif, @pkellner, @jpfifer, @quisido, @tomfa, @raphaelbadia, @j9141997, @hongaar, @MadCcc, @luismulinari, @dumb-programmer, @nonoakij, @franky47, @robbertstevens, @bryndyment, @marcosmartini, @functino, @Anisi, @AdonisAgelis, @seangray-dev, @prkagrawal, @heloineto, @kn327, @ihommani, @MrNiceRicee, @falsepopsky, @thomasballinger, @tmilewski, @Vadman97, @dnhn, @RodrigoTomeES, @sadikkuzu, @gffuma, @Schniz, @joulev, @Athrun-Judah, @rasvanjaya21, @rashidul0405, @nguyenbry, @Mwimwii, @molebox, @mrr11k, @philwolstenholme, @IgorKowalczyk, @Zoe-Bot, @HanCiHu, @JackHowa, @goncy, @hirotomoyamada, @pveyes, @yeskunall, @ChendayUP, @hmaesta, @ajz003, @its-kunal, @joelhooks, @blurrah, @tariknh, @Vinlock, @Nayeem-XTREME, @aziyatali, @aspehler, and @moka-ayumu。