2020 年 5 月 11 日,星期一
Next.js 9.4
发布者今天我们很高兴地推出 Next.js 9.4,其特点包括
- 快速刷新:快速且可靠的实时编辑体验,已在 Facebook 规模上得到验证
- 增量静态再生(beta 版):在部署后以毫秒为单位重建静态页面
- CMS 示例:Contentful、DatoCMS、Prismic、Sanity 和 TakeShape 的示例,使用了我们新的 下一代静态站点生成
- 新的环境变量支持:内置支持
.env
和NEXT_PUBLIC_
前缀,与 CRA 中相同 - 改进的内置 Fetch 支持:抛弃您的
node-fetch
和isomorphic-fetch
导入,转而使用内置的fetch
polyfill,适用于 Node.js 和所有浏览器(构建和运行时) - 集成的 Web Vitals 报告:捕获驱动 Lighthouse 分数的 指标,但来自您的真实流量
- 绝对导入和别名:更清晰和更短的导入,避免
../../../
意大利面条式代码 - 可配置的 Sass 支持:配置
includePaths
和我们的 内置 Sass 支持 的其他选项 - 改进的日志输出:更易于阅读、格式一致且重复性更低的控制台输出
快速刷新
快速刷新是一种新的热重载体验,可让您即时获得对 React 组件所做编辑的反馈。现在,对于 Next.js 9.4 或更高版本上的所有项目,默认启用此功能。
热重载已经 存在很长时间了,但 历史上一直 过于脆弱,无法在您的工作流程中默认启用。因此,Next.js 之前实现了粗略的热重载形式,该形式会重置应用程序的整个状态。
旧的热重载实现对编译或运行时错误不具有弹性,如果您在编辑 CSS 或 JavaScript 时出现拼写错误,则会执行应用程序的完全重新加载。这是不理想的,并且会中断您的思路。
快速刷新深入集成到 React 本身(通过 React Refresh),使 Next.js 能够对您的 React 组件树执行可预测的精确更新。
这意味着 Next.js 将仅更新您编辑的文件中的代码,并且仅重新渲染该组件,而不会丢失组件状态。这包括样式(内联、CSS-in-JS 或 CSS/Sass 模块)、标记、事件处理程序和效果(通过 useEffect
)。
作为此体验的一部分,我们完全重新设计了错误覆盖,使其更具帮助性并使您的应用程序能够应对拼写错误或运行时错误。这包括但不限于
- 准确的错误位置,解析到代码的原始行和列,在编译之前
- 上下文相关的源代码片段,能够单击以在编辑器中打开
- 修复语法错误后,开发会话恢复,而不会丢失应用程序状态
- 当您修复错误时,自动消除未处理的运行时错误
我们要感谢 Dan Abramov 对实现此功能做出的宝贵贡献和帮助。
增量静态再生(beta 版)
Next.js 在 9.3 中引入了静态站点生成方法,其明确目标是:我们应该获得 静态的优势 (始终快速、始终在线、全球分发),但要为动态数据提供出色的支持,而这正是 Next.js 的优势。
为了兼顾两者,Next.js 支持增量静态生成,在您构建站点后更新静态内容。例如,在 9.3 中,我们在 getStaticPaths
中引入了 fallback: true
选项,这使您可以在运行时添加新页面。
我们最近 整理了一个示例,展示了 Next.js 如何以这种方式静态预渲染无限数量的页面。
今天,我们还推出了 增量静态再生 (beta),这是一种更新现有页面的机制,方法是在后台重新渲染它们,同时有流量进入。受到 stale-while-revalidate 的启发,这确保了流量始终静态地不间断地提供,并且新构建的页面仅在生成完成后才推送。
export async function getStaticProps() {
return {
props: await getDataFromCMS(),
// we will attempt to re-generate the page:
// - when a request comes in
// - at most once every second
unstable_revalidate: 1,
};
}
与 SSR 不同,增量静态再生确保您保留静态的优势
- 没有延迟峰值。页面始终快速提供。
- 页面永远不会离线。如果后台页面重新生成失败,则旧页面保持不变。
- 数据库和后端负载低。页面最多同时重新计算一次。
增量功能(添加页面和延迟更新页面)以及 预览模式 都已开箱即用地完全由 next start
和 Vercel 边缘平台 支持。
接下来,我们将致力于补充 RFC,以解决另外两个增量静态生成功能
- 一次重新生成和失效多个页面(例如您的博客索引和某个博客文章)
- 通过监听事件(例如 CMS webhook)在用户流量之前重新生成
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
键来公开这些变量。
// The environment variable will be exposed to the browser
console.log('My Application Version', process.env.NEXT_PUBLIC_VERSION);
export default function HomePage() {
return <h1>Hello World</h1>;
}
第二个变化是 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 执行
export async function getStaticProps() {
// fetch no longer needs to be imported from isomorphic-unfetch
const res = await fetch('https://.../posts');
const posts = await res.json();
return {
props: {
posts,
},
};
}
function Blog({ posts }) {
// Render posts...
}
export default Blog;
集成的 Web Vitals 报告
上周,Google Chrome 团队推出了 Core Web Vitals。Core Web Vitals 是交付出色的 Web UX 的关键质量信号,著名的 Lighthouse 报告 构建于其之上。
如果您希望您的网站或 Web 应用程序尽可能快,那么跟踪这些指标非常有用,这也是 Next.js 的核心目标之一。

Chrome 团队发布了一个 Core Web Vitals Chrome 扩展,使您作为开发人员可以获得有关页面性能的可视化反馈。
在构建生产 Web 应用程序时,您还想知道您的站点对访问者和(潜在)客户的性能如何。您甚至可能想跟踪这些指标随时间的改进或衰退,以查看您的更改是否对您的受众产生了预期的影响。
为了帮助向您的分析服务报告 Core Web Vitals,我们引入了一个新的方法 reportWebVitals
,可以从 pages/_app.js
中导出,这是 与 Google 合作 完成的。
// Will be called once for every metric that has to be reported.
export function reportWebVitals(metric) {
// These metrics can be sent to any analytics service
console.log(metric);
}
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
要将此方法与您的分析服务结合使用,请参阅文档的 “将结果发送到分析” 部分。如果您想了解有关 Core Web Vitals 的更多信息,可以参考 web.dev/vitals。
绝对导入和别名
如果您正在开发大型项目,则某些 import
语句可能会受到 ../../../
意大利面条式代码的困扰
import Button from '../../../../components/button';
在这种情况下,我们可能希望使用绝对导入而不是相对导入。假设 components
目录存在于根目录中,我们可能希望 import
语句看起来像
import Button from 'components/button';
我们很高兴地宣布,Next.js 9.4 使 JavaScript 和 TypeScript 项目的绝对导入设置变得超级简单。您只需将 baseUrl
配置添加到 jsconfig.json
(JS 项目) 或 tsconfig.json
(TS 项目)。
{
"compilerOptions": {
"baseUrl": "."
}
}
这将允许从 .
(根目录)进行绝对导入。它还与 VSCode 和其他编辑器集成,支持代码导航和其他编辑器功能。
注意: 如果您之前修改过 Webpack 模块别名配置 以启用绝对导入,则现在可以删除该配置。
此外,Next.js 9.4 也支持 paths
选项,该选项允许您创建自定义模块别名。例如,以下配置允许您使用 @/design-system
而不是 components/design-system
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/design-system/*": ["components/design-system/*"]
}
}
}
然后您可以像这样使用您的别名
// Imports 'components/design-system/button'
import Button from '@/design-system/button';
如果您指定了 paths
,则必须指定 baseUrl
。您可以在 TypeScript 文档中了解有关 paths
选项的更多信息。
可配置的 Sass 支持
当内置 Sass 支持在 Next.js 9.3 中推出时,我们收到了用户反馈,一部分用户希望配置 Sass 编译器。例如,配置 includePaths
。
现在可以通过在 next.config.js
中使用 sassOptions
键来实现这一点
const path = require('path');
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
};
改进的日志输出
我们重新设计了命令行输出,使其更一致,并减少了重复数据的输出,例如部署 URL、等待开发服务器启动等等。我们还更改了消息类型的间距,使其在消息之间保持一致,这意味着它们不再在行与行之间跳动。
在 9.4 之前的版本上运行 next dev

在 9.4 上运行 next dev

社区
我们很高兴看到 Next.js 的采用率持续增长
- 我们已经有超过 1066 位独立贡献者。
- 在 GitHub 上,该项目已被标星超过 48,000 次。
加入 Next.js 社区,请访问 GitHub Discussions。Discussions 是一个社区空间,您可以在其中与其他 Next.js 用户联系并提出问题。
如果您正在使用 Next.js,请随时与社区分享您的项目 URL。
我们感谢我们的社区以及所有外部反馈和贡献,这些帮助塑造了此版本的发布。