Astro Renderer API
Astro 旨在支持任何 UI 框架。这项能力由渲染器提供,渲染器是集成。请参阅前端框架指南,了解如何在 Astro 中使用不同框架的 UI 组件。
什么是渲染器?
Section titled “什么是渲染器?”渲染器是一种特殊的集成,用于告诉 Astro 如何检测和渲染它原生不处理的组件语法,例如 UI 框架组件。渲染器由两部分组成:
- 一个在开发和生产构建期间导入、用于将组件渲染为 HTML 的服务端模块。
- 一个可选的客户端模块,在浏览器中导入,用于使用客户端指令对组件进行水合。
当你需要在 Astro 中添加对新组件语法的支持时,创建一个集成,并在 astro:config:setup 钩子中调用 addRenderer()。这样你可以定义 Astro 用于渲染组件的服务端入口点。你也可以选择定义用于水合的客户端入口点。
以下示例展示了如何在 Astro 集成中注册渲染器:
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", }); }, }, };}构建服务端入口点
Section titled “构建服务端入口点”你需要创建一个在服务端渲染期间运行的文件,并定义如何渲染组件语法。服务端模块必须默认导出一个实现 SSRLoadedRendererValue 接口的对象。
以下示例展示了一个实现 check() 和 renderToStaticMarkup() 的最小服务端渲染器:
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;构建客户端入口点
Section titled “构建客户端入口点”当你的渲染器支持客户端指令时,创建一个客户端入口点,定义如何在浏览器中为组件进行水合。客户端模块必须默认导出一个接收岛屿元素并返回异步水合函数的函数。
每当一个岛屿从页面中移除时,Astro 都会在岛屿的根元素上分发自定义的 astro:unmount 事件。你可以在客户端入口点中监听此事件,以清理任何已挂载的应用状态。
以下示例展示了一个在浏览器中为组件进行水合的最小客户端入口点:
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 }); };渲染器类型参考
Section titled “渲染器类型参考”以下类型可以从 astro 模块导入:
import type { AstroComponentMetadata, AstroRenderer, NamedSSRLoadedRendererValue, SSRLoadedRenderer, SSRLoadedRendererValue,} from "astro";AstroComponentMetadata
Section titled “AstroComponentMetadata”类型: { displayName: string; hydrate?: 'load' | 'idle' | 'visible' | 'media' | 'only'; hydrateArgs?: any; componentUrl?: string; componentExport?: { value: string; namespace?: boolean }; astroStaticSlot: true; }
包含正在渲染的组件的信息,包括其水合指令。
AstroComponentMetadata.displayName
Section titled “AstroComponentMetadata.displayName”类型: string
定义组件名称,用于错误消息和调试。
AstroComponentMetadata.hydrate
Section titled “AstroComponentMetadata.hydrate”类型: 'load' | 'idle' | 'visible' | 'media' | 'only'
定义组件上使用的客户端指令。如果没有提供值,组件不会在客户端进行水合。
渲染器可以使用此值有条件地包含客户端水合状态。例如,渲染器可以跳过为不会水合的组件序列化传输状态:
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 });}AstroComponentMetadata.hydrateArgs
Section titled “AstroComponentMetadata.hydrateArgs”类型: any
指定传递给水合指令的附加参数。
例如,它可以是 client:media 的媒体查询字符串(即 "(max-width: 768px)"),也可以是 client:only 的渲染器提示(即 "react")。
AstroComponentMetadata.componentUrl
Section titled “AstroComponentMetadata.componentUrl”类型: string
定义组件源文件的 URL。
AstroComponentMetadata.componentExport
Section titled “AstroComponentMetadata.componentExport”类型: { value: string; namespace?: boolean }
描述 Astro 将在客户端为已水合组件加载的组件导出。
AstroComponentMetadata.componentExport.namespace
Section titled “AstroComponentMetadata.componentExport.namespace”类型: boolean
指示该导出是否为命名空间导出。
AstroComponentMetadata.componentExport.value
Section titled “AstroComponentMetadata.componentExport.value”类型: string
定义导出名称(例如默认导出使用 "default")。
AstroComponentMetadata.astroStaticSlot
Section titled “AstroComponentMetadata.astroStaticSlot”类型: true
指示 Astro 是否支持此组件的静态插槽优化。将 supportsAstroStaticSlot 设置为 true 的渲染器可以将其与 hydrate 结合使用,以确定如何渲染插槽。
AstroRenderer
Section titled “AstroRenderer”类型: { name: string; clientEntrypoint?: string | URL; serverEntrypoint: string | URL; }
描述由集成添加的组件渲染器。
AstroRenderer.name
Section titled “AstroRenderer.name”类型: string
定义渲染器唯一的公共名称。
AstroRenderer.clientEntrypoint
Section titled “AstroRenderer.clientEntrypoint”类型: string | URL
定义组件使用时在客户端运行的渲染器的导入路径。
AstroRenderer.serverEntrypoint
Section titled “AstroRenderer.serverEntrypoint”类型: string | URL
定义组件使用时,在服务端请求或静态构建期间运行的渲染器的导入路径。
NamedSSRLoadedRendererValue
Section titled “NamedSSRLoadedRendererValue”在 SSRLoadedRendererValue 的基础上增加了必需的 name 属性。
SSRLoadedRenderer
Section titled “SSRLoadedRenderer”类型: Pick<AstroRenderer, ‘name’ | ‘clientEntrypoint’> & { ssr: SSRLoadedRendererValue; }
描述可供服务端使用的渲染器。这是 AstroRenderer 的子集,并包含额外属性。
SSRLoadedRenderer.ssr
Section titled “SSRLoadedRenderer.ssr”定义此框架的服务端使用的函数和配置。
SSRLoadedRendererValue
Section titled “SSRLoadedRendererValue”类型: object
包含在服务端从特定 UI 框架渲染组件所需的函数和配置。
SSRLoadedRendererValue.name
Section titled “SSRLoadedRendererValue.name”类型: string
指定渲染器的名称标识符。
SSRLoadedRendererValue.check()
Section titled “SSRLoadedRendererValue.check()”类型: (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 字符串,在此渲染器处理的第一个已水合组件之前,每页注入一次。对于需要页面级水合设置的渲染器,这很有用。
Reference