Astro 2.1

作者
Matthew Phillips

我们刚刚发布了 Astro 2.1,主要新特性包括:

  • 内置图片支持: (实验性)自动图片优化功能正在集成到 Astro 核心中。
  • Markdoc 集成: (实验性)Stripe 推出的一种新的内容格式,针对大型项目进行了优化。
  • astro check --watch: 使用此标志在开发期间检查 .astro 文件的类型。
  • 动态路由的推断类型: 无需重复定义类型即可获取参数 (params) 和属性 (props)。

Astro 2.1 现已在 npm 上发布。运行 npm i astro@latest 升级现有项目,或在终端中运行 npm create astro 创建新项目。

内置图片支持

Astro 2.1 为 Astro 带来了内置图片优化功能的实验性支持。要在项目中启用此功能,请使用 --experimental-assets 标志运行 Astro,或在 Astro 配置文件中设置 experimental.assets 布尔标志。

如果您已经熟悉我们原有的 @astrojs/image 集成,那么 Astro 新的内置 <Image> 组件应该会感觉很熟悉,但有一些显著的改进。您现在可以使用 widthheight 属性调整图像大小而无需更改其纵横比,并使用新的 quality 属性控制图像优化级别。

---
import { Image } from "astro:assets"
import penguin from "~/assets/penguin.png"
---
<Image src={penguin} quality="high" alt="a high-quality penguin" />

生成的图像将自动为您优化为现代网络格式,以实现最佳性能和最小的累积布局偏移 (CLS)

此外,内置图片支持可以替换为其他提供商,让您可以将其连接到 Cloudinary 等生产图片 CDN 或 Vercel 等主机,以利用它们的图片优化服务。

Astro 2.1 还解决了我们自 2.0 版本发布以来最受要求的功能之一:内容集合内的图片处理。Content Collections API 现在提供了一个新的 image() schema helper,允许您在 frontmatter schema 中定义图片。

import { image, defineCollection, z } from "astro:content"
const blogCollection = defineCollection({
schema: z.object({
title: z.string(),
cover: image(),
}),
})
export const collections = {
blog: blogCollection,
}

如果您在 frontmatter 中引用的图片不存在,Astro 将会通知您。您可以进一步完善 schema,以检查图片尺寸和文件扩展名等内容。

cover: image().refine((img) => img.width === 800 && img.height === 600, {
message: "Cover needs to be 800x600 pixels!",
})

要亲自尝试,请查看我们新的资源指南中的迁移说明。我们将继续修订和改进对图片的支持,直到该功能稳定并在未来的主要版本中取消实验性标志。您可以通过在图片 RFC 上评论来提供反馈。

Markdoc 集成

The logo for the Markdoc project

Astro 2.1 还发布了一个新的实验性 Markdoc 集成。您可以通过在项目目录中运行 npx astro add markdoc@astrojs/markdoc 添加到您的项目中。

MarkdocStripe 开发的一种有前景的新内容格式,旨在满足其大规模需求。尽管我们仍然喜爱 Astro 的 MDX,但用户在处理大量 MDX 文件时出现明显速度下降的情况并不少见。

作为我们自己调查的一部分,我们构建了一个性能基准,以比较 Markdoc 在 Astro 中的构建性能与我们现有内容格式(Markdown 和 MDX)的性能。这些测试显示了令人兴奋的改进,与 MDX 渲染静态内容和交互岛屿相比,构建速度提升高达 3 倍

一旦将 @astrojs/markdoc 集成添加到您的项目中,Markdoc 将仅在使用 .mdoc 文件扩展名的内容集合中可用。您可以将 Markdoc 文件与现有 Markdown 和 MDX 文件混合使用,以实现平滑、渐进的迁移过程。

对 MDX 的支持不会消失。我们正在同时试验这两种格式,以探索 Astro 中内容的未来形态。在我们努力寻找灵活语法和扩展到大型网站之间的正确平衡时,我们非常欢迎您的反馈。特别是如果您是第一次尝试 Markdoc,请在正在进行的 Markdoc RFC 中提供您的想法。

astro check —watch

CLI output of the astro check --watch command, showing no errors and that it is waiting on file changes.

astro check 是 Astro CLI 的一个内置命令,用于对项目中的 .astro 文件进行 TypeScript 类型检查。它通常用于在合并更改或部署网站之前,在 CI 中捕获错误和类型错误。

我们从一些用户那里听说,他们希望在开发过程中也能使用相同的功能,类似于 TypeScript 中的 tsc --watch。对于某些人来说,编辑器中的错误很容易被忽略,并且在推送更改之前很容易忘记手动运行 astro check

在 Astro 2.1 中,astro check 命令新增了一个 --watch 标志。这将启动一个长期运行的进程,监听文件更改并对已更改的文件重新运行诊断。您可以通过在 package.json 中添加脚本来使其与开发服务器并行运行。

{
"scripts": {
"dev": "astro check --watch & astro dev"
}
}

动态路由的推断类型

您的 Astro 页面中的 getStaticPaths() 导出用于在 SSG 模式下定义应为动态路由构建哪些页面。对于每个页面,您返回一个 paramsprops 属性。

在 Astro 2.1 中,我们新增了两个 helper,用于推断这些类型并在模板中使用这些值时提供类型检查。

给定以下 getStaticPaths() 函数

src/pages/blog/[slug].astro
---
export async function getStaticPaths() {
const posts = await getCollection("blog")
return posts.map((post) => {
return {
params: { slug: post.slug },
props: { draft: post.data.draft, title: post.data.title },
}
})
}
---

您现在可以使用新的 InferGetStaticParamsTypeInferGetStaticPropsType helper 类型来获取 paramsprops 值的类型定义,而无需手动定义它们。

import { InferGetStaticParamsType, InferGetStaticPropsType } from "astro"
export async function getStaticPaths() {
/* ... */
}
type Params = InferGetStaticParamsType<typeof getStaticPaths>
type Props = InferGetStaticPropsType<typeof getStaticPaths>
const { slug } = Astro.params as Params
// ^? { slug: string; }
const { title } = Astro.props
// ^? { draft: boolean; title: string; }

尝试 Astro 2.1

感谢所有为此次杰出发布做出贡献的人。除了这些新功能之外,核心包和集成中也修复了许多错误。请查看完整的发布说明以了解更多信息。