Astro 4.10 已发布,带来了实验性的类型安全环境变量,以及对容器 API 和重写(Rewrites)的增强。
完整版本亮点包括
要升级现有项目,请使用自动化的 @astrojs/upgrade
CLI 工具。或者,通过运行包管理器的升级命令来手动升级
# Recommended:npx @astrojs/upgrade
# Manual:npm install astro@latestpnpm upgrade astro --latestyarn upgrade astro --latest
实验性:astro:env
Astro 4.10 引入了一个新的实验性内置模块 `astro:env`,以便更方便地使用环境变量。
环境变量允许您在不同环境中为应用程序配置不同的值。但这带来了很大的复杂性
- 有些变量在客户端需要,有些则只在服务器端需要。
- 服务器变量通常是**机密信息**,例如 API 密钥,您不希望它们在客户端暴露,也不希望它们被内联到服务器构建中(任何有权访问构建输出的人都可以查看)。
- 有些变量对于您的应用程序正常运行是**必需的**;而另一些则是可选的增强功能。
- 变量可以在您的 shell 中、`.env` 文件中或在构建配置中定义。
- 诸如Cloudflare 和 Deno 等运行时读取变量的 API 不同,这造成了您需要处理的开发/生产环境差异。
我们构建了 `astro:env` 以提供对环境变量更多的控制和结构。通过模式(schema)直接在您的配置中管理这种复杂性
import { defineConfig, envField } from 'astro/config';
export default defineConfig({ experimental: { env: { schema: { API_PORT: envField.number({ context: 'server', access: 'secret', default: 7000 }), PUBLIC_DASHBOARD_V2: envField.boolean({ context: 'server', access: 'public', default: false }), } } }})
定义后,您可以通过从 `astro:env/server` 和 `astro:env/client` 模块导入来使用您的变量
import { PUBLIC_DASHBOARD_V2, getSecret } from 'astro:env/server';
if (PUBLIC_DASHBOARD_V2) { const API_PORT = getSecret("API_PORT") // number await fetch(`https://my-secret-api.com:${API_PORT}/v2`)}
客户端的 `astro:env/client` 可以在组件、脚本或任何您运行客户端代码的地方使用。例如,仅在启用功能标志时显示增强功能
import { SOME_FEATURE_FLAG } from 'astro:env/client';
export default function() { return ( <section> { SOME_FEATURE_FLAG && ( <div id="fancy-enhanced-feature"></div> )}
... </section> )}
当您需要读取模式中未定义的变量时,请使用 `getSecret()`,它适用于任何运行时(Cloudflare、Node.js、Deno)。
import { getSecret } from 'astro:env/server';
function getServerEndpoint(num: number) { return getSecret(`BACKUP_SERVER_${num}`); // string | undefined}
`astro:env` 是一个实验性功能,与所有实验性功能一样,可能会有所更改。感谢 Florian Lefebvre 成为 RFC 的倡导者并提供实现!请在 RFC 上留下您的反馈,以帮助指导这项新功能的开发,直至其稳定。
所有 HTTP 方法的重写
重写是 4.9 中发布的一项新的实验性功能。第一个版本针对 `GET` 请求,这是重写最常见的情况。现在在 4.10 中,可以通过克隆初始请求来使用重写来更改任何请求的路由。
这是一个在中间件中进行重写的示例,用于将您定向到版本化 API 的默认版本
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(({ request, url }, next) => { if(request.method === 'POST' && url.pathname === '/api') { return next('/api/v2'); }});
进行重写时,会创建一个指向新 URL 的新请求。现有请求头和请求体将被复制到新请求中。
嵌入 Astro
在 4.9 中,我们引入了容器 API,这是一种在 Astro 框架上下文之外渲染 Astro 组件的新方式。我们最初的重点是**测试**方面:使用容器 API 来测试 Astro 组件。创建一个容器,使用 `container.renderToString()` 渲染组件,并检查生成的 HTML。
我们一直知道人们会希望以其他方式使用容器 API,我们也不想让他们失望。在 4.10 中,您现在可以使用此 API 渲染任何使用 `astro build` 构建的组件,这意味着您可以在 Astro 站点之外使用它们!
为了演示其工作原理,我们构建了一个 Astro-in-PHP 演示应用程序。PHP 专家们,请勿评价代码!😅
容器部分看起来像这样
import * as components from './dist/server/all.mjs';import { renderers } from './dist/server/renderers.mjs';import { manifest } from './dist/server/entry.mjs';import { experimental_AstroContainer as AstroContainer } from 'astro/container';
const container = await AstroContainer.create({ manifest, renderers, resolve(s) { const found = manifest.entryModules[s]; if(found) { return `/astro-project/dist/client/${found}`; } return found; }});
const html = await container.renderToString(components.ReactWrapper);
// Log to the console so that PHP injects the HTML into its page.console.log(html);
容器 API 是一个低级 API,它反映了 Astro 内部渲染其自身路由的方式。我们渴望社区能够构建集成,以弥补其不足之处,并提供更简单的方式来嵌入 Astro。亲自尝试一下,并向我们展示您在何处添加了 Astro!
容器 API 辅助函数
我们还添加了一些方便的辅助函数,用于在 Vite 环境(`vitest`、Astro 集成等)中渲染您的 UI 框架组件时使用容器 API。
这意味着您不再需要知道(或弄清楚!)每个包的客户端和服务器渲染脚本的单独直接文件路径。新的 `getContainerRenderer()` 从我们的官方渲染器集成包(`@astrojs/react`、`@astrojs/preact`、`@astrojs/solid-js`、`@astrojs/svelte`、`@astrojs/vue`、`@astrojs/lit` 和 `@astrojs/mdx`)提供适当的渲染脚本。请务必同时升级您的集成以获得此新功能!
新的 `astro:container` 虚拟模块中的 `loadRenderers()` 函数将为您从每个包中加载这些渲染器
import { experimental_AstroContainer as AstroContainer } from 'astro/container';import ReactWrapper from '../src/components/ReactWrapper.astro';import { loadRenderers } from "astro:container";import { getContainerRenderer } from "@astrojs/react";
test('ReactWrapper with react renderer', async () => { const renderers = await loadRenderers([getContainerRenderer()]) const renderers = [ { name: '@astrojs/react', clientEntrypoint: '@astrojs/react/client.js', serverEntrypoint: '@astrojs/react/server.js', }, ]; const container = await AstroContainer.create({ renderers, }); const result = await container.renderToString(ReactWrapper);
expect(result).toContain('Counter'); expect(result).toContain('Count: <!-- -->5');});
对 `renderers` 的这种类型更改还将允许无 Vite 环境手动加载和传递渲染器模块。
有关更多信息,请参阅容器 API 文档。
错误修复
一如既往,Astro 4.10 包含了更多本文中未能提及的错误修复和小改进!查看完整的发布说明以了解更多信息,并观看 Astro Together 的 4.10 完整发布揭示!特别感谢 Sarah、Erika、Bjorn、Ema、Chris、Florian 以及所有为此次发布做出贡献的人员。