2019年10月7日,星期一
Next.js 9.1
发布者今天,我们很高兴地宣布 Next.js 9.1 发布,并带来了 src
和 public
目录支持。
此版本的新特性
src
目录支持:pages
目录现在可以嵌套在src
文件夹下,从而支持更广泛的应用程序设置。public
目录支持:定义要挂载到应用程序 URL 根目录的文件 (例如favicon.ico
)。
此版本中的预览特性
- 内置 CSS 支持:应用程序很快就可以导入全局 CSS,并利用开发热重载和高级生产优化、编译和 polyfill。
- 静态错误页面:静态导出预期的错误页面(如 404),以获得更好的可用性 (CDN)。
- Module / Nomodule:向在常青浏览器上运行的最终用户发送更小的 JavaScript 包。
- 改进的代码包拆分:向您的最终用户发送更少的字节,从而提高 TTI 和页面过渡速度。大型库代码块也在跨部署中进行长期缓存。
与往常一样,我们努力确保所有这些优势都向后兼容。您只需运行
npm i next@latest react@latest react-dom@latest
如果您的应用程序使用的 Next.js 版本低于 9,您可以参考升级指南,了解您可能需要升级的更改。
自从我们上次重大版本发布以来,我们很高兴看到像 TikTok、希尔顿、Elastic、Realtor 和 JW Player 这样的公司使用 Next.js 发布产品。查看案例展示了解更多信息!
src
目录支持
Next.js 有一个特殊的 pages
目录,其中每个文件都成为一个单独的路由。遵循约定优于配置的方法,此目录必须位于 Next.js 应用程序的根目录中。
在与使用 Next.js 的公司交流并检查一些闭源代码库后,我们发现开发人员想要的一个常见模式是拥有一个 src
目录来存放他们的代码,并将 pages
目录也放在其中。
从 Next.js 9.1 开始,现在可以创建 src/pages
目录,而不是在应用程序的根目录中创建 pages
目录。
使用 src
目录是可选的,并且适用于贵公司已经有此标准的情况。

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 导入
// Global styles can be imported from _app.js
import '../styles/global.css';
import App from 'next/app';
export default App;
在全局 CSS 导入之后,我们将通过 .module.css
扩展名引入对 CSS 模块的支持
// 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,同时允许旧版浏览器回退到 polyfilled ES5 代码。
这项新功能目前正在由多个大型 Next.js 应用程序在生产环境中进行测试,以收集真实世界的数据。这些测试的结果看起来很有希望,有关此更改的性能改进的更多详细信息将很快分享。
改进的代码包拆分
Next.js 当前有多个 JavaScript 包,它会加载这些包以使页面具有交互性。最值得注意的是
- 页面 JavaScript 包。
- 包含通用 JavaScript 的文件。
- Next.js 客户端运行时包。
- 动态导入(通常通过
next/dynamic
添加)。
为了确保页面具有交互性,所有这些包都必须加载,因为它们都相互依赖才能在浏览器中启动 React。
由于启动 React 需要加载这些包,因此重要的是它们要尽可能优化,并且不要从应用程序的其余部分过度下载太多代码。
因此,存在一个 commons
包,其中包含页面之间通用的 JavaScript。生成 commons
的当前代码包拆分策略的计算基于基于比率的启发式方法:如果一个模块在所有页面的 50% 中使用,它将被标记为通用模块。
但是,应用程序可能由许多不同的部分组成。例如,营销页面、博客和仪表板。如果与仪表板相比,营销页面数量很多,则 commons 计算将为营销页面带来更优化的结果。
我们的目标是在一个应用程序中同时优化这两者。
Alex Castle 定义了一个新的代码块层级(创建单独的 JavaScript 文件),它允许通过多个文件进行更优化的 commons 代码块划分,尤其是在涉及许多页面时。
与 module/nomodule 支持类似,改进的代码包拆分正在由多个大型 Next.js 应用程序在生产环境中进行测试,以收集真实世界的数据。这些测试的结果以及有关此更改的性能改进的更多详细信息将很快在另一篇博文中分享。
社区
我们对即将到来的更改感到兴奋,这些更改将提高所有 Next.js 应用程序的性能。
此外,Next.js 社区仍在不断扩大
- 我们有超过 800 位贡献者提交了至少 1 次提交。
- 在 GitHub 上,该项目已被 Star 超过 41,350 次。
- 示例目录 包含超过 210 个示例。
Next.js 社区现在拥有超过 11,250 名成员。 加入我们!
我们感谢我们的社区以及所有帮助塑造此版本的外部反馈和贡献。