跳至内容
返回博客

2020年5月11日,星期一

Next.js 9.4

发布者

我们很高兴今天推出 Next.js 9.4,其特点包括

快速刷新

快速刷新是一种新的热重载体验,可为您对 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 的启发,这确保流量始终以静态方式无中断地提供服务,并且新构建的页面仅在生成完成后才推送。

pages/blog/[slug].js
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 startVercel 边缘平台 开箱即用地支持。

接下来,我们将致力于补充 RFC 以解决另外两种增量静态生成功能

  • 一次重新生成和失效多个页面(如您的博客索引和某个博客文章)
  • 通过侦听事件(如 CMS Webhook)重新生成,抢在用户流量之前

CMS 示例

在我们宣布 下一代静态站点生成 后,我们希望分享从无头 CMS API 获取内容并将其呈现为 Next.js HTML 的真实场景。

我们与世界上一些最好的 CMS 系统的创建者合作:Contentful, DatoCMS, Prismic, SanityTakeShape,更多内容即将推出。

这些示例不仅可以使用,而且是 100% 开源并获得 MIT 许可,它们还结合了最佳实践

DatoCMS achieves impeccable results due to their built-in image optimization support.
由于其内置的图像优化支持,DatoCMS 取得了完美的结果。

由于其内置的图像优化支持,DatoCMS 取得了完美的结果

我们还与 TinaCMS 在 CMS 的一个激动人心的新方向上进行了合作:内容的页面内编辑查看他们的指南,了解如何在您的项目中实现它。

新的环境变量支持

使用 Next.js 的公司给我们的一个常见反馈是,不清楚何时将环境变量内联到浏览器捆绑包中,以及何时仅在 Node.js 环境中可用。

今天,我们宣布了两项完全向后兼容的功能,将有助于简化此过程。

首先,您现在可以在环境变量前加上 NEXT_PUBLIC_ 前缀以将其公开给浏览器。当使用该环境变量时,它将被内联到浏览器 JavaScript 捆绑包中。

您不再需要添加 next.config.js 并添加 env 键来公开这些变量。

pages/index.js
// 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 中,我们宣布了在浏览器中填充 fetch() API。今天,这种填充也扩展到了 Node.js 环境。

在实践中,您不再需要使用任何类型的服务器端 fetch 填充(例如 isomorphic-unfetchnode-fetch),因为 Next.js 将在所有环境中自动提供 fetch()

例如,当使用 getStaticProps 时,它会在构建时由 Next.js 执行

pages/blog.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 指标报告

上周,Google Chrome 团队推出了 核心 Web 指标。核心 Web 指标是提供出色 Web 体验的关键质量信号,著名的 Lighthouse 报告 就是基于这些指标构建的。

如果您希望您的网站或 Web 应用程序尽可能快,那么跟踪这些指标将非常有用,这也是 Next.js 的核心目标之一。

Chrome 团队发布了一个 核心 Web 指标 Chrome 扩展程序,它允许您作为开发人员获得有关页面性能的视觉反馈。

在构建生产 Web 应用程序时,您还需要了解您的网站对访问者和(潜在)客户的性能表现。您甚至可能希望随着时间的推移跟踪这些指标的改进或下降,以查看您的更改是否对您的受众产生了预期的影响。

为了帮助将核心 Web 指标报告到您的分析服务,我们与 Google 合作,引入了一种名为 reportWebVitals 的新方法,它可以从 pages/_app.js 中导出。

pages/_app.js
// 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;

要将此方法与您的分析服务结合使用,请参阅文档中的 “将结果发送到分析” 部分。如果您想了解更多关于核心 Web 指标的信息,可以参考 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 项目)

jsconfig.json / tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "."
  }
}

这将允许从 .(根目录)进行绝对导入。它还与 VSCode 和其他编辑器集成,支持代码导航和其他编辑器功能。

注意:如果您之前修改了 Webpack 模块别名配置 以启用绝对导入,则现在可以删除该配置。

此外,Next.js 9.4 还支持 paths 选项,允许您创建自定义模块别名。例如,以下配置允许您使用 @/design-system 代替 components/design-system

jsconfig.json / tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/design-system/*": ["components/design-system/*"]
    }
  }
}

然后您可以像这样使用您的别名

// Imports 'components/design-system/button'
import Button from '@/design-system/button';

如果您指定了 paths,则必须指定 baseUrl。您可以在 TypeScript 文档中了解有关 paths 选项的更多信息。

可配置 Sass 支持

Next.js 9.3 中推出内置 Sass 支持时,我们收到了一些用户的反馈,他们希望能够配置 Sass 编译器。例如配置 includePaths

现在可以通过在 next.config.js 中使用 sassOptions 键来实现。

next.config.js
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 讨论。讨论区是一个社区空间,您可以在这里与其他 Next.js 用户联系并提出问题。

如果您正在使用 Next.js,请随时与社区分享您的项目 URL,访问 此处

我们感谢我们的社区以及所有帮助塑造此版本的外部反馈和贡献。