Skip to content

Astro 容器 API(实验性)

Added in: astro@4.9.0

Container API 允许你单独渲染 Astro 组件。

¥The Container API allows you to render Astro components in isolation.

这个实验性的服务器端 API 解锁了各种潜在的未来用途,但目前的范围是允许在 vite 环境(例如 vitest)中使用 测试 .astro 组件输出

¥This experimental server-side API unlocks a variety of potential future uses, but is currently scoped to allow testing of .astro component output in vite environments such as vitest.

它还允许你使用 手动加载渲染脚本 在按需渲染的页面或 vite 之外的其他 “shell” 环境中创建容器(例如在 PHP 或 Elixir 应用内)。

¥It also allows you to manually load rendering scripts for creating containers in pages rendered on demand or other “shell” environments outside of vite (e.g. inside a PHP or Elixir application).

此 API 允许你 创建新容器,并渲染返回 字符串Response 的 Astro 组件。

¥This API allows you to create a new container, and render an Astro component returning a string or a Response.

此 API 是实验性的,即使在 次要版本或补丁版本 中也可能发生重大更改。请咨询 Astro 变更日志 以了解发生的变化。此页面将始终使用最新版本 Astro 的最新信息进行更新。

¥This API is experimental and subject to breaking changes, even in minor or patch releases. Please consult the Astro CHANGELOG for changes as they occur. This page will always be updated with the most current information for the latest version of Astro.

创建容器的新实例。

¥Creates a new instance of the container.

import { experimental_AstroContainer } from "astro/container";
const container = await experimental_AstroContainer.create();

它接受具有以下选项的对象:

¥It accepts an object with the following options:

export type AstroContainerOptions = {
streaming?: boolean;
renderers?: AddServerRenderer[];
};
export type AddServerRenderer =
| {
renderer: NamedSSRLoadedRendererValue;
name: never;
}
| {
renderer: SSRLoadedRendererValue;
name: string;
};

¥streaming option

类型:boolean

¥Type: boolean

启用使用 HTML 流式传输 渲染组件。

¥Enables rendering components using HTML streaming.

¥renderers option

类型:AddServerRenderer[]

¥Type: AddServerRenderer[]

组件所需的已加载客户端渲染器列表。如果你的 .astro 组件使用官方 Astro 集成(例如 React、Vue 等)渲染任何 UI 框架组件 或 MDX,请使用此选项。

¥A list of loaded client renderers required by the component. Use this if your .astro component renders any UI framework components or MDX using an official Astro integration (e.g. React, Vue, etc.).

对于静态应用,或者在运行时不调用容器的情况(例如使用 vitest 进行测试),可以通过容器 API 自动添加渲染器。

¥Renderers can be added through the Container API automatically for static applications, or cases where the container isn’t called at runtime (e.g. testing with vitest).

对于 按需渲染应用,或者在运行时或在其他 “shells”(例如 PHP、Ruby、Java 等)内调用容器的情况,必须手动导入渲染器。

¥For on-demand rendered applications, or cases where the container is called at runtime or inside other “shells” (e.g. PHP, Ruby, Java, etc.), renderers must be manually imported.

通过容器 API 添加渲染器

标题部分 通过容器 API 添加渲染器

¥Adding a renderer through the Container API

对于每个官方 Astro 集成,请导入并使用 getContainerRenderer() 辅助函数来公开其客户端和服务器渲染脚本。这些可用于 @astrojs/react@astrojs/preact@astrojs/solid-js@astrojs/svelte@astrojs/vue@astrojs/mdx

¥For each official Astro integration, import and use the getContainerRenderer() helper function to expose its client and server rendering scripts. These are available for @astrojs/react, @astrojs/preact, @astrojs/solid-js, @astrojs/svelte, @astrojs/vue, and @astrojs/mdx.

对于 @astrojs npm org 之外的渲染器包,请在其文档中查找 getContainerRenderer() 或提供的类似功能。

¥For renderer packages outside the @astrojs npm org, look in their documentation for getContainerRenderer() or a similar function provided.

使用 vitevitest、Astro 集成等)时,渲染器会使用虚拟模块 astro:container 中的函数 loadRenderers() 加载。

¥When using vite (vitest, Astro integrations, etc.), the renderers are loaded with the function loadRenderers() from the virtual module astro:container.

以下示例提供了渲染 Astro 组件所需的对象,该组件渲染 React 组件和 Svelte 组件:

¥The following example provides the necessary object to render an Astro component that renders a React component and a Svelte component:

import { getContainerRenderer as reactContainerRenderer } from "@astrojs/react";
import { getContainerRenderer as svelteContainerRenderer } from "@astrojs/svelte";
import { loadRenderers } from "astro:container";
const renderers = await loadRenderers([reactContainerRenderer(), svelteContainerRenderer()]);
const container = await experimental_AstroContainer.create({
renderers
})
const result = await container.renderToString(ReactWrapper);

¥Adding a renderer manually

当在运行时调用容器时,或者在其他 “shells” 内部,astro:container 虚拟模块的辅助函数不可用。你必须手动导入必要的服务器和客户端渲染器,并使用 addServerRendereraddClientRenderer 将它们存储在容器内。

¥When the container is called at runtime, or inside other “shells”, the astro:container virtual module’s helper functions are not available. You must import the necessary server and client renderers manually and store them inside the container using addServerRenderer and addClientRenderer.

服务器渲染器是构建项目所必需的,并且必须存储在每个使用的框架的容器中。使用 client:* 指令 的任何水合客户端组件还需要客户端渲染器。

¥Server renderers are required to build your project, and must be stored in the container for every framework used. Client renderers are additionally needed to any hydrate client-side components using client:* directives.

每个框架只需要一个导入语句。导入渲染器使服务器和客户端渲染器都可用于你的容器。但是,必须在客户端渲染器之前将服务器渲染器添加到你的容器中。这允许你的整个容器首先渲染,然后补充任何交互式组件。

¥Only one import statement is needed per framework. Importing a renderer makes both the server and client renderers available to your container. However, server renderers must be added to your container before client renderers. This allows your entire container to render first, and then hydrate any interactive components.

以下示例手动导入必要的服务器渲染器,以便能够显示静态 Vue 组件和 .mdx 页面。它还为交互式 React 组件添加了服务器和客户端渲染器。

¥The following example manually imports the necessary server renderers to be able to display static Vue components and .mdx pages. It additionally adds both server and client renderers for interactive React components.

import reactRenderer from "@astrojs/react/server.js";
import vueRenderer from "@astrojs/vue/server.js";
import mdxRenderer from "@astrojs/mdx/server.js";
const container = await experimental_AstroContainer.create();
container.addServerRenderer({renderer: vueRenderer});
container.addServerRenderer({renderer: mdxRenderer});
container.addServerRenderer({ renderer: reactRenderer });
container.addClientRenderer({ name: "@astrojs/react", entrypoint: "@astrojs/react/client.js" });

此函数在容器内渲染指定的组件。它将 Astro 组件作为参数,并返回一个字符串,该字符串表示 Astro 组件渲染的 HTML/内容。

¥This function renders a specified component inside a container. It takes an Astro component as an argument and it returns a string that represents the HTML/content rendered by the Astro component.

import { experimental_AstroContainer } from "astro/container";
import Card from "../src/components/Card.astro";
const container = await experimental_AstroContainer.create();
const result = await container.renderToString(Card);

在底层,此函数调用 renderToResponse 并调用 Response.text()

¥Under the hood, this function calls renderToResponse and calls Response.text().

它还接受一个对象作为第二个参数,该参数可以包含 选项数量

¥It also accepts an object as a second argument that can contain a number of options.

它渲染一个组件,并返回一个 Response 对象。

¥It renders a component, and it returns a Response object.

import { experimental_AstroContainer } from "astro/container";
import Card from "../src/components/Card.astro";
const container = await experimental_AstroContainer.create();
const result = await container.renderToResponse(Card);

它还接受一个对象作为第二个参数,该参数可以包含 选项数量

¥It also accepts an object as a second argument that can contain a number of options.

¥Rendering options

renderToResponserenderToString 都接受一个对象作为它们的第二个参数:

¥Both renderToResponse and renderToString accept an object as their second argument:

export type ContainerRenderOptions = {
slots?: Record<string, any>;
props?: Record<string, unknown>;
request?: Request;
params?: Record<string, string | undefined>;
locals?: App.Locals;
routeType?: "page" | "endpoint";
};

这些可选值可以传递给渲染函数,以提供 Astro 组件正确渲染所需的其他信息。

¥These optional values can be passed to the rendering function in order to provide additional information necessary for an Astro component to properly render.

类型:Record<string, any>

¥Type: Record<string, any>;

传递要使用 <slots> 渲染的内容的选项。

¥An option to pass content to be rendered with <slots>.

如果你的 Astro 组件渲染一个默认插槽,请传递一个以 default 为键的对象:

¥If your Astro component renders one default slot, pass an object with default as the key:

import Card from "../src/components/Card.astro";
const result = await container.renderToString(Card, {
slots: { default: "Some value" }
});

如果你的组件渲染命名插槽,请使用插槽名称作为对象键:

¥If your component renders named slots, use the slot names as the object keys:

---
---
<div>
<slot name="header" />
<slot name="footer" />
</div>
import Card from "../src/components/Card.astro";
const result = await container.renderToString(Card, {
slots: {
header: "Header content",
footer: "Footer"
}
});

你还可以级联渲染组件:

¥You can also render components in cascade:

---
---
<div>
<slot name="header" />
<slot name="footer" />
</div>
import Card from "../src/components/Card.astro";
import CardHeader from "../src/components/CardHeader.astro";
import CardFooter from "../src/components/CardFooter.astro";
const result = await container.renderToString(Card, {
slots: {
header: await container.renderToString(CardHeader),
footer: await container.renderToString(CardFooter)
}
});

¥props option

类型:Record<string, unknown>

¥Type: Record<string, unknown>

为 Astro 组件传递 properties 的选项。

¥An option to pass properties for Astro components.

import Card from "../src/components/Card.astro";
const result = await container.renderToString(Card, {
props: { name: "Hello, world!" }
});
---
// For TypeScript support
interface Props {
name: string;
};
const { name } = Astro.props;
---
<div>
{name}
</div>

¥request option

类型:Request

¥Type: Request

传递 Request 的选项,其中包含有关组件将渲染的路径/URL 的信息。

¥An option to pass a Request with information about the path/URL the component will render.

当你的组件需要读取 Astro.urlAstro.request 等信息时,请使用此选项。

¥Use this option when your component needs to read information like Astro.url or Astro.request.

你还可以注入可能的标题或 cookie。

¥You can also inject possible headers or cookies.

import Card from "../src/components/Card.astro";
const result = await container.renderToString(Card, {
request: new Request("https://example.com/blog", {
headers: {
"x-some-secret-header": "test-value"
}
})
});

¥params option

类型:Record<string, string | undefined>

¥Type: Record<string, string | undefined>;

将有关路径参数的信息传递给负责 生成动态路由 的 Astro 组件的对象。

¥An object to pass information about the path parameter to an Astro component responsible for generating dynamic routes.

当你的组件需要 Astro.params 的值才能动态生成单个路由时,请使用此选项。

¥Use this option when your component needs a value for Astro.params in order to generate a single route dynamically.

---
const { locale, slug } = Astro.params;
---
<div></div>
import LocaleSlug from "../src/components/[locale]/[slug].astro";
const result = await container.renderToString(LocaleSlug, {
params: {
locale: "en",
slug: "getting-started"
}
});

¥locals options

类型:App.Locals

¥Type: App.Locals

传递来自 Astro.locals 的信息以渲染组件的选项。

¥An option to pass information from Astro.locals for rendering your component.

当你的组件需要在请求的生命周期内存储信息才能渲染时,请使用此选项,例如登录状态。

¥Use this option to when your component needs information stored during the lifecycle of a request in order to render, such as logged in status.

---
const { checkAuth } = Astro.locals;
const isAuthenticated = checkAuth();
---
{isAuthenticated ? <span>You're in</span> : <span>You're out</span> }
import Card from "../src/components/Card.astro";
test("User is in", async () => {
const result = await container.renderToString(Card, {
locals: {
checkAuth() { return true; }
}
});
// assert result contains "You're in"
});
test("User is out", async () => {
const result = await container.renderToString(Card, {
locals: {
checkAuth() { return false; }
}
});
// assert result contains "You're out"
});

¥routeType option

类型:"page" | "endpoint"

¥Type: "page" | "endpoint"

使用 renderToResponse 时可用的选项,用于指定你正在渲染 endpoint

¥An option available when using renderToResponse to specify that you are rendering an endpoint:

container.renderToString(Endpoint, { routeType: "endpoint" });
import * as Endpoint from "../src/pages/api/endpoint.js";
const response = await container.renderToResponse(Endpoint, {
routeType: "endpoint"
});
const json = await response.json();

要在 POSTPATCH 等方法上测试端点,请使用 request 选项调用正确的函数:

¥To test your endpoint on methods such as POST, PATCH, etc., use the request option to call the correct function:

export function GET() {}
// need to test this
export function POST() {}
import * as Endpoint from "../src/pages/api/endpoint.js";
const response = await container.renderToResponse(Endpoint, {
routeType: "endpoint",
request: new Request("https://example.com", {
method: "POST" // Specify POST method for testing
})
});
const json = await response.json();

¥partial option

类型:boolean
默认:true

¥Type: boolean
Default: true

Added in: astro@4.16.6

容器 API 是否将组件渲染为 页面部分。这通常是你在渲染 components.boolean 时想要的行为,因此你可以在没有完整页面外壳的情况下渲染组件。

¥Whether or not the Container API renders components as if they were page partials. This is usually the behavior you want when rendering components.boolean so you can render components without a full page shell.

要将组件渲染为完整的 Astro 页面(包括 <!DOCTYPE html>),你可以通过将 partial 设置为 false 来选择退出此行为:

¥To render a component as a full Astro page, including <!DOCTYPE html>, you can opt-out of this behavior by setting partial to false:

import Blog from "../src/pages/Blog.astro";
const result = await container.renderToString(Card, {
partial: false
});
console.log(result) // includes `<!DOCTYPE html>` at the beginning of the HTML
Astro 中文网 - 粤ICP备13048890号