今天我们很高兴地推出 Next.js 9.4,主要特性包括:
- 快速刷新 (Fast Refresh):提供快速可靠的实时编辑体验,已在 Facebook 规模 得到验证
- 增量静态再生 (beta):部署后以毫秒级速度重建静态页面
- CMS 示例:提供与 Contentful、DatoCMS、Prismic、Sanity 和 TakeShape 集成的示例,使用我们的 新一代静态站点生成
- 新环境变量支持:内置支持
.env
文件和NEXT_PUBLIC_
前缀,与 CRA 类似 - 改进的内置 Fetch 支持:无需再导入
node-fetch
和isomorphic-fetch
,Node.js 和所有浏览器(构建时和运行时)都内置了fetch
polyfill - 集成 Web 核心指标报告:从真实流量中捕获 影响 Lighthouse 分数的指标
- 绝对导入和别名:更清晰简洁的导入,避免
../../../
路径混乱 - 可配置的 Sass 支持:配置
includePaths
等 内置 Sass 支持 的选项 - 改进的日志输出:更易读、格式统一且减少重复的控制台输出
快速刷新 (Fast Refresh)
快速刷新是一种新的热重载体验,可即时反馈对 React 组件所做的编辑。从 Next.js 9.4 开始,默认启用 所有项目的快速刷新功能。
热重载 早已存在,但 历史上一直 过于脆弱,无法默认在工作流中使用。因此,Next.js 之前实现了一种粗略的热重载形式,会重置整个应用状态。
旧的热重载实现无法应对编译或运行时错误,如果在编辑 CSS 或 JavaScript 时出现拼写错误,会触发应用完全重新加载。这种方式不够理想,会打断开发思路。
快速刷新深度集成到 React 本身(通过 React Refresh),使 Next.js 能够对 React 组件树执行精确的预测性更新。
这意味着 Next.js 只会更新你编辑的文件中的代码,并且仅重新渲染该组件,不会丢失组件状态。这包括样式(内联、CSS-in-JS 或 CSS/Sass Modules)、标记、事件处理程序和效果(通过 useEffect
)。
一个包含编译和运行时错误(快速恢复)以及保留状态的编辑会话演示。
作为此体验的一部分,我们完全重新设计了错误覆盖层,使其更有帮助,并使应用对拼写错误或运行时错误更具弹性。包括但不限于:
- 精确的错误位置,解析为编译前代码的 原始行和列
- 上下文相关的 源代码片段,支持 点击在编辑器中打开
- 修复语法错误后 恢复开发会话,不丢失应用状态
- 修复错误后 自动消除 未处理的运行时错误
我们要感谢 Dan Abramov 在实现此功能过程中提供的宝贵贡献和帮助。
增量静态再生 (beta)
Next.js 在 9.3 版本中引入了静态站点生成方法,目标明确:我们应获得 静态化的优势(始终快速、始终在线、全球分发),同时提供 Next.js 所擅长的对动态数据的出色支持。
为了兼顾两者优势,Next.js 支持 增量静态生成,在构建站点后更新静态内容。例如,在 9.3 版本中我们引入了 getStaticPaths
中的 fallback: true
选项,允许在运行时添加 新页面。
我们最近 构建了一个示例 展示 Next.js 如何以这种方式静态预渲染无限数量的页面。
今天,我们还推出了 增量静态再生 (beta),这是一种 更新现有页面 的机制,通过在流量到来时在后台重新渲染它们。受 stale-while-revalidate 启发,这确保流量不间断地提供静态内容,新构建的页面仅在生成完成后推送。
与 SSR 不同,增量静态再生确保你保留静态化的优势:
- 无延迟峰值。页面始终快速提供。
- 页面永不离线。如果后台页面重新生成失败,旧页面保持不变。
- 数据库和后端负载低。页面最多同时重新计算一次。
增量功能(添加页面和惰性更新)以及 预览模式 都已完全支持 next start
和 Vercel 边缘平台 开箱即用。
接下来,我们将制定补充 RFC 以解决另外两个增量静态生成能力:
- 同时重新生成和失效多个页面(如博客索引和特定博客文章)
- 通过监听事件(如 CMS webhooks)在用户流量到来前重新生成
CMS 示例
在我们宣布 新一代静态站点生成 后,我们希望分享从 Headless CMS API 获取内容并将其渲染为 Next.js HTML 的实际场景。
我们与一些全球最佳 CMS 系统的创建者合作:Contentful、DatoCMS、Prismic、Sanity 和 TakeShape,更多即将推出。
这些示例不仅可以直接使用,100% 开源且采用 MIT 许可,还融入了最佳实践:
DatoCMS 因其内置的图像优化支持而取得了完美效果。
我们还与 TinaCMS 合作探索 CMS 的新方向:页面内内容编辑。查看他们的指南 了解如何为你的项目实现此功能。
新环境变量支持
使用 Next.js 的公司反馈的一个常见问题是,不清楚环境变量何时会内联到浏览器包中,何时仅在 Node.js 环境中可用。
今天我们宣布两个完全向后兼容的功能,将帮助简化此流程。
首先,现在可以在环境变量前添加 NEXT_PUBLIC_
前缀以将其暴露给浏览器。使用该环境变量时,它将内联到浏览器 JavaScript 包中。
不再需要添加 next.config.js
并设置 env
键来暴露这些变量。
第二个变化是 Next.js 现在默认支持 .env
文件加载。允许你轻松定义开发和生成环境变量。
你可以在 环境变量文档 中阅读更多关于 .env
加载的信息。
这些新功能将通过以下约定简化环境变量的使用:
- 默认情况下,环境变量仅在 Node.js 环境中可用
- 以
NEXT_PUBLIC_
为前缀的环境变量会暴露给浏览器
改进的内置 Fetch 支持
在 Next.js 9.1.7 中,我们宣布在浏览器中 polyfill fetch()
API。今天这个 polyfill 已扩展到 Node.js 环境。
实际上,你不再需要使用任何类型的服务端 fetch polyfill(如 isomorphic-unfetch
或 node-fetch
),因为 Next.js 将在所有环境中自动提供 fetch()
。
例如,在使用 getStaticProps
时(在构建时由 Next.js 执行):
集成 Web 核心指标报告
上周 Google Chrome 团队推出了 核心 Web 指标 (Core Web Vitals)。核心 Web 指标是提供出色 Web 用户体验的关键质量信号,著名的 Lighthouse 报告 即基于此构建。
如果你想使网站或 Web 应用尽可能快,跟踪这些指标非常有用,这也是 Next.js 的核心目标之一。
Chrome 团队发布了 核心 Web 指标 Chrome 扩展,允许开发者直观了解页面性能。
在构建生产 Web 应用时,你还希望了解访问者和(潜在)客户的网站性能。你甚至可能希望跟踪这些指标随时间的改进或退化,以查看更改是否对受众产生预期影响。
为了帮助将核心 Web 指标报告到分析服务,我们 与 Google 合作 引入了一个名为 reportWebVitals
的新方法,可以从 pages/_app.js
导出:
要结合分析服务使用此方法,请参阅文档中的 "发送结果到分析" 部分。如果你想了解更多关于核心 Web 指标的信息,可以参考 web.dev/vitals。
绝对导入和别名
如果你正在开发大型项目,一些 import
语句可能会受到 ../../../
路径混乱的影响:
在这种情况下,我们可能希望使用 绝对导入 而不是相对导入。假设 components
目录存在于根目录,我们希望 import
语句如下所示:
我们很高兴地宣布,Next.js 9.4 使得为 JavaScript 和 TypeScript 项目设置绝对导入变得非常简单。只需将 baseUrl
配置添加到 jsconfig.json
(JS 项目) 或 tsconfig.json
(TS 项目)。
这将允许从 .
(根目录)进行绝对导入。它还集成了 VSCode 和其他编辑器,支持代码导航和其他编辑器功能。
注意: 如果你之前修改过 Webpack 模块别名配置 以启用绝对导入,现在可以删除该配置。
此外,Next.js 9.4 还支持 paths
选项,允许创建自定义模块别名。例如,以下配置允许使用 @/design-system
代替 components/design-system
:
然后可以像这样使用别名:
如果指定 paths
,则必须指定 baseUrl
。你可以在 TypeScript 文档 中了解更多关于 paths
选项的信息。
可配置的 Sass 支持
在 Next.js 9.3 中推出内置 Sass 支持后,我们收到部分用户的反馈,希望配置 sass 编译器。例如配置 includePaths
。
现在可以通过在 next.config.js
中使用 sassOptions
键实现:
改进的日志输出
我们重新设计了命令行输出,使其更加一致,并减少重复数据的输出,如部署 URL、等待开发服务器启动等。我们还更改了消息类型的间距,使其在消息之间保持一致,不再逐行跳动。
在 9.4 之前版本运行 next dev
在 9.4 版本运行 next dev
社区
我们很高兴看到 Next.js 的采用持续增长:
- 我们已有超过 1066 位独立贡献者。
- 在 GitHub 上,项目已获得超过 48,000 次 star。
加入 GitHub Discussions 上的 Next.js 社区。Discussions 是一个社区空间,允许你与其他 Next.js 用户联系并提问。
如果你正在使用 Next.js,欢迎 分享你的项目链接 与社区交流。
我们感谢社区以及所有外部反馈和贡献,帮助塑造了这个版本。