跳至内容
返回博客

2019年10月7日,星期一

Next.js 9.1

发布者

今天,我们很高兴地宣布 Next.js 9.1,它支持 `src` 和 `public` 目录。

此版本的新增功能

  • `src` 目录支持:`pages` 目录现在可以嵌套在 `src` 文件夹下,支持更多类型的应用程序设置。
  • `public` 目录支持:定义要安装在应用程序 URL 根目录下的文件(例如 `favicon.ico`)。

此版本中的预览

  • 内置 CSS 支持:应用程序很快就可以导入全局 CSS 并利用开发热重载和高级生产优化、编译和填充。
  • 静态错误页面:静态导出预期的错误页面(如 404),以提高可用性(CDN)。
  • 模块/非模块:向在 Evergreen 浏览器上运行的最终用户交付更小的 JavaScript 包。
  • 改进的包拆分:向最终用户交付更少的字节,从而提高 TTI 和页面转换速度。大型库块也会在部署中长期缓存。

与往常一样,我们努力确保所有这些优势都向后兼容。您需要做的只是运行

终端
npm i next@latest react@latest react-dom@latest

如果您的应用程序使用的是 9 之前的 Next.js 版本,您可以参考升级指南,了解您可能需要升级的更改。

自从我们上次发布主要版本以来,我们很高兴地看到像TikTok希尔顿ElasticRealtorJW Player 使用 Next.js 发布。查看展示了解更多信息!

`src` 目录支持

Next.js 有一个特殊的 `pages` 目录,其中每个文件都成为一个单独的路由,遵循约定优于配置的方法,此目录必须位于 Next.js 应用程序的根目录中。

在与使用 Next.js 的公司交谈并检查一些闭源代码库时,我们确定了开发人员想要的一个常见模式,即为他们的代码创建一个 `src` 目录,并在其中包含 `pages` 目录。

从 Next.js 9.1 开始,现在可以创建 `src/pages` 目录,而不是在应用程序的根目录中创建 `pages` 目录。

使用 `src` 目录是可选的,它涵盖了您的公司已经实施此标准的情况。

The pages folder in the src directory directory
src 目录中的 pages 文件夹

`public` 目录支持

除了 `pages` 目录之外,Next.js 还有另一个特殊的目录,称为 `static`,其文件映射到 `/static` 路由。

例如,`static/my-image.png` 将映射到 `/static/my-image.png`。

此约定自从 Next.js 首次发布以来一直运行良好,并且没有特别的问题。

但是,随着时间的推移,我们已经确定 `/static` 无法涵盖 Web 应用程序所需的所有内容。例如,`robots.txt` 必须从域的根目录提供服务。

从 Next.js 9.1 开始,我们引入了一个名为 `public` 的新目录。

`public` 目录中的任何文件都将映射到域的根目录。

例如,`public/robots.txt` 将映射到 `/robots.txt`。

因为 `public` 也涵盖了 `static` 目录的使用案例,所以我们决定弃用 `static` 目录,转而创建一个具有相同功能的 `public/static` 文件夹。

与往常一样,我们努力实现向后兼容性,因此 `static` 目录将继续使用弃用消息工作。

即将推出

以下功能目前处于实验性标记下,并在最终实现准备就绪后发布。

内置 CSS 支持

目前,Next.js 内置了一个名为 styled-jsx 的 CSS-in-JS 解决方案。此解决方案非常适合为单个 React 组件设置样式。

然而,在与公司沟通的过程中,我们发现普遍存在一个需求,即需要复用一些基于 CSS 的现有样式或设计系统。

通常,这意味着需要添加 next-css 插件以添加 CSS 导入支持。

我们发现大约 50% 的 Next.js 用户在其应用程序中添加了此插件。

由于这种广泛的使用,我们正在添加对 CSS 导入的内置支持,包括在开发环境中自动重新加载样式,以及在 next-css 插件中之前无法实现的生产环境优化。

初始实现目前正在生产环境的 Next.js 应用程序中进行测试。

全局 CSS 导入将首先引入

pages/_app.js
// Global styles can be imported from _app.js
import '../styles/global.css';
import App from 'next/app';
 
export default App;

在全局 CSS 导入之后,我们将引入对通过 .module.css 扩展名使用的 CSS 模块的支持

pages/index.js
// Scoped styles are imported through .module.css
import styles from '../styles/index.module.css';
 
export default function HomePage() {
  return <h1 className={styles.heading}>Hello World</h1>;
}

这将使我们能够在使用 CSS 导入时提供更好的开发体验。

您可以在 GitHub 上的 RFC 中了解更多关于正在进行的工作。

静态错误页面

当发生错误时,Next.js 会渲染一个特殊的页面,此页面在内部称为 /_error。用户可以通过创建一个导出 React 组件的 pages/_error.js 文件来自定义此页面。

渲染的错误通常分为两种情况:预期错误和意外错误。

例如,预期错误包括 404 页面。

意外错误的例子包括在 getInitialProps 中或渲染 React 树时抛出的错误,这会导致渲染 500 错误。

我们计划为预期错误添加 自动静态优化,因为通常情况下,它们不需要动态渲染。

如果用户希望动态渲染这些页面,将提供一个退出选项,但默认情况下,404 将是一个静态页面。这减少了使用 server 目标时服务器上的负载,并减少了使用 serverless 目标时的成本。

将页面设为静态的另一个好处是,在使用 CDN 时可以自动缓存它。

Google Chrome 合作

正如在 Next.js 9 公告 中分享的那样,Google Chrome 团队正在投入资源改进 Next.js,并且一直在努力为所有 Next.js 应用程序带来大规模的性能提升。

要了解有关此合作的更多信息,您可以阅读 Next.js 9 公告 并观看 Nicole Sullivan 在 React Rally 上的演讲

模块/非模块

在 Next.js 中编写代码时,通常会编写“现代”JavaScript。您可以使用所有最新的稳定功能,Next.js 会自动确保通过使用 Babel 编译代码来转换或填充这些功能。

在这一点上,许多 JavaScript 功能已在大多数浏览器中得到支持。但是,通常情况下(包括在 Next.js 中),代码会被打包成一个 JavaScript 包,并在您的应用程序支持的所有浏览器上运行。

在 Next.js 的情况下,这意味着将现代 JavaScript 编译成与 Internet Explorer 11 兼容的格式。

例如,目前,Next.js 必须为 async/await 语法提供 polyfill,因为代码可能在不支持 async/await 的浏览器中执行,这会导致程序中断。

为了避免在将现代 JavaScript 发送到支持较新语法的浏览器时破坏旧版浏览器,Next.js 将使用 模块/非模块 模式。模块/非模块模式提供了一种可靠的机制,可以将现代 JavaScript 提供给现代浏览器,同时允许旧版浏览器回退到经过 polyfill 的 ES5 代码。

此新功能目前正在多个大型 Next.js 应用程序的生产环境中进行测试,以收集真实世界的数据。这些测试的结果看起来很有希望,有关此更改性能改进的更多详细信息将很快分享。

我们看到的一个初始结果示例是 Natalie Marleny 关于在 Next.js 中启用内置模块/非模块支持前后包大小的比较。

改进的包拆分

Next.js 当前加载多个 JavaScript 包以使页面具有交互性。最值得注意的是

  • 页面 JavaScript 包。
  • 包含常用 JavaScript 的文件。
  • Next.js 客户端运行时包。
  • 动态导入(通常通过 next/dynamic 添加)。

为了确保页面具有交互性,所有这些包都必须加载,因为它们都依赖于彼此才能在浏览器中启动 React。

由于这些包是 React 启动的必要条件,因此它们必须尽可能优化,并且不要从应用程序的其他部分过度下载代码。

出于这个原因,有一个 commons 包包含页面之间的常用 JavaScript。当前包拆分策略用于生成 commons 的计算基于基于比率的启发式算法,如果某个模块在所有页面的 50% 中使用,它将被标记为公共模块。

但是,应用程序可能由许多不同的部分组成。例如,营销页面、博客和仪表盘。如果与仪表盘相比,营销页面数量众多,那么公共模块的计算将导致对营销页面进行更优化的结果。

我们的目标是在一个应用程序中同时优化这两者。

Alex Castle 定义了一个新的分块层(创建单独的 JavaScript 文件),它允许更优化的公共模块分块,特别是当涉及到许多页面时。

与模块/非模块支持类似,改进的包拆分正在多个大型 Next.js 应用程序的生产环境中进行测试,以收集真实世界的数据。这些测试的结果以及此更改性能改进的更多详细信息将很快在单独的博文中分享。

社区

我们对即将到来的更改感到兴奋,这些更改将提高所有 Next.js 应用程序的性能。

此外,Next.js 社区仍在不断发展

  • 我们有超过 800 位贡献者至少提交了 1 次代码。
  • 在 GitHub 上,该项目获得了超过 41,350 次星标。
  • 示例目录 有超过 210 个示例。

Next.js 社区现在拥有超过11,250名成员。 加入我们!

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