Astro 适配器 API

Astro 可以轻松部署到任何云托管平台,以实现服务端渲染(SSR)。该能力由适配器集成提供,请参阅 SSR 指南 了解如何使用现有的适配器。

适配器是一种特殊类型的集成,它为服务器端渲染提供了入口。适配器包含两项主要功能:

  • 实现托管平台的 API,以处理请求。
  • 根据托管平台的约定配置构建过程。

由于适配器是一种集成,因此它拥有集成提供的全部能力。

必须 通过在 astro:config:done 钩子中调用 setAdapter API 来使用适配器,例如:

my-adapter.mjs
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js'
});
},
},
};
}

setAdapter 的传入参数定义如下:

interface AstroAdapter {
name: string;
serverEntrypoint?: string;
exports?: string[];
}

这些属性分别是:

  • name:适配器的唯一名称,用于日志记录。
  • serverEntrypoint:服务端渲染的入口。
  • exports:导出数组,与 createExports 配套使用(在下文中说明)。

Astro 的适配器 API 尝试适配多种类型的托管方,并提供了灵活的配置方式。

一些无服务架构的托管方会希望你导出一个handler函数:

...
export function handler(event, context) {
}

在适配器 API 中,你可以在 serverEntrypoint 中实现 createExports 方法:

import { App } from 'astro/app';
export function createExports(manifest) {
const app = new App(manifest);
const handler = (event, context) => {
// ...
};
return { handler };
}

在此之后,你需要在 setAdapterexports 属性中配置该 handler

my-adapter.mjs
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
exports: ['handler'],
});
},
},
};
}

有些托管方希望你自行管理服务的启动,例如通过监听一个端口的方式。对于这类托管方,可以导出一个 start 函数,该函数会在绑定脚本执行时被调用。

import { App } from 'astro/app';
export function start(manifest) {
const app = new App(manifest);
addEventListener('fetch', event => {
// ...
});
}

该模块用于渲染已通过 astro build 命令预构建的页面。Astro 使用标准的 RequestResponse 对象。如果托管方使用不同格式的请求/响应 API ,需要在适配器中进行转换处理。

import { App } from 'astro/app';
import http from 'http';
export function start(manifest) {
const app = new App(manifest);
addEventListener('fetch', event => {
event.respondWith(
app.render(event.request)
);
});
}

该模块提供以下几个方法:

app.render(request, routeData, locals)
标题部分 app.render(request, routeData, locals)

此方法用于匹配符合请求的 Astro 页面,并返回一个 Promise 对象给 Response 。该方法对于不渲染页面的 API 路由同样适用。

const response = await app.render(request);

方法拥有一个必传参数 request,和两个可选参数 routeData 以及 locals

如果你已经明确需要渲染的路由,可以通过传入 routeData 参数,跳过内部调用 app.match 进行匹配的步骤。

如需使用 locals 参数,必须将其作为第三个参数传入。如果不需要指定路由的话,可以将 routeData 参数设置为 undefined

下方示例尝试解析 x-private-header 请求头,并将其传入 locals 中。在此之后,它就可以作为参数被任意中间件使用了。

const privateHeader = request.headers.get("x-private-header");
let locals = {};
try {
if (privateHeader) {
locals = JSON.parse(privateHeader);
}
} finally {
const response = await app.render(request, undefined, locals);
}

该方法用于判断请求是否匹配 Astro 应用的路由规则。

if(app.match(request)) {
const response = await app.render(request);
}

通常可以在不使用 .match 的情况下调用 app.render(request)。因为当配置了 404.astro 文件后,Astro 就会自动处理 404 的情况。如果想要自定义处理规则,请使用 app.match(request)

使用 astro add 安装适配器

标题部分 使用 astro add 安装适配器

用户可以使用 astro add 命令 轻松地在他们的项目中添加集成和适配器。如果希望其他用户可以使用该命令安装 你的 适配器,请在 package.json 文件的 keywords 项中添加 astro-adapter 属性

{
"name": "example",
"keywords": ["astro-adapter"],
}

将适配器发布到 npm 后,执行 astro add example 命令,即可安装适配器以及在 package.json 文件中指定的对等依赖。我们将指导用户手动更新他们的项目配置。