2024 年 1 月 18 日,星期四
Next.js 14.1
发布者Next.js 14.1 包括开发者体验改进,其中包括
- 改进的自托管: 新文档和自定义缓存处理程序
- Turbopack 改进: 5,600 个测试通过
next dev --turbo
- DX 改进: 改进的错误消息、
pushState
和replaceState
支持 - 并行 & 拦截路由: 基于您的反馈修复了 20 个错误
next/image
改进:<picture>
、艺术指导和暗黑模式支持
立即升级或开始使用
npx create-next-app@latest
改进的自托管
我们听取了您关于如何使用 Node.js 服务器、Docker 容器或静态导出自托管 Next.js 的反馈,以提高清晰度。我们已经彻底修改了关于以下方面的自托管文档:
在 Next.js 14.1 中,我们还稳定了为增量静态再生和更精细的应用路由数据缓存提供自定义缓存处理程序的功能
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.com 和 v0.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
。
例如,这是之前的错误消息

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

window.history.pushState
和 window.history.replaceState
应用路由器现在允许使用原生 pushState
和 replaceState
方法来更新浏览器的历史记录堆栈,而无需重新加载页面。
pushState
和 replaceState
调用集成到 Next.js 应用路由器中,允许您与 usePathname
和 useSearchParams
同步。
当需要立即更新 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
配置选项 进行了一些改进。
您现在可以显示是否存在缓存 HIT
或 SKIP
以及请求的完整 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
启用此功能
module.exports = {
logging: {
fetches: {
fullUrl: true,
},
},
};
next/image
支持 <picture>
和艺术指导
Next.js Image 组件现在通过 getImageProps()
(稳定版)支持更高级的用例,这些用例不需要直接使用 <Image>
。这包括:
- 使用
background-image
或image-set
- 使用 canvas
context.drawImage()
或new Image()
- 使用
<picture>
媒体查询来实现 艺术指导 或明/暗模式图像
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/script
和beforeInteractive
与应用路由器的使用问题 (PR) - [改进] 自动转译
@aws-sdk
和lodash
以加快路由启动速度 (PR) - [改进] 修复了
next dev
和next/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)
- [改进] 构建现在会因为不正确地使用不带
Suspense
的useSearchParams
而失败 (PR)
贡献者
Next.js 是超过 3,000 名个人开发者、行业合作伙伴(如 Google 和 Meta)以及 Vercel 核心团队共同努力的成果。在 GitHub Discussions、Reddit 和 Discord 上加入社区。
此版本由以下团队推出
- Next.js 团队: Andrew, Balazs, Jiachi, Jimmy, JJ, Josh, Sebastian, Shu, Steven, Tim, Wyatt, and Zack。
- Turbopack 团队: Donny, Leah, Maia, OJ, Tobias, and Will。
- Next.js 文档: Delba, Steph, Michael, and Lee。
以及以下贡献者的贡献:@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。