跳到内容
返回博客

2019 年 10 月 7 日,星期一

Next.js 9.1

发布者

今天,我们很高兴地宣布 Next.js 9.1 发布,并带来了 srcpublic 目录支持。

此版本的新特性

  • src 目录支持pages 目录现在可以嵌套在 src 文件夹下,从而支持更广泛的应用程序设置。
  • public 目录支持:定义要挂载到应用程序 URL 根目录的文件(例如 favicon.ico)。

此版本中的预览特性

  • 内置 CSS 支持:应用程序很快就可以导入全局 CSS,并利用开发热重载和高级生产优化、编译和 polyfilling。
  • 静态错误页面:静态导出预期的错误页面(如 404),以获得更好的可用性 (CDN)。
  • Module / Nomodule:为运行在常青浏览器上的最终用户提供更小的 JavaScript 包。
  • 改进的包拆分:向最终用户发送更少的字节,从而提高 TTI 和页面过渡速度。大型库 chunk 也在跨部署中进行长期缓存。

与往常一样,我们努力确保所有这些优势都向后兼容。您只需运行以下命令即可更新

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

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

自上次主要版本发布以来,我们很高兴看到像 TikTok希尔顿 (Hilton)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 内置了一个 CSS-in-JS 解决方案,称为 styled-jsx。此解决方案非常适合样式化单个 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 上的演讲

Module / Nomodule

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

此时,许多 JavaScript 功能在大多数浏览器中都受支持。但是,通常(包括在 Next.js 中),代码以单个 JavaScript 包的形式发布,该包在您的应用程序支持的所有浏览器上运行。

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

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

为了避免破坏旧版浏览器,同时向支持较新语法的浏览器发送现代 JavaScript,Next.js 将利用 module/nomodule 模式。module/nomodule 模式提供了一种可靠的机制,用于向现代浏览器提供现代 JavaScript,同时允许旧版浏览器回退到 polyfill 的 ES5 代码。

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

我们看到的初始结果的一个示例是 Natalie Marleny 对启用 Next.js 内置 module/nomodule 支持前后的包大小进行的比较

改进的包拆分

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

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

为了确保页面变得可交互,必须加载所有这些包,因为它们都相互依赖才能在浏览器中启动 React。

由于启动 React 需要加载这些包,因此务必尽可能优化它们,并且不要从应用程序的其余部分过度下载太多代码。

因此,有一个 commons 包,其中包含页面之间通用的 JavaScript。当前包拆分策略的计算以基于比率的启发式方法为基础,如果一个模块在所有页面的 50% 中使用,则它将被标记为通用模块。

但是,应用程序可能由许多不同的部分组成。例如,营销页面、博客和仪表板。如果营销页面的数量相对于仪表板较多,则 commons 计算将为营销页面带来更优化的结果。

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

Alex Castle 定义了一个新的 chunking 层级(创建单独的 JavaScript 文件),允许更优化的 commons chunking,具有多个文件,尤其是在涉及许多页面时。

与 module/nomodule 支持类似,改进的包拆分正在多个大型 Next.js 应用程序的生产环境中进行测试,以收集真实世界的数据。这些测试的结果以及有关此更改的性能改进的更多详细信息将在另一篇博客文章中分享。

社区

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

此外,Next.js 社区仍在不断扩大

  • 我们有超过 800 位贡献者至少提交了 1 次 commit。
  • 在 GitHub 上,该项目已被 star 超过 41,350 次。
  • 示例目录 包含超过 210 个示例。

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

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