Astro 7.0
摘要
Astro 7.0 是一个主要版本,专注于速度提升,具备 Rust 编译器、基于 Rust 的 Markdown/MDX 处理、基于队列的渲染引擎、Vite 8 及 Rolldown 打包器、路由缓存以及 AI 开发增强功能。
暂无内容
查看缓存全文
缓存时间: 2026/07/07 20:14
# Astro 7.0 来源:https://astro.build/blog/astro-7/ **Astro 7 来了!**
这个版本的全部重点就是速度。`.astro` 编译器已用 Rust 重写。Markdown 和 MDX 处理现在通过新的 Rust 驱动管道运行。渲染引擎已替换为更快的基于队列的方法。与 Vite 8 及其新的 Rolldown 打包器一起,Astro 7 的构建在我们的基准测试中快了 15-61%。最快的构建就是根本不发生的构建,所以 Astro 7 还稳定了路由缓存,并为 Netlify、Vercel 和 Cloudflare 添加了实验性 CDN 缓存提供商。Astro 7 还引入了高级路由,为你提供一个 `src/fetch.ts` 入口点,完全控制 Astro 的请求管道。对于 AI 辅助开发,Astro 现在可以检测编码代理,在后台运行开发服务器,并在代理需要机器可读反馈时输出结构化的 JSON 日志。完整版本亮点包括:
- **Vite 8 (https://astro.build/blog/astro-7/#vite-8)**
- **性能 (https://astro.build/blog/astro-7/#performance)**
- **Rust 编译器 (https://astro.build/blog/astro-7/#rust-compiler)**
- **Markdown 和 MDX 在 Rust 中 (https://astro.build/blog/astro-7/#markdown--mdx-in-rust)**
- **队列渲染 (https://astro.build/blog/astro-7/#queued-rendering)**
- **高级路由 (https://astro.build/blog/astro-7/#advanced-routing)**
- **路由缓存 (https://astro.build/blog/astro-7/#route-caching)**
- **CDN 缓存提供商 (https://astro.build/blog/astro-7/#cdn-cache-providers)**
- **AI 增强 (https://astro.build/blog/astro-7/#ai-enhancements)**
- **后台开发服务器 (https://astro.build/blog/astro-7/#background-dev-server)**
- **JSON 日志 (https://astro.build/blog/astro-7/#json-logging)**
- **社区 (https://astro.build/blog/astro-7/#community)**
## 立即升级
要将现有项目升级到 Astro 7,请使用自动化的 `@astrojs/upgrade` CLI 工具:
``
# 推荐:
npx @astrojs/upgrade
# 手动:
npm install astro@latest
``
对于新项目,只需使用:
查看升级指南 (https://docs.astro.build/en/guides/upgrade-to/v7/) 了解详细的迁移步骤。
## Vite 8
Astro 7 升级到了 Vite 8 (https://vite.dev/blog/announcing-vite8),这是多年来最重要的 Vite 版本。标题性变化:Vite 现在搭载了 Rolldown (https://rolldown.rs/),一个基于 Rust 的打包器,同时替代了 esbuild 和 Rollup,成为一个统一的打包器。在基准测试中,Rolldown 比 Rollup 快 10-30 倍 (https://github.com/rolldown/benchmarks),同时支持相同的 Rollup 和 Vite 插件 API。对于 Astro 用户来说,这意味着更快的构建,并且大部分项目无需更改配置。Vite 8 包含一个兼容层,可以将现有的 `esbuild` 和 `rollupOptions` 配置自动转换为其 Rolldown 等效项。如果你的项目使用了自定义的 Vite 插件,大多数应该能继续工作,因为 Rolldown 支持与 Rollup 相同的插件 API。
## 性能
Astro 7 是迄今为止最快的 Astro 版本。随着使用量的增长,越来越多的团队正在突破使用 Astro 能构建的网站类型的界限。在我们发布 Astro 6 及其庞大的内部重构之后,我们将目光投向了帮助 Astro 扩展到更大、更复杂的网站。Astro 构建的工作方式如下:
1. 将网站的页面、内容和客户端组件打包成 JavaScript。
2. 像一个小型服务器一样运行打包的代码,为每个预渲染页面创建请求,并保存生成的 HTML。
Astro 7 改进了这两个步骤,但重点放在第一步:打包网站。最大的收益来自于将构建中最慢的部分迁移到用 Rust 编写的原生代码中。生成步骤也更快,这要归功于一种新的渲染策略,可以更有效地将部分内容排队渲染。在我们的测试中,总体构建时间提高了 15–61%,有些网站**构建速度提升了一倍以上**。`.astro` 编译和 Markdown 处理在构建中占比较高的网站收益最大,因为这些正是迁移到 Rust 的部分。这些基准测试是在配备 48 GB 内存的 MacBook Pro Apple M4 Pro 上运行的:
| 网站 | 之前 | 之后 |
|------|------|------|
| https://docs.astro.build/ (~6,313 页) | 114.54s | 73.53s |
| https://astro.build/ (~308 页) | 62.70s | 24.24s |
| https://biomejs.dev/ (~6,488 页) | 176.39s | 149.90s |
| https://developers.cloudflare.com/ (8,431 页) | 386.89s | 261.94s |
| https://tauri.app/ (7,117 页) | 86.12s | 55.33s |
| https://aspire.dev/ (13,275 页) | 385.84s | 326.11s |
### Rust 编译器
我们为 `.astro` 组件格式构建了一个新的编译器,现在用 Rust 编写。该编译器是对之前基于 Go 的编译器的完全重写,大部分向后兼容,除了:
- **不再进行 HTML 修正。** Go 编译器会静默地重写你的标记以使其“有效 HTML”,通过重新排序元素、自动闭合标签和移动节点,这些操作常常让用户感到意外并导致难以调试的问题。新编译器按原样处理你的标记。
- **JSX 风格的严格性。** 未闭合的标签如 `Hello` 和未终止的属性如 `HelloWorld` 现在会导致错误。以前像 `<p>Hello` 这样的写法会被纠正为 `<p>Hello</p>`,现在你必须自己闭合标签,否则构建会失败。类似地,字符串插值现在遵循 JSX 规则:`HelloWorld` 会被视为普通文本,而 `Hello{' '}World` 会在单词之间插入一个空格。
迁移到 Rust 使我们能够为支持的平台提供原生二进制文件,并为需要它的环境提供 WASM 回退。这种模式现在已成为 JavaScript 工具世界的标准,被 Rolldown 和 Lightning CSS 等项目使用。在内部,新编译器基于 oxc (https://oxc.rs/) 进行解析,并使用 Lightning CSS (https://lightningcss.dev/) 进行 CSS 作用域限定。单独来看,Rust 编译器在 https://docs.astro.build/ 上显示构建时间大约提升了 6%。这是因为 `.astro` 编译很少是瓶颈;Markdown 处理和打包通常主导构建时间。但每一点的提升都很重要,尤其是在有数千页的大型网站上,而且编译器的提升与本版本中的其他性能改进相结合。
### Markdown 和 MDX 在 Rust 中
Astro 7 将默认的 Markdown 和 MDX 管道替换为 Sätteri (https://satteri.bruits.org/),这是一个由 Astro 核心团队成员 Erika (https://bsky.app/profile/erika.florist) 创建的 Rust 驱动处理器。将 Astro 文档和 Cloudflare 文档构建切换到 Sätteri 后,构建时间缩短了一分多钟,使得 Markdown 密集型网站成为 Astro 7 的最大赢家。直到现在,Astro 的 Markdown 管道一直运行在 unified (https://unifiedjs.com/)(remark、rehype 和一长串 JavaScript 依赖项)之上。在拥有数千页的大型网站上,这个管道通常是构建中最慢的阶段:每个文件通过 JavaScript 解析,经过一个又一个插件遍历整个 AST,然后序列化为 HTML。在 Astro 6.4 中,我们使管道可插拔 (https://astro.build/blog/astro-640/#new-markdownprocessor-api) 并发布了 Sätteri 作为可选方案。Astro 7 将其设为默认。在内部,Sätteri 使用 pulldown-cmark (https://github.com/pulldown-cmark/pulldown-cmark) 进行 CommonMark 解析,使用 Oxc (https://oxc.rs/) 进行 MDX 表达式解析,两者都是原生的 Rust。它提供平台特定的二进制文件,并带有 WASM 回退,与新的 `.astro` 编译器采用相同的方法。不过,速度不是唯一的优势。Sätteri 还原生实现了许多以前需要单独插件的 Markdown 功能:
| 功能 | unified | Sätteri |
|------|---------|---------|
| GFM(表格、脚注、删除线、任务列表) | remark-gfm 插件 | 内置,默认开启 |
| 智能标点(弯引号、长破折号) | remark-smartypants 插件 | 内置 |
| 标题 ID | remark-heading-id 或类似插件 | 内置 |
| 容器指令 | remark-directive 插件 | 内置 |
| 数学公式 | remark-math 插件 | 内置 |
| Frontmatter(YAML、TOML) | remark-frontmatter 插件 | 内置 |
| 上标/下标 | remark-supersub 或类似插件 | 内置 |
| 维基链接 | remark-wiki-link 插件 | 内置 |
非默认功能通过 `features` 选项启用:
```javascript
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';
export default defineConfig({
markdown: {
processor: satteri({
features: {
directive: true,
math: true,
headingAttributes: true,
},
}),
},
});
```
Sätteri 也有自己的插件 API。插件声明它们关心的节点类型,并跳过其余节点,而不是每次遍历整个树。这使得添加插件的成本远低于 unified,在 unified 中每个插件都会遍历每个节点。如果你依赖 remark 或 rehype 插件,基于 unified 的管道仍可通过 `@astrojs/markdown-remark` 使用:
```javascript
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import remarkToc from 'remark-toc';
export default defineConfig({
markdown: {
processor: unified({
remarkPlugins: [remarkToc],
}),
},
});
```
了解更多关于 Sätteri 的功能和插件 API,请访问 satteri.bruits.org (https://satteri.bruits.org/)。
### 队列渲染
队列渲染在 Astro 6.0 中以实验性选项引入,现在已稳定并成为默认渲染引擎。它的速度**快了约 2.4 倍**¹ (https://astro.build/blog/astro-7/#user-content-fn-1)!
```javascript
import { defineConfig } from "astro/config";
export default defineConfig({
experimental: {
queuedRendering: {
enabled: true,
pooling: true,
contentCache: 1000
}
}
})
```
以前,Astro 使用递归方法渲染页面,子节点使用相同的 `render*` 函数渲染,如下面的伪代码所示:
```javascript
export function renderComponentToString(node: unknown): string {
let destination = "";
destination += `<${node.name}>`; // 开始标签
// 渲染属性
for (const child of node.children) {
// 这里我们递归子节点,调用 renderComponentToString
destination += renderComponentToString(child);
}
destination += `</${node.name}>`; // 结束标签
return destination;
}
```
新引擎使用队列(或栈)和单个循环。队列按正确顺序填充子节点,循环持续渲染节点直到队列为空。以下伪代码是对实际情况的过度简化,但应该能提供清晰的画面:
```javascript
export function renderComponentToString(root: unknown): string {
let destination = "";
destination += `<${root.name}>`; // 开始标签
// 这是我们的队列,在渲染过程中填充并刷新
let stack = [root];
while (stack.length > 0) {
const node = stack.pop();
if (Array.isArray(node)) {
// 最后的节点必须首先渲染到目的地
for (let i = node.length - 1; i >= 0; i--) stack.push(node[i]);
continue;
}
const nodeType = typeof node;
if (nodeType === 'string') {
destination += escapeHTML(node as string);
}
}
destination += `</${root.name}>`; // 结束标签
return destination;
}
```
该策略的第一个实现分为两个阶段:创建一个有序的组件(节点)列表,然后循环列表并渲染组件。新的实现不再创建完整的列表,而是在循环列表的同时渲染(刷新)列表。这种最终方法比第一次迭代更快,并且与递归方法相比需要更少的内存。
## 高级路由
Astro 最初是一个基于文件的静态站点生成器。随着时间的推移,中间件、重定向、重写、Actions、会话和 i18n 等功能赋予了 Astro 应用更多的服务器端能力,但也使得请求生命周期更难控制。如果你需要在 Actions 之前运行身份验证,只想在页面渲染时包装日志记录,或者希望先由非 Astro API 处理某些请求,你必须绕过管道而不是直接组合它。在 Astro 7 中,你现在可以通过在项目中添加 `src/fetch.ts` 文件来完全控制 Astro 的请求管道。该文件导出了由 Cloudflare Workers (https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/)、Deno (https://docs.deno.com/runtime/fundamentals/http_server/) 和 Bun (https://bun.sh/docs/api/http#bun-serve) 推广的标准 `fetch` 处理程序模式。
```typescript
import { astro, FetchState } from 'astro/fetch';
export default {
fetch(request: Request) {
const state = new FetchState(request);
// 将 API 请求转发到后端服务
if (state.url.pathname.startsWith('/api')) {
const url = new URL(state.url.pathname + state.url.search, 'https://backend-api.example.com');
return fetch(new Request(url, request));
}
// 回退到 Astro 页面/端点
return astro(state);
}
}
```
该 API 也与 Hono (https://hono.dev/) 兼容,允许你将 Hono 中间件引入你的 Astro 应用程序:
```typescript
import { astro } from 'astro/hono';
import { Hono } from 'hono';
import { basicAuth } from 'hono/basic-auth';
const app = new Hono();
app.use(basicAuth({ username: 'admin', password: 'secret' }));
app.use(astro());
export default app;
```
对于高级用法,你可以将单个 Astro 功能作为单独的中间件组合,从而完全控制请求管道。如果你曾经使用过 Astro 中间件,并因为身份验证检查在 Astro Actions *之后*运行,或者无法在不自己包裹所有内容的情况下记录响应时间而感到沮丧,现在你可以将代码放在它需要的位置:
```typescript
import { Hono } from 'hono';
import { actions, middleware, pages, i18n } from 'astro/hono';
import { auth } from './middleware/auth';
import { timing } from './middleware/timing';
const app = new Hono();
app.use(i18n());
app.use(auth()); // 身份验证在Actions之前运行,没有未经验证的调用
app.use(actions());
app.use(middleware());
app.use(timing()); // 计时只包装页面渲染
app.use(pages());
export default app;
```
如果你不添加 `src/fetch.ts` 文件,Astro 的行为与现在完全相同。
## 路由缓存
按需渲染响应的缓存比应有的方式更难。每个主机都以不同的方式处理,并且从未有一种标准的方法从应用程序代码中控制它。Astro 7 引入了路由缓存 (https://docs.astro.build/en/guides/caching/) 来解决这个问题。该功能首次在 Astro 6 (https://astro.build/blog/astro-6/#experimental-route-caching) 中实验性发布,现在已稳定,并添加了一个统一的、与平台无关的缓存 API:在路由中设置指令,Astro 会处理其余部分,无论你部署到哪里。你配置一次缓存提供商,然后在页面中使用 `Astro.cache`(或在 API 路由和中间件中使用 `context.cache`)根据标准的 HTTP 缓存语义来控制每次响应的缓存。Astro 自带内置的 `memoryCache()` 提供商,让你快速上手:
```javascript
import { defineConfig, memoryCache } from 'astro/config';
export default defineConfig({
cache: {
provider: memoryCache(),
},
});
```
```astro
---
Astro.cache.set({ maxAge: 120, // 缓存 2 分钟
swr: 60, // 后备缓存 1 分钟,同时重新验证
tags: ['products'], // 用于定向失效的标签
});
---
```
你还可以在配置中使用 `routeRules` 声明性地为路由组定义缓存规则,从而将缓存逻辑完全排除在路由代码之外:
```javascript
export default defineConfig({
cache: {
provider: memoryCache()
},
routeRules: {
'/blog/[...path]': { maxAge: 300, swr: 60 },
},
});
```
路由缓存的真正亮点在于它与实时内容集合 (https://docs.astro.build/en/guides/content-collections/#live-content-collections) 的集成。一个实时加载器可以为返回的数据附加一个缓存提示,包含用于失效的标签和用于新鲜度的最后修改时间。将该条目直接传递给 `Astro.cache.set()`,Astro 会为你读取该提示,无需手动设置头部:
```astro
---
import { getLiveEntry } from 'astro:content';
const { entry } = await getLiveEntry('products', Astro.params.id);
// Astro 从条目中读取加载器的缓存提示:
Astro.cache.set(entry);
---
```
缓存的响应可以通过 `cache.invalidate()` 按需清除,可以通过标签或路径。例如,你可以为你的 CMS 暴露一个 webhook 端点,当内容发生变化时调用它。这映射到每个提供商的失效 API,无需重新构建即可清除所有受影响的响应:
```typescript
import type { APIRoute } from 'astro';
export const POST: APIRoute = async ({ request, cache }) => {
// 实际实现会验证
相似文章
AI2027模型已通过Astra组件升级
AI2027模型现已整合Astra组件,从而进一步提升性能与功能表现。
WordPress 7.0
WordPress 7.0 是一个重大版本,包含重新设计的导航覆盖层、通过集中式 Connectors 中心实现的人工智能集成、可视化修订、将模式作为单个块处理、性能提升、改进的可访问性以及焕然一新的管理体验。
@gdb:Astra 正在逐步推出,期待看到大家的创作与构建
GPT-6 Astra 正在向 Pro、Enterprise 和 Business Premium 用户推出,可通过 Work/Codex 及 API 使用,Plus 和 Business 用户将在后续安排。
GPT-6 Astra
OpenAI发布GPT-6 Astra,这是其最强大的AI模型,适用于高级推理、软件工程和智能体工作流,具备异步工具调用和中途引导功能,并制定了分阶段推出计划。
@gunta85: 我一直等着有人做出这个东西。文档工具,我全都试过:Astro Starlight → 快但丑…
Blume 是一个基于 Astro 构建的快速、开源文档工具,能从 Markdown 文件夹生成生产级文档站点,内置 AI 就绪、交互式 API 参考和零配置设置。