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 中,我们还稳定了为增量静态再生和 App Router 更细粒度的数据缓存提供自定义缓存处理程序的功能
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
};
当使用 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 的现有开发测试套件中添加了新的测试。
性能
对于大型 Next.js 应用程序 vercel.com
,我们已经看到:
- 本地服务器启动速度最高提升 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
App Router 现在允许使用原生的 pushState
和 replaceState
方法来更新浏览器的历史堆栈,而无需重新加载页面。
pushState
和 replaceState
调用集成到 Next.js App Router 中,允许您与 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>
</>
);
}
了解更多关于将 原生 History API 与 Next.js 结合使用的信息。
数据缓存日志记录
为了改进在运行 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 的性能和可靠性。现在,我们已经能够根据您的反馈,对 并行 和 拦截路由 进行了许多改进。值得注意的是,我们添加了对全部捕获路由和服务器操作的支持。
- 并行路由 允许您在同一布局中同时或有条件地渲染一个或多个页面。对于应用程序的高度动态部分,例如社交网站上的仪表板和提要,并行路由可用于实现复杂的路由模式。
- 拦截路由 允许您在当前布局中从应用程序的另一部分加载路由。例如,当单击提要中的照片时,您可以在模态框中显示照片,覆盖提要。在这种情况下,Next.js 拦截了
/photo/123
路由,屏蔽了 URL,并将其覆盖在/feed
上。
其他改进
自 14.0
以来,我们修复了社区中许多高票数的错误。
我们最近还发布了一些视频,解释了缓存 和一些您可能会觉得有用的 App Router 的常见错误。
- [文档] 关于 重定向 的新文档
- [文档] 关于 测试 的新文档
- [文档] 包含 生产环境清单 的新文档
- [功能] 向
next/third-parties
添加<GoogleAnalytics />
组件 (文档) - [改进]
create-next-app
现在更小且安装速度更快 (PR) - [改进] 嵌套路由抛出错误时仍然可以被
global-error
捕获 (PR) - [改进] 在服务器操作中使用时,
redirect
现在尊重basePath
(PR) - [改进] 修复
next/script
和beforeInteractive
与 App Router 的使用 (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)
- [改进] 改进当与通配路由一起使用时拦截的路由 (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 这样的库进行 Barrel 文件优化 (PR)
- [改进] 现在,如果错误地使用不带
Suspense
的useSearchParams
,构建将会失败 (PR)
贡献者
Next.js 是超过 3,000 名独立开发者、谷歌和 Meta 等行业合作伙伴以及 Vercel 核心团队共同努力的成果。加入我们的社区:GitHub 讨论区, Reddit, and Discord.
此版本由以下团队为您带来
- Next.js 团队: Andrew, Balazs, Jiachi, Jimmy, JJ, Josh, Sebastian, Shu, Steven, Tim, Wyatt, 和 Zack。
- Turbopack 团队: Donny, Leah, Maia, OJ, Tobias, 和 Will。
- Next.js 文档: Delba, Steph, Michael, 和 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, 和 @moka-ayumu。