Astro 5.6

作者
Matt Kane
Emanuele Stoppa

Astro 5.6 为 Cloudflare 带来了原生的 astro:env 和实验性会话支持,并提供了对预加载的更多控制。

☁️ 借助 Astro 的这些新功能,翱翔于云端

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

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

Cloudflare 上的全局 astro:env

自 Astro 5 以来,您已经能够使用 astro:env 访问类型安全的环境变量。然而,Cloudflare 中的环境变量只能在请求内部访问,这限制了您何时何地可以使用它们。例如,如果您想使用共享的 API 客户端实例,则在请求外部实例化时无法使用环境变量。这可能会令人困惑,并且与我们的其他适配器有所不同。

Astro 5.6 解除了这一限制,这意味着您现在可以在整个服务器代码中全局访问环境变量,并使 Cloudflare 适配器与其他官方适配器保持一致。这得益于 Cloudflare Workers 的增强,这些增强现已在 Astro 中实现。

import { defineMiddleware } from 'astro:middleware';
import { API_URL } from 'astro:env/server';
import { createClient } from './client.js';
// Astro 5.5: undefined
// Astro 5.6: string
const client = createClient(API_URL);
export const onRequest = defineMiddleware((ctx, next) => {
ctx.locals.client = client;
return next();
});

这一改进在所有 Astro 服务器环境中创造了更一致的开发体验,意味着您无需担心区分请求作用域或全局作用域。

Cloudflare 上的实验性会话

Astro 会话 API 是一项实验性功能,允许您在请求之间轻松存储用户数据。它使用可插拔的后端进行存储,在使用 Node 或 Netlify 适配器时会自动配置。

借助 Astro 5.6,我们也为 Cloudflare 带来了简化的集成。当您将会话与 Cloudflare 适配器一起使用时,Astro 现在会自动配置 Cloudflare KV 存储。这意味着您的会话数据可以以最少的配置在 Cloudflare 的全球网络中可靠地存储和访问。

开始使用只需三步

  1. 使用 Wrangler CLI 创建 KV 命名空间

    npx wrangler kv namespace create "SESSION"
  2. 在 Wrangler 配置中声明 KV 命名空间

    wrangler.json
    {
    "kv_namespaces": [
    {
    "binding": "SESSION",
    "id": "<SESSION_ID>"
    }
    ]
    }
  3. 在 Astro 配置中启用实验性会话

    astro.config.mjs
    export default defineConfig({
    adapter: cloudflare(),
    experimental: {
    sessions: true,
    },
    });

然后您可以在服务器代码中使用会话

---
export const prerender = false;
const cart = await Astro.session.get('cart');
---
<a href="/checkout">🛒 {cart?.length ?? 0} items</a>

有关更多信息,请参阅实验性会话文档

新的预加载积极性选项

借助 Astro 新的预加载积极性控制,在速度和资源使用之间找到完美的平衡。启用实验性 clientPrerender 标志后,您可以使用 prefetch() 上的 eagerness 选项向浏览器建议它应以多大积极性预加载/预渲染链接目标。

这个新选项与浏览器的 猜测规则 API 对齐,让您能够精细控制浏览器应该以多大积极性预加载或预渲染您的链接

---
---
<script>
// Control prefetching eagerness
import { prefetch } from 'astro:prefetch';
// Let's be strategic about this resource-intensive page
prefetch('/data-heavy-dashboard', { eagerness: 'conservative' });
// This page is critical to the user journey, load it ASAP!
prefetch('/product-details'); // defaults to `{ eagerness: 'immediate' }`
// For most pages, a balanced approach works best
prefetch('/about', { eagerness: 'moderate' });
</script>

您可以选择三种积极性级别

  • 'immediate':如果资源允许,立即预加载
  • 'eager':链接很可能需要,因此尽早获取
  • 'moderate':让浏览器决定何时预加载
  • 'conservative':仅在极有可能需要时才预加载

此功能在处理大量链接时特别有价值,否则您可能会遇到为防止过度猜测而设置的浏览器限制

感谢社区成员 Marocco2 贡献此功能!

预渲染错误页面的自定义获取选项

当按需渲染的页面需要显示错误时,您的适配器可能需要从服务器以外的其他地方获取预渲染的错误页面。目前,这是通过使用默认的 fetch 实现发出请求来完成的,这可能不适用于所有用例。例如,页面可能从无法递归调用的位置提供,或者页面可能存储在其他地方。

Astro 5.6 在适配器 API 中添加了一个新的可选 prerenderedErrorPageFetch 选项,允许适配器为获取预渲染错误页面提供自定义实现。

以下示例为 500.html404.html 提供了一个自定义获取,从磁盘读取它们而不是执行 HTTP 调用:

return app.render(request, {
prerenderedErrorPageFetch: async (url: string): Promise<Response> => {
if (url.includes("/500")) {
const content = await fs.promises.readFile("500.html", "utf-8");
return new Response(content, {
status: 500,
headers: { "Content-Type": "text/html" },
});
}
const content = await fs.promises.readFile("404.html", "utf-8");
return new Response(content, {
status: 404,
headers: { "Content-Type": "text/html" },
});
});

如果没有提供值,Astro 将使用 fetch,并根据需要向 /500/404 发出请求。这与 Astro 的先前版本中的行为相同。

适配器 API 参考中阅读有关此功能的更多信息。

感谢 Yury Michurin 贡献此功能!

实验性会话的新 load() 方法

当使用实验性会话 API 时,您通常无需担心会话 ID 和 cookie 的管理:Astro 会自动读取用户的 cookie 并在需要时加载正确的会话。然而,有时您需要对加载哪个会话有更多控制。

新的 load() 方法允许您通过 ID 手动加载会话。如果您自己处理会话 ID,或者您想在不使用 cookie 的情况下跟踪会话,这会很有用。例如,您可能希望从另一个设备上的已登录用户恢复会话,或者使用不使用 cookie 的 API 端点。

src/pages/api/cart.ts
import type { APIRoute } from 'astro';
export const GET: APIRoute = async ({ session, request }) => {
// Load the session from a header instead of cookies
const sessionId = request.headers.get('x-session-id');
await session.load(sessionId);
const cart = await session.get('cart');
return Response.json({ cart });
};

如果该 ID 的会话不存在,将创建一个新会话。这允许您在需要时在客户端生成会话 ID。

有关更多信息,请参阅实验性会话文档

改进的配置验证

Astro 现在在每次集成运行后都会验证您的配置,从而更容易及早发现问题并查明任何问题的根源。这在使用多个集成时特别有用,因为它有助于确保它们彼此兼容并与您的 Astro 项目兼容。

实验性 SVG API 的破坏性变更

实验性 SVG RFC 一直在激烈讨论中,为此我们感谢所有人的参与!讨论的结果是,我们决定暂时删除某些功能。实验性 API 有时就是这样!

但是,这并不意味着它们永远消失了!在早期阶段移除它们,为我们提供了时间进行单独讨论,并根据您的反馈重新构建功能,在开发体验 (DX)、可访问性最佳实践和合理默认值之间取得正确的平衡。

这些项不再可用,必须从您的代码中删除

  • title 属性已被移除,直到我们能在开发者体验和可访问性之间取得正确的平衡。请将组件上所有 title 属性替换为 aria-label
    <Logo title="My Company Logo" />
    <Logo aria-label="My Company Logo" />
  • Sprite 模式已暂时移除,同时我们正在考虑一种新的实现,以解决此功能在实践中的使用方式。这意味着不再有多个 mode 选项,所有 SVG 都将是内联的。您项目中的所有 mode 实例都必须移除,因为您无法再控制模式。
    <Logo mode="inline" />
    <Logo /> // Always inline
    import { defineConfig } from 'astro'
    export default defineConfig({
    experimental: {
    svg: {
    mode: 'sprite'
    },
    svg: true
    }
    });
  • 由于开发者反馈,默认的 role 不再应用。请根据需要为每个组件单独添加适当的 role
    <Logo />
    <Logo role="img" /> // To keep the role that was previously applied by default
  • size 属性已被移除,以便更好地与 viewBox 和其他样式/属性结合使用。请用明确的 widthheight 属性替换 size
    <Logo size={64} />
    <Logo width={64} height={64} />

错误修复

一如既往,自 5.5 版本发布以来,我们一直在努力修复问题。有关所有详细信息,请参阅更新日志

社区

Astro 核心团队成员是

Ben Holmes , Caleb Jasik , Chris Swithinbank , Emanuele Stoppa , Erika , Florian Lefebvre , Fuzzy , HiDeoo , Luiz Ferraz , Matt Kane , Matthew Phillips , Nate Moore , Reuben Tier , Sarah Rainsberger , and Yan Thomas

感谢所有其他为 Astro 5.6 做出贡献的贡献者,包括 Edward BrunetiereMartin TrappVardhaman BhandariMarocco2Yury MichurinMichael Stramel

我们期待看到您使用 Astro 5.6 构建的作品!如果您有任何问题、意见,或者只是想打个招呼,请访问 Astro Discord