Astro 4.14

作者
Erika
Matt Kane

Astro 4.14 现已发布!此版本包括 Content Layer API 的首次实验性发布(这是我们用于在 Astro 项目中管理内容的全新超灵活解决方案)、对内容文件内 Intellisense 的支持等等。

此版本包括以下亮点

要升级现有项目,请使用自动化的 @astrojs/upgrade CLI 工具。或者,通过运行包管理器的升级命令来手动升级

# Recommended:
npx @astrojs/upgrade
# Manual:
npm install astro@latest
pnpm upgrade astro --latest
yarn upgrade astro --latest

实验性:Content Layer API

在 Astro 2.0 中,我们引入了 内容集合(Content Collections),这是一种在 Astro 项目中管理本地内容的强大方式。虽然这已帮助数十万开发者使用 Astro 构建内容驱动的网站,但我们听到了您的反馈,希望在管理内容方面获得更大的灵活性和能力。我们很高兴宣布 Astro 中下一代内容集合的实验性发布:Content Layer API。

新的 Content Layer API 在内容集合的基础上构建,将其扩展到 src/content/ 中的本地文件之外,并允许您从任何地方(包括远程 API)获取内容。这些新集合与您现有的内容集合并行工作,您可以按照自己的节奏将它们迁移到新的 API。我们认为您会很快想要这样做,因为它们具有许多优势,但无需着急——现有集合将继续像往常一样工作。

性能

Content Layer API 是扩展 Astro 以支持具有数万或数十万页面的网站快速构建的第一步。新的 API 在内容加载方式上旨在更高效、性能更优。它会在本地缓存内容,以避免持续访问 API 的需求,并显著改进了对本地 Markdown 和 MDX 文件的处理。此基准测试展示了在 Macbook Air M1 上构建一个包含 10,000 个页面的网站时的性能表现

Astro 4.13Astro 4.14 (Content Layer)
Markdown构建时间136.29秒25.96秒快 5.3 倍
内存763.50MB276.22MB减少 64%
MDX构建时间129.82秒66.70秒快 1.9 倍
内存897.91MB674.39MB减少 25%

我们计划在未来的版本中继续改进 Content Layer API 的性能,包括增加对 SQLite 后端的支持,以处理更大的网站。

快速开始

要试用新的 Content Layer API,请在 Astro 配置中启用它

import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
contentLayer: true
}
})

然后您可以使用 Content Layer API 在 src/content/config.ts 中创建集合。

加载您的内容

新的 Content Layer API 的核心是加载器(loader),它是一个从源获取内容并将其缓存到本地数据存储的功能。Astro 4.14 内置了 glob()file() 加载器,用于处理您的本地 Markdown、MDX、Markdoc 和 JSON 文件

src/content/config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
// The ID is a slug generated from the path of the file relative to `base`
loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
publishDate: z.coerce.date(),
})
});
export const collections = { blog };

然后您可以在您的站点中使用这些内容

---
import { getEntry, render } from 'astro:content';
const post = await getEntry('blog', Astro.params.slug);
const { Content } = await render(entry);
---
<Content />

创建加载器

您不局限于内置的加载器——我们希望您能尝试构建自己的加载器。您可以从任何地方获取内容并返回一个条目数组

src/content/config.ts
const countries = defineCollection({
loader: async () => {
const response = await fetch("https://restcountries.com/v3.1/all");
const data = await response.json();
// Must return an array of entries with an id property,
// or an object with IDs as keys and entries as values
return data.map((country) => ({
id: country.cca3,
...country,
}));
},
// optionally add a schema to validate the data and make it type-safe for users
// schema: z.object...
});
export const collections = { countries };

对于更高级的加载逻辑,您可以定义一个对象加载器。这允许增量更新和条件加载,同时还提供对数据存储的完全访问。它还允许加载器定义自己的 schema,包括根据源 API 动态生成。有关更多详细信息,请参阅 Content Layer API RFC

共享您的加载器

加载器在共享时效果更佳!您可以创建一个导出加载器的模块并将其发布到 npm,然后任何人都可以将其用于他们的站点。请为您的包添加关键词 astro-loader 以便它们能够被找到。我们很高兴看到社区能创造出什么!要开始使用,请查看一些示例。以下是如何使用 RSS/Atom feed 加载器加载内容:

src/content/config.ts
import { defineCollection } from "astro:content";
import { feedLoader } from "@ascorbic/feed-loader";
const podcasts = defineCollection({
loader: feedLoader({
url: "https://feeds.99percentinvisible.org/99percentinvisible",
}),
});
export const collections = { podcasts };

了解更多

要了解有关使用 Content Layer API 的更多信息,请查阅 Content Layer RFC分享您的反馈

实验性:内容文件内的 Intellisense

Astro 4.14 引入了对内容文件 frontmatter 内 Intellisense 的实验性支持。此功能通过为 frontmatter 键和值提供补全、验证、悬停信息等,帮助您更高效地编写内容文件。这些工具基于您的内容 schema,并可直接在您的编辑器中使用。

此功能在 VS Code 和其他支持 Markdown、MDX 和 Markdoc 文件语言服务器协议的编辑器中可用。

要启用内容文件 Intellisense,请在您的 Astro 配置中添加以下内容

import { defineConfig } from 'astro';
export default defineConfig({
experimental: {
contentIntellisense: true
}
})

并在 VS Code 中,启用 astro.content-intellisense 设置。对于其他编辑器,请将 contentIntellisense: true 传递给 Astro 语言服务器的初始化参数。

{
"astro.content-intellisense": true
}

此功能目前仅在编辑器中有效,并将在未来版本中在 astro check 中启用。

弃用对动态 prerender 值的支持

为了改进我们的打包和摇树(tree-shaking)能力,Astro 4.14 弃用了对在 Astro 页面中使用动态 prerender 值的支持。

此功能现在可以用 Astro 集成中的新 astro:route:setup 钩子代替,它允许您动态控制特定页面的预渲染。

---
export const prerender = import.meta.env.PROD;
---
astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
integrations: [setPrerender()],
});
function setPrerender() {
return {
name: 'set-prerender',
hooks: {
'astro:route:setup': ({ route }) => {
if (route.component.endsWith('/blog/[slug].astro')) {
route.prerender = true;
}
},
},
};
}

新的 injectTypes 集成 API

类型生成在近年来变得非常流行,Astro 也不例外!我们广泛使用类型生成来支持 Astro DB 和内容集合(或新的 Content Layer API)等功能。

感谢 @florian-lefebvre,Astro 集成现在可以通过新的 injectTypes 集成 API 加入其中!此 API 允许集成将类型注入到用户的项目中,从而更容易为您的集成功能提供类型定义。

my-integration/index.js
export default {
name: 'my-integration',
'astro:config:done': ({ injectTypes }) => {
injectTypes({
filename: "types.d.ts",
content: "declare module 'virtual:my-integration' {}"
})
}
};

有关此功能的更多信息,请查阅 Astro 集成 API 文档

Code 组件中对 metastrings 的支持

Astro 4.14 增加了对 Code 组件中 meta 属性的支持。此属性模拟在 Markdown 中对代码块使用属性,例如 ```js astro=cool,然后可由 Shiki 转换器 用于对代码块应用自定义转换。

---
import { Code } from "astro:components";
import { transformerMetaHighlight } from '@shikijs/transformers';
---
<Code
code={code}
lang="js"
transformers={[transformerMetaHighlight()]}
meta="{1,3}" />

感谢 @jcayzac 的贡献!

错误修复和特别鸣谢

一如既往,Astro 4.14 包含了更多本文中未能提及的错误修复和小型改进!请查看完整的发布说明以了解更多信息。

感谢 Sarah Rainsberger (@sarah11918)Yan (@yanthomasdev)Bjorn Lu (@bluwy) 以及所有为此次发布做出贡献的人。