跳转到内容

Astro Renderer API

Astro 旨在支持任何 UI 框架。这项能力由渲染器提供,渲染器是集成。请参阅前端框架指南,了解如何在 Astro 中使用不同框架的 UI 组件。

渲染器是一种特殊的集成,用于告诉 Astro 如何检测和渲染它原生不处理的组件语法,例如 UI 框架组件。渲染器由两部分组成:

  • 一个在开发和生产构建期间导入、用于将组件渲染为 HTML 的服务端模块。
  • 一个可选的客户端模块,在浏览器中导入,用于使用客户端指令对组件进行水合。

当你需要在 Astro 中添加对新组件语法的支持时,创建一个集成,并在 astro:config:setup 钩子中调用 addRenderer()。这样你可以定义 Astro 用于渲染组件的服务端入口点。你也可以选择定义用于水合的客户端入口点。

以下示例展示了如何在 Astro 集成中注册渲染器:

my-renderer/index.js
export default function createIntegration() {
return {
name: "@example/my-renderer",
hooks: {
"astro:config:setup": ({ addRenderer }) => {
addRenderer({
name: "@example/my-renderer",
clientEntrypoint: "@example/my-renderer/client.js",
serverEntrypoint: "@example/my-renderer/server.js",
});
},
},
};
}

你需要创建一个在服务端渲染期间运行的文件,并定义如何渲染组件语法。服务端模块必须默认导出一个实现 SSRLoadedRendererValue 接口的对象。

以下示例展示了一个实现 check() 和 renderToStaticMarkup() 的最小服务端渲染器:

my-renderer/server.ts
import type { AstroComponentMetadata, NamedSSRLoadedRendererValue } from 'astro';
async function check(Component: unknown) {
return typeof Component === 'function' && Component.name === 'MyCustomComponent';
}
async function renderToStaticMarkup(
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
metadata?: AstroComponentMetadata,
) {
const rendered = Component(props);
return {
attrs: metadata?.hydrate ? { 'data-my-renderer': 'true' } : undefined,
html: `<${rendered.tag}>${rendered.text}${slots.default ?? ''}</${rendered.tag}>`,
};
}
const renderer: NamedSSRLoadedRendererValue = {
name: 'my-renderer',
check,
renderToStaticMarkup,
};
export default renderer;

当你的渲染器支持客户端指令时,创建一个客户端入口点,定义如何在浏览器中为组件进行水合。客户端模块必须默认导出一个接收岛屿元素并返回异步水合函数的函数。

每当一个岛屿从页面中移除时,Astro 都会在岛屿的根元素上分发自定义的 astro:unmount 事件。你可以在客户端入口点中监听此事件,以清理任何已挂载的应用状态。

以下示例展示了一个在浏览器中为组件进行水合的最小客户端入口点:

my-renderer/client.ts
export default (element: HTMLElement) =>
async (
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
{ client }: { client: string },
) => {
const rendered = Component({ ...props, slots });
if (client === 'only') {
element.innerHTML = '';
}
const node = document.createElement(rendered.tag);
node.textContent = rendered.text;
element.appendChild(node);
element.addEventListener('astro:unmount', () => node.remove(), { once: true });
};

以下类型可以从 astro 模块导入:

import type {
AstroComponentMetadata,
AstroRenderer,
NamedSSRLoadedRendererValue,
SSRLoadedRenderer,
SSRLoadedRendererValue,
} from "astro";

类型: { displayName: string; hydrate?: 'load' | 'idle' | 'visible' | 'media' | 'only'; hydrateArgs?: any; componentUrl?: string; componentExport?: { value: string; namespace?: boolean }; astroStaticSlot: true; }

包含正在渲染的组件的信息,包括其水合指令。

类型: string

定义组件名称,用于错误消息和调试。

类型: 'load' | 'idle' | 'visible' | 'media' | 'only'

定义组件上使用的客户端指令。如果没有提供值,组件不会在客户端进行水合。

渲染器可以使用此值有条件地包含客户端水合状态。例如,渲染器可以跳过为不会水合的组件序列化传输状态:

my-renderer/server.ts
import type { AstroComponentMetadata } from 'astro';
import { render } from './custom-render';
async function renderToStaticMarkup(
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
metadata?: AstroComponentMetadata,
) {
const willHydrate = !!metadata?.hydrate;
// Skip serializing hydration state if the component won't be hydrated
return render(Component, props, { includeTransferState: willHydrate });
}

类型: any

指定传递给水合指令的附加参数。

例如,它可以是 client:media 的媒体查询字符串(即 "(max-width: 768px)"),也可以是 client:only 的渲染器提示(即 "react")。

类型: string

定义组件源文件的 URL。

类型: { value: string; namespace?: boolean }

描述 Astro 将在客户端为已水合组件加载的组件导出。

AstroComponentMetadata.componentExport.namespace
Section titled “AstroComponentMetadata.componentExport.namespace”

类型: boolean

指示该导出是否为命名空间导出。

AstroComponentMetadata.componentExport.value
Section titled “AstroComponentMetadata.componentExport.value”

类型: string

定义导出名称(例如默认导出使用 "default")。

类型: true

指示 Astro 是否支持此组件的静态插槽优化。将 supportsAstroStaticSlot 设置为 true 的渲染器可以将其与 hydrate 结合使用,以确定如何渲染插槽。

类型: { name: string; clientEntrypoint?: string | URL; serverEntrypoint: string | URL; }

描述由集成添加的组件渲染器。

类型: string

定义渲染器唯一的公共名称。

类型: string | URL

定义组件使用时在客户端运行的渲染器的导入路径。

类型: string | URL

定义组件使用时,在服务端请求或静态构建期间运行的渲染器的导入路径。

在 SSRLoadedRendererValue 的基础上增加了必需的 name 属性。

类型: Pick<AstroRenderer, ‘name’ | ‘clientEntrypoint’> & { ssr: SSRLoadedRendererValue; }

描述可供服务端使用的渲染器。这是 AstroRenderer 的子集,并包含额外属性。

类型: SSRLoadedRendererValue

定义此框架的服务端使用的函数和配置。

类型: object

包含在服务端从特定 UI 框架渲染组件所需的函数和配置。

类型: string

指定渲染器的名称标识符。

类型: (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<boolean>

确定渲染器是否可以处理某个组件。此函数会针对每个已注册的渲染器调用,直到其中一个返回 true。

SSRLoadedRendererValue.renderToStaticMarkup()

Section titled “SSRLoadedRendererValue.renderToStaticMarkup()”

类型: (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<{ html: string; attrs?: Record<string, string>; }>

在服务端渲染框架组件,并返回生成的 HTML 字符串以及要传递给客户端入口点的可选属性。

SSRLoadedRendererValue.supportsAstroStaticSlot

Section titled “SSRLoadedRendererValue.supportsAstroStaticSlot”

类型: boolean

添加于: [email protected]

指示渲染器是否支持 Astro 的静态插槽优化。为 true 时,Astro 会阻止移除岛屿中的嵌套插槽。

SSRLoadedRendererValue.renderHydrationScript()

Section titled “SSRLoadedRendererValue.renderHydrationScript()”

类型: () => string

添加于: [email protected]

返回一个 HTML 字符串,在此渲染器处理的第一个已水合组件之前,每页注入一次。对于需要页面级水合设置的渲染器,这很有用。

贡献 社区 赞助