2020年5月11日,星期一
Next.js 9.4
发布者我们很高兴今天推出 Next.js 9.4,其特点包括
- 快速刷新:快速可靠的实时编辑体验,已在 Facebook 规模 证明
- 增量静态再生(测试版):在部署后以毫秒为单位重新构建静态页面
- 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 示例
在我们宣布 下一代静态站点生成 后,我们希望分享从无头 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 中,我们宣布了在浏览器中填充 fetch()
API。今天,这种填充也扩展到了 Node.js 环境。
在实践中,您不再需要使用任何类型的服务器端 fetch 填充(例如 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 指标报告
上周,Google Chrome 团队推出了 核心 Web 指标。核心 Web 指标是提供出色 Web 体验的关键质量信号,著名的 Lighthouse 报告 就是基于这些指标构建的。
如果您希望您的网站或 Web 应用程序尽可能快,那么跟踪这些指标将非常有用,这也是 Next.js 的核心目标之一。
Chrome 团队发布了一个 核心 Web 指标 Chrome 扩展程序,它允许您作为开发人员获得有关页面性能的视觉反馈。
在构建生产 Web 应用程序时,您还需要了解您的网站对访问者和(潜在)客户的性能表现。您甚至可能希望随着时间的推移跟踪这些指标的改进或下降,以查看您的更改是否对您的受众产生了预期的影响。
为了帮助将核心 Web 指标报告到您的分析服务,我们与 Google 合作,引入了一种名为 reportWebVitals
的新方法,它可以从 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 项目)。
{
"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 支持
当 Next.js 9.3 中推出内置 Sass 支持时,我们收到了一些用户的反馈,他们希望能够配置 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 讨论。讨论区是一个社区空间,您可以在这里与其他 Next.js 用户联系并提出问题。
如果您正在使用 Next.js,请随时与社区分享您的项目 URL,访问 此处。
我们感谢我们的社区以及所有帮助塑造此版本的外部反馈和贡献。