diff --git a/src/content/docs/zh-cn/guides/upgrade-to/v4.mdx b/src/content/docs/zh-cn/guides/upgrade-to/v4.mdx index ac6be1739ea8b..5065afed8e6b1 100644 --- a/src/content/docs/zh-cn/guides/upgrade-to/v4.mdx +++ b/src/content/docs/zh-cn/guides/upgrade-to/v4.mdx @@ -273,7 +273,7 @@ Astro v4.0 移除了对简单对象的支持并要求端点必须返回一个 `R ### 移除:`build.split` 和 `build.excludeMiddleware` -在 Astro v3.0 中,`build.split` 和 `build.excludeMiddleware` 构建配置项被弃用,它们被实现相同功能的[适配器配置选项](/zh-cn/reference/adapter-reference/#adapter-features)替代。 +在 Astro v3.0 中,`build.split` 和 `build.excludeMiddleware` 构建配置项被弃用,它们被实现相同功能的[适配器配置选项](/zh-cn/reference/adapter-reference/#适配器特性)替代。 Astro v4.0 完全移除了这些属性。 diff --git a/src/content/docs/zh-cn/guides/upgrade-to/v5.mdx b/src/content/docs/zh-cn/guides/upgrade-to/v5.mdx index 587fb306f4491..49ebf9812949f 100644 --- a/src/content/docs/zh-cn/guides/upgrade-to/v5.mdx +++ b/src/content/docs/zh-cn/guides/upgrade-to/v5.mdx @@ -1106,7 +1106,7 @@ function useRoute(route: IntegrationRouteData) { } ``` -请参阅 [`IntegrationRouteData` 的 API 参考](/zh-cn/reference/integrations-reference/#integrationroutedata-类型参考)。 +请参阅 [`IntegrationRouteData` 的 API 参考](/zh-cn/reference/integrations-reference/#integrationroutedata)。 ### 改动:`distURL` 现在是一个数组(集成 API) @@ -1133,7 +1133,7 @@ if (route.distURL) { } ``` -请参阅 [`IntegrationRouteData` 的 API 参考](/zh-cn/reference/integrations-reference/#integrationroutedata-类型参考) +请参阅 [`IntegrationRouteData` 的 API 参考](/zh-cn/reference/integrations-reference/#integrationroutedata) ### 改动:传递给 `app.render()` 的参数(适配器 API) @@ -1186,7 +1186,7 @@ supportedAstroFeatures: { } ``` -了解有关在 [适配器中指定支持的 Astro 功能](/zh-cn/reference/adapter-reference/#astro-features)的更多信息。 +了解有关在 [适配器中指定支持的 Astro 功能](/zh-cn/reference/adapter-reference/#astro-特性)的更多信息。 ### 移除:开发工具栏应用程序已弃用的定义结构(开发工具栏 API) diff --git a/src/content/docs/zh-cn/reference/adapter-reference.mdx b/src/content/docs/zh-cn/reference/adapter-reference.mdx index f0c028a13370a..6797088e67636 100644 --- a/src/content/docs/zh-cn/reference/adapter-reference.mdx +++ b/src/content/docs/zh-cn/reference/adapter-reference.mdx @@ -4,6 +4,7 @@ sidebar: label: 适配器 API --- +import ReadMore from '~/components/ReadMore.astro'; import Since from '~/components/Since.astro'; import { FileTree } from '@astrojs/starlight/components'; @@ -11,18 +12,18 @@ Astro 可以轻松部署到任何云托管平台,以实现按需渲染,也 ## 什么是适配器? -适配器是一种特殊类型的[集成](/zh-cn/reference/integrations-reference/),它为请求时的服务器渲染提供了入口。适配器包含两项主要功能: +适配器是一种特殊类型的[集成](/zh-cn/reference/integrations-reference/),它为请求时的服务器渲染提供了入口。适配器可以访问完整的集成 API,并执行两项操作: - 实现托管平台的 API,以处理请求。 - 根据托管平台的约定配置构建过程。 ## 构建适配器 -由于适配器是一种[集成](/zh-cn/reference/integrations-reference/),因此它拥有集成提供的全部能力。 +创建一个集成并在 [`astro:config:done`](/zh-cn/reference/integrations-reference/#astroconfigdone) 钩子中调用 `setAdapter()` 函数。这允许你定义服务器入口点以及适配器支持的功能。 -__必须__ 通过在 `astro:config:done` 钩子中调用 `setAdapter` API 来使用适配器,例如: +以下示例创建了一个具有服务器入口点并对 Astro 静态输出提供稳定支持的适配器: -```js title="my-adapter.mjs" +```js title="my-adapter.mjs" {5-13} "setAdapter" export default function createIntegration() { return { name: '@example/my-adapter', @@ -32,7 +33,7 @@ export default function createIntegration() { name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { - staticOutput: 'stable' + staticOutput: 'stable' } }); }, @@ -41,94 +42,227 @@ export default function createIntegration() { } ``` -`setAdapter` 的传入参数定义如下: +`setAdapter()` 函数接受一个包含以下属性的对象: -```ts -interface AstroAdapter { - name: string; - serverEntrypoint?: string; - previewEntrypoint?: string; - exports?: string[]; - args?: any; - adapterFeatures: AstroAdapterFeaturesMap; - supportedAstroFeatures?: AstroFeatureMap; +### `name` + +

+ +**类型:** `string` +

+ +为你的适配器定义一个唯一的名称。这将用于日志记录。 + +### `serverEntrypoint` + +

+ +**类型:** `string | URL` +

+ +定义按需渲染的入口点。 + +了解更多关于 [构建服务器入口点](#building-a-server-entrypoint) 的信息。 + +### `supportedAstroFeatures` + +

+ +**类型:** `AstroAdapterFeatureMap`
+ +

+ +适配器所支持的 Astro 内置功能映射表。这使得 Astro 能够确定适配器支持哪些功能,从而提供相应的错误消息。 + +了解更多关于 [可用的 Astro 特性](#astro-特性) 的信息。 + +### `adapterFeatures` + +

+ +**类型:** `AstroAdapterFeatures`
+ +

+ +一个对象,用于指定适配器支持哪些 [会改变构建输出的适配器特性](#适配器特性)。 + +### `args` + +

+ +**类型:** `any` +

+ +一个 JSON 可序列化的值,将在运行时传递给适配器的服务器入口点。这对于将包含构建时配置(例如路径、密钥)的对象传递给服务器运行时代码非常有用。 + +以下示例定义了一个 `args` 对象,其中包含一个属性,用于标识 Astro 生成的资源所在的位置: + + +```js title="my-adapter.mjs" {9-11} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ config, setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + args: { + assets: config.build.assets + } + }); + }, + }, + }; } +``` + +### `client` -export interface AstroAdapterFeatures { - /** - * 创建一个与 Astro 中间件通信的边缘函数 - */ - edgeMiddleware: boolean; - /** - * 确定适配器的构建输出类型。默认为 `server`。 - */ - buildOutput?: 'static' | 'server'; +

+ +**类型:** `{ internalFetchHeaders?: Record | () => Record; assetQueryParams?: URLSearchParams; }`
+ +

+ +Astro 客户端代码的配置对象。 + +#### `internalFetchHeaders` + +

+ +**类型:** `Record | () => Record` +

+ +定义要注入到 Astro 内部 fetch 调用中的请求头(例如 Actions、View Transitions、Server Islands、Prefetch)。这可以是一个 headers 对象或一个返回 headers 的函数。 + +以下示例从环境变量中检索 `DEPLOY_ID`,如果提供了该变量,则返回一个对象,其中 header 名称作为键,部署 ID 作为值: + +```js title="my-adapter.mjs" {9-14} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ config, setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + client: { + internalFetchHeaders: () => { + const deployId = process.env.DEPLOY_ID; + return deployId ? { 'Your-Header-ID': deployId } : {}; + }, + }, + }); + }, + }, + }; } +``` -export type AdapterSupportsKind = 'unsupported' | 'stable' | 'experimental' | 'deprecated' | 'limited'; +#### `assetQueryParams` -export type AdapterSupportWithMessage = { - support: Exclude; - message: string; - suppress?: 'default' | 'all'; -}; +

-export type AdapterSupport = AdapterSupportsKind | AdapterSupportWithMessage; - -export type AstroAdapterFeatureMap = { - /** - * 适配器对静态页面的支持 - */ - staticOutput?: AdapterSupport; - /** - * 适配器对静态页面或通过服务器渲染的页面的支持 - */ - hybridOutput?: AdapterSupport; - /** - * 适配器对按需渲染的支持 - */ - serverOutput?: AdapterSupport; - /** - * 适配器对 i18n 域名的支持 - */ - i18nDomains?: AdapterSupport; - /** - * 适配器对 `astro:env/server` 导出的 `getSecret` 的支持 - */ - envGetSecret?: AdapterSupport; - /** - * 适配器对 Sharp 图像服务的支持 - */ - sharpImageService?: AdapterSupport; -}; +**类型:** `URLSearchParams` +

+ +定义要追加到所有资源 URL (例如图片、样式表、脚本)的查询参数。这对于需要跟踪部署版本或其他元数据的适配器非常有用。 +以下示例从环境变量中检索 `DEPLOY_ID`,如果提供了该变量,则返回一个对象,其中自定义搜索参数名称作为键,部署 ID 作为值: + +```js title="my-adapter.mjs" {9-13} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ config, setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + client: { + assetQueryParams: process.env.DEPLOY_ID + ? new URLSearchParams({ yourParam: process.env.DEPLOY_ID }) + : undefined, + }, + }); + }, + }, + }; +} ``` -这些属性分别是: +### `exports` + +

+ +**类型:** `string[]` +

+ +定义一个命名导出数组,与服务器入口点的 [`createExports()` 函数](#createexports) 配合使用。 + +以下示例假设 `createExports()` 提供了一个名为 `handler` 的导出: -* __name__:适配器的唯一名称,用于日志记录。 -* __serverEntrypoint__:按需服务器渲染的入口。 -* __exports__:导出数组,与 `createExports` 配套使用(在下文中说明)。 -* __adapterFeatures__:一个对象,用于启用适配器必须支持的特定功能。这些功能将改变构建输出,适配器必须实现适当的逻辑来处理不同的输出。 -* __supportedAstroFeatures__:Astro 内置功能的映射。这允许 Astro 确定适配器无法或不愿意支持的功能,以便提供适当的错误消息。 +```js title="my-adapter.mjs" {9} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ config, setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + exports: ['handler'] + }); + }, + }, + }; +} +``` -### 服务端入口 +### `previewEntrypoint` -Astro 的适配器 API 尝试适配多种类型的托管方,并提供了灵活的配置方式。 +

-#### Exports +**类型:** `string | URL`
+ +

-一些无服务架构的托管方会希望你导出一个 `handler` 函数: +定义适配器包中负责在运行 `astro preview` 时启动已构建服务器的模块的路径或 ID。 -```js -export function handler(event, context) { - // ... +```js title="my-adapter.mjs" {9} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ config, setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + previewEntrypoint: '@example/my-adapter/preview.js', + }); + }, + }, + }; } ``` -在适配器 API 中,你可以在 `serverEntrypoint` 中实现 `createExports` 方法: +## 构建服务器入口点 -```js +你需要创建一个在服务端请求期间执行的文件,以便为特定的托管平台启用按需渲染。Astro 的适配器 API 旨在与任何类型的托管平台协同工作,并提供了一种灵活的方式来符合托管平台的 API。 + +### `createExports()` + +

+ +**类型:** (manifest: SSRManifest, options: any) => Record\ +

+ +一个导出的函数,接受 SSR 清单作为第一个参数,包含适配器 [`args`](#args) 的对象作为第二个参数。这应该提供你的托管平台所需的导出。 + +例如,某些无服务器托管平台希望你导出一个 `handler()` 函数。使用适配器 API,你可以通过在服务器入口点中实现 `createExports()` 来实现这一点: + +```js title="my-adapter/server.js" import { App } from 'astro/app'; export function createExports(manifest) { @@ -142,7 +276,7 @@ export function createExports(manifest) { } ``` -在此之后,你需要在 `setAdapter` 的 `exports` 属性中配置该 `handler`: +然后在你的集成中,调用 `setAdapter()` 的地方,在 [`exports`](#exports) 中提供此名称: ```js title="my-adapter.mjs" ins={9} export default function createIntegration() { @@ -161,11 +295,35 @@ export default function createIntegration() { } ``` -#### Start +你可以通过 `createExports()` 的第二个参数访问适配器定义的 [`args`](#args)。当你在服务器入口点中需要访问构建时配置时,这非常有用。例如,你的服务器可能需要识别 Astro 生成的资源所在的位置: -有些托管方希望你自行管理服务的**启动**,例如通过监听一个端口的方式。对于这类托管方,可以导出一个 `start` 函数,该函数会在绑定脚本执行时被调用。 -```js +```js title="my-adapter/server.js" {4} "args" +import { App } from 'astro/app'; + +export function createExports(manifest, args) { + const assetsPath = args.assets; + + const handler = (event, context) => { + // ... + }; + + return { handler }; +} +``` + +### `start()` + +

+ +**类型:** (manifest: SSRManifest, options: any) => Record\ +

+ +一个导出的函数,接受 SSR 清单作为第一个参数,包含适配器 [`args`](#args) 的对象作为第二个参数。 + +某些托管平台希望你*自己启动*服务器,例如通过监听端口。对于这些类型的托管平台,适配器 API 允许你导出一个 `start()` 函数,该函数将在运行打包脚本时被调用。 + +```js title="my-adapter/server.js" import { App } from 'astro/app'; export function start(manifest) { @@ -177,9 +335,11 @@ export function start(manifest) { } ``` -#### `astro/app` +### `astro/app` + +该模块用于渲染已通过 `astro build` 命令预构建的页面。Astro 使用标准的 [`Request`](https://developer.mozilla.org/zh-CN/docs/Web/API/Request) 和 [`Response`](https://developer.mozilla.org/zh-CN/docs/Web/API/Response) 对象。如果托管方使用不同格式的请求/响应 API,需要在适配器中进行转换处理。 -该模块用于渲染已通过 `astro build` 命令预构建的页面。Astro 使用标准的 [Request](https://developer.mozilla.org/zh-CN/docs/Web/API/Request) 和 [Response](https://developer.mozilla.org/zh-CN/docs/Web/API/Response) 对象。如果托管方使用不同格式的请求/响应 API,需要在适配器中进行转换处理。 +`App` 构造函数接受必需的 SSR 清单参数,并可选择接受一个用于启用或禁用流式传输的参数,默认为 `true`。 ```js import { App } from 'astro/app'; @@ -198,14 +358,14 @@ export function start(manifest) { 该模块提供以下几个方法: -##### `app.render()` +#### `app.render()`

**类型:** `(request: Request, options?: RenderOptions) => Promise`

-此方法用于匹配符合请求的 Astro 页面,并返回一个 Promise 对象给 [Response](https://developer.mozilla.org/zh-CN/docs/Web/API/Response) 。该方法对于不渲染页面的 API 路由同样适用。 +一个方法,接受必需的 `request` 参数和可选的 `RenderOptions` 对象。此方法用于匹配符合请求的 Astro 页面,并返回一个 Promise 对象给 [Response](https://developer.mozilla.org/zh-CN/docs/Web/API/Response) 。该方法对于不渲染页面的 API 路由同样适用。 ```js const response = await app.render(request); @@ -218,7 +378,7 @@ const response = await app.render(request); **类型:** `{addCookieHeader?: boolean; clientAddress?: string; locals?: object; prerenderedErrorPageFetch?: (url: ErrorPagePath) => Promise; routeData?: RouteData;}`

-`app.render()` 方法接受一个必填的 `request` 参数,以及一个可选的 `RenderOptions` 对象,用于 [`addCookieHeader`](#addcookieheader)、[`clientAddress`](#clientaddress)、[`locals`](#locals)、[`prerenderedErrorPageFetch`](#prerenderederrorpagefetch) 和 [`routeData`](#routedata)。 +一个控制渲染的对象,包含以下属性: ###### `addCookieHeader` @@ -232,7 +392,7 @@ const response = await app.render(request); 是否自动将 `Astro.cookie.set()` 写入的所有 cookie 添加到响应头中。 当设置为 `true` 时,它们将作为逗号分隔的键值对添加到响应的 `Set-Cookie` 头中。你可以使用标准的 `response.headers.getSetCookie()` API 来单独读取它们。 -当设置为 `false`(默认值)时,这些 cookie 只能从 `App.getSetCookieFromResponse(response)` 中获取。 +当设置为 `false`(默认值)时,这些 cookie 只能从 [`App.getSetCookieFromResponse(response)`](#appgetsetcookiefromresponse) 中获取。 ```js const response = await app.render(request, { addCookieHeader: true }); @@ -270,15 +430,15 @@ const response = await app.render(request, { clientAddress }); const privateHeader = request.headers.get("x-private-header"); let locals = {}; try { - if (privateHeader) { - locals = JSON.parse(privateHeader); - } + if (privateHeader) { + locals = JSON.parse(privateHeader); + } } finally { - const response = await app.render(request, { locals }); + const response = await app.render(request, { locals }); } ``` -###### `prerenderedErrorPageFetch` +###### `prerenderedErrorPageFetch()`

@@ -293,22 +453,23 @@ try { 以下示例读取了磁盘中的 `500.html` 和 `404.html`,而不是执行 HTTP 调用: -```js "prerenderedErrorPageFetch" +```ts "prerenderedErrorPageFetch" return app.render(request, { prerenderedErrorPageFetch: async (url: string): Promise => { if (url.includes("/500")) { - const content = await fs.promises.readFile("500.html", "utf-8"); - return new Response(content, { - status: 500, - headers: { "Content-Type": "text/html" }, - }); - } - - const content = await fs.promises.readFile("404.html", "utf-8"); + const content = await fs.promises.readFile("500.html", "utf-8"); return new Response(content, { - status: 404, + status: 500, headers: { "Content-Type": "text/html" }, }); + } + + const content = await fs.promises.readFile("404.html", "utf-8"); + return new Response(content, { + status: 404, + headers: { "Content-Type": "text/html" }, + }); + } }); ``` @@ -318,30 +479,30 @@ return app.render(request, {

-**类型:** `RouteData`
+**类型:** [`RouteData`](/zh-cn/reference/integrations-reference/#routedata)
**默认值:** `app.match(request)`

-如果你已经知道要渲染的路由,请为 [`integrationRouteData`](/zh-cn/reference/integrations-reference/#integrationroutedata-类型参考) 提供一个值。这样做将绕过内部调用 [`app.match`](#appmatch) 来确定要渲染的路由。 +定义路由信息。如果你已经知道要渲染的路由,这将非常有用。这样做将绕过内部调用 [`app.match()`](#appmatch) 来确定要渲染的路由。 ```js "routeData" const routeData = app.match(request); if (routeData) { - return app.render(request, { routeData }); + return app.render(request, { routeData }); } else { - /* 特定于适配器的 404 响应 */ - return new Response(..., { status: 404 }); + /* 特定于适配器的 404 响应 */ + return new Response(..., { status: 404 }); } ``` -##### `app.match()` +#### `app.match()`

-**类型:** `(request: Request) => RouteData | undefined` +**类型:** `(request: Request, allowPrerenderedRoutes = false) => RouteData | undefined`

-该方法用于判断请求是否匹配 Astro 应用的路由规则。 +判断请求是否匹配 Astro 应用的路由规则。 ```js if(app.match(request)) { @@ -351,158 +512,292 @@ if(app.match(request)) { 通常可以在不使用 `.match` 的情况下调用 `app.render(request)`。因为当配置了 `404.astro` 文件后,Astro 就会自动处理 404 的情况。如果想要自定义处理规则,请使用 `app.match(request)`。 -## 使用 `astro add` 安装适配器 +默认情况下,即使匹配到预渲染的路由,也不会返回它们。你可以通过使用 `true` 作为第二个参数来更改此行为。 -用户可以使用 [`astro add` 命令](/zh-cn/reference/cli-reference/#astro-add) 轻松地在他们的项目中添加集成和适配器。如果希望其他用户可以使用该命令安装 _你的_ 适配器,**请在 `package.json` 文件的 `keywords` 项中添加 `astro-adapter` 属性**: +#### `app.getAdapterLogger()` -```json -{ - "name": "example", - "keywords": ["astro-adapter"], +

+ +**类型:** `() => AstroIntegrationLogger`
+ +

+ +返回适配器运行时环境可用的 [Astro 日志记录器实例](/zh-cn/reference/integrations-reference/#astrointegrationlogger)。 + +```js "logger" +const logger = app.getAdapterLogger(); +try { + /* 某些可能抛出错误的逻辑 */ +} catch { + logger.error("使用 Astro 日志记录器的自定义错误消息。"); } ``` -当[将适配器发布到 npm](https://docs.npmjs.com/cli/v8/commands/npm-publish) 后,执行 `astro add example` 命令,即可安装适配器以及在 `package.json` 文件中指定的对等依赖。我们将指导用户手动更新他们的项目配置。 +#### `app.getAllowedDomains()` -## Astro features +

-

+**类型:** `() => Partial[] | undefined`
+ +

-Astro features 是适配器告诉 Astro 它们是否能够支持某个特性的一种方式,也是适配器支持程度的一种方式。 +返回使用按需渲染时允许的传入请求的托管平台模式列表,[在用户配置中定义](/zh-cn/reference/configuration-reference/#securityalloweddomains)。 -当使用这些属性时,Astro 将: -- 运行特定的验证; -- 向日志抛出(emit)上下文信息; +#### `app.removeBase()` -这些操作是基于支持或不支持的特性、支持程度、[所需的记录量](#suppress) 以及用户使用的配置来运行的。 +

-以下配置告诉 Astro,该适配器对 Sharp 提供的内置图像服务有实验性支持: +**类型:** `(pathname: string) => string`
+ +

-```js title="my-adapter.mjs" ins={9-11} -export default function createIntegration() { - return { - name: '@example/my-adapter', - hooks: { - 'astro:config:done': ({ setAdapter }) => { - setAdapter({ - name: '@example/my-adapter', - serverEntrypoint: '@example/my-adapter/server.js', - supportedAstroFeatures: { - sharpImageService: 'experimental' - } - }); - }, - }, - }; +从给定路径中移除基础路径。当你需要从文件系统查找资源时,这非常有用。 + +#### `app.setCookieHeaders()` + +

+ +**类型:** `(response: Response) => Generator`
+ +

+ +返回一个生成器,从 `Response` 对象中生成单个 cookie 请求头值。这用于正确处理在请求处理期间可能设置的多个 cookie。 + +以下示例为从响应中获取的每个请求头附加一个 `Set-Cookie`: + +```js +for (const setCookieHeader of app.setCookieHeaders(response)) { + response.headers.append('Set-Cookie', setCookieHeader); } ``` -如果使用 Sharp 图像服务,Astro 将根据适配器的支持程度向终端输出警告和错误: +#### `App.getSetCookieFromResponse()` -``` -[@example/my-adapter] The feature is experimental and subject to issues or changes. +

-[@example/my-adapter] The currently selected adapter `@example/my-adapter` is not compatible with the service "Sharp". Your project will NOT be able to build. -``` +**类型:** `(response: Response) => Generator`
+ +

-还可以提供一条消息,以便为用户提供更多上下文: +返回一个生成器,从 `Response` 对象中生成单个 cookie 请求头值。这与 [`app.setCookieHeaders()`](#appsetcookieheaders) 的工作方式相同,但可以在任何时候使用,因为它是一个静态方法。 -```js title="my-adapter.mjs" ins={9-14} -export default function createIntegration() { - return { - name: '@example/my-adapter', - hooks: { - 'astro:config:done': ({ setAdapter }) => { - setAdapter({ - name: '@example/my-adapter', - serverEntrypoint: '@example/my-adapter/server.js', - supportedAstroFeatures: { - sharpImageService: { - support: 'limited', - message: 'This adapter has limited support for Sharp, certain features may not work as expected.' - } - } - }); - }, - }, - }; +以下示例为从响应中获取的每个请求头附加一个 `Set-Cookie`: + +```js +for (const cookie of App.getSetCookieFromResponse(response)) { + response.headers.append('Set-Cookie', cookie); } ``` -### `suppress` +#### `App.validateForwardedHost()`

-**类型:** `'default' | 'all'`
- +**类型:** `(forwardedHost: string, allowedDomains?: Partial[], protocol?: string = 'https') => boolean`
+

-该选项是用于阻止在日志内容中,展示有关适配器对特性支持情况的部分或全部信息。 +检查 `forwardedHost` 是否匹配任何给定的 [`allowedDomains`](/zh-cn/reference/configuration-reference/#securityalloweddomains)。此静态方法接受第三个参数,允许你覆盖托管平台协议,默认为 `https`。 -如果 Astro 的默认日志信息已经多余,甚至与用户自定义的 `message` 部分混杂在一起,从而导致使用过程中的困惑,那么你可以使用 `suppress: "default"` 来仅显示自定义消息,同时抑制默认日志输出: +以下示例从头中检索 `forwardedHost` 并检查托管平台是否匹配允许的域名: -```js title="my-adapter.mjs" ins={13} -export default function createIntegration() { - return { - name: '@example/my-adapter', - hooks: { - 'astro:config:done': ({ setAdapter }) => { - setAdapter({ - name: '@example/my-adapter', - serverEntrypoint: '@example/my-adapter/server.js', - supportedAstroFeatures: { - sharpImageService: { - support: 'limited', - message: 'The adapter has limited support for Sharp. It will be used for images during build time, but will not work at runtime.', - suppress: 'default' // 自定义信息相较于默认信息会更加详尽 - } - } - }); - }, - }, - }; +```js {4-6} +export function start(manifest) { + addEventListener('fetch', (event) => { + const forwardedHost = event.request.headers.get('X-Forwarded-Host'); + if (App.validateForwardedHost(forwardedHost, manifest.allowedDomains)) { + /* 执行某些操作 */ + } + }); } ``` -你还可通过 `suppress: "all"` 配置完全抑制该功能的所有相关日志信息。这在特定场景下尤为实用,例如当用户通过配置项明确禁用某功能时,相关提示信息反而会造成干扰。以屏蔽 Sharp 图像处理库的日志为例: +#### `App.sanitizeHost()` -```js title="my-adapter.mjs" ins={13} -export default function createIntegration() { - return { - name: '@example/my-adapter', - hooks: { - 'astro:config:done': ({ setAdapter }) => { - setAdapter({ - name: '@example/my-adapter', - serverEntrypoint: '@example/my-adapter/server.js', - supportedAstroFeatures: { - sharpImageService: { - support: 'limited', - message: 'This adapter has limited support for Sharp. Certain features may not work as expected.', - suppress: 'all' - } - } - }); - }, - }, - }; +

+ +**类型:** `(hostname: string | undefined) => string | undefined`
+ +

+ +通过拒绝任何包含路径分隔符的名称来验证主机名。当主机名无效时,此静态方法将返回 `undefined`。 + +以下示例从头中检索 `forwardedHost` 并对其进行清理: + +```js {4} +export function start(manifest) { + addEventListener('fetch', (event) => { + const forwardedHost = event.request.headers.get('X-Forwarded-Host'); + const sanitized = App.sanitizeHost(forwardedHost); + }); } ``` -## Adapter features +#### `App.validateForwardedHeaders()` -一组可以改变产出文件输出的特性。当适配器选择这些特性时,它们将在特定的钩子中获得额外的信息。 +

-### `edgeMiddleware` +**类型:** `(forwardedProtocol?: string, forwardedHost?: string, forwardedPort?: string, allowedDomains?: Partial[]) => { protocol?: string; host?: string; port?: string }`
+ +

+ +根据 `allowedDomains` 验证转发的协议、主机和端口。此静态方法返回验证后的值或对被拒绝的头返回 `undefined`。 + +以下示例根据接收到的清单中定义的授权域名验证转发的请求头: + +```js {3-8} +export function start(manifest) { + addEventListener('fetch', (event) => { + const validated = App.validateForwardedHeaders( + request.headers.get('X-Forwarded-Proto') ?? undefined, + request.headers.get('X-Forwarded-Host') ?? undefined, + request.headers.get('X-Forwarded-Port') ?? undefined, + manifest.allowedDomains, + ); + }); +} +``` + +### `astro/app/node` + +与 [`astro/app`](#astroapp) 类似,该模块用于渲染已通过 `astro build` 预构建的页面。这允许你创建一个 `NodeApp`,提供 `App` 中的所有方法以及适用于 Node 环境的附加方法。 + +`NodeApp` 构造函数接受必需的 SSR 清单参数,并可选择接受一个用于启用或禁用流式传输的参数,默认为 `true`。 + +```js +import { NodeApp } from 'astro/app/node'; +import http from 'http'; + +export function start(manifest) { + const nodeApp = new NodeApp(manifest); + + addEventListener('fetch', event => { + event.respondWith( + nodeApp.render(event.request) + ); + }); +} +``` + +提供以下附加方法: + +#### `nodeApp.render()`

-**类型:** `boolean` +**类型:** `(request: NodeRequest | Request, options?: RenderOptions) => Promise`
+ +

+ +扩展 [`app.render()`](#apprender),除了标准的 `Request` 对象外,还可以接受 [Node.js `IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) 对象作为第一个参数。第二个参数是一个可选对象,允许你 [控制渲染](#renderoptions)。 + +```js +const response = await nodeApp.render(request); +``` + +#### `nodeApp.match()` + +

+ +**类型:** `(req: NodeRequest | Request, allowPrerenderedRoutes?: boolean) => RouteData | undefined` +

+ +扩展 [`app.match()`](#appmatch),除了标准的 `Request` 对象外,还可以接受 [Node.js `IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) 对象。 + +```js +if(nodeApp.match(request)) { + const response = await nodeApp.render(request); +} +``` + +#### `nodeApp.headersMap` + +

+ +**类型:** `NodeAppHeadersJson | undefined`
+**默认值:** `undefined`
+ +

+ +包含 headers 请求头配置的数组。每个条目将路径名映射到应该为该路由应用的 headers 的列表。这对于将 CSP 指令等 headers 应用于预渲染路由非常有用。 + +#### `nodeApp.setHeadersMap()` + +

+ +**类型:** `(headers: NodeAppHeadersJson) => void`
+ +

+ +将 [headers 配置](#nodeappheadersmap) 加载到 `NodeApp` 实例中。 + +```js +nodeApp.setHeadersMap([ + { + pathname: "/blog", + headers: [ + { key: "Content-Security-Policy", value: "default-src 'self'" }, + ] + } +]); +``` + +#### `NodeApp.createRequest()` + +

+ +**类型:** `(req: NodeRequest, options?: { skipBody?: boolean; allowedDomains?: Partial[]; }) => Request`
+ +

+ +将 NodeJS `IncomingMessage` 转换为标准的 `Request` 对象。此静态方法接受一个可选对象作为第二个参数,允许你定义是否应忽略请求体,默认为 `false`,以及 [`allowedDomains`](/zh-cn/reference/configuration-reference/#securityalloweddomains)。 + +以下示例创建一个 `Request` 并将其传递给 `app.render()`: + +```js {5} +import { NodeApp } from 'astro/app/node'; +import { createServer } from 'node:http'; + +const server = createServer(async (req, res) => { + const request = NodeApp.createRequest(req); + const response = await app.render(request); +}) +``` + +#### `NodeApp.writeResponse()` + +

+ +**类型:** `(source: Response, destination: ServerResponse) => Promise | undefined>`
+

-定义在构建时是否会打包任何按需渲染的中间件代码。 +将 Web 标准 `Response` 流式传输到 NodeJS 服务器响应中。此静态方法接受一个 `Response` 对象和初始 `ServerResponse`,然后返回 `ServerResponse` 对象的 promise。 + +以下示例创建一个 `Request`,将其传递给 `app.render()`,并写入响应: + +```js {7} +import { NodeApp } from 'astro/app/node'; +import { createServer } from 'node:http'; -启用此功能时,会阻止在构建期间将中间件代码打包并导入到所有页面中: +const server = createServer(async (req, res) => { + const request = NodeApp.createRequest(req); + const response = await app.render(request); + await NodeApp.writeResponse(response, res); +}) +``` + +## Astro 特性 + +Astro 特性能是适配器向 Astro 告知其是否支持某项功能以及适配器支持程度的一种方式。 + +使用这些属性时,Astro 将: +- 运行特定的验证; +- 向日志发出上下文信息; + +这些操作基于支持或不支持的特性、支持级别、[期望的日志量](#suppress) 和用户自己的配置运行。 + +以下配置告诉 Astro 该适配器对基于 Sharp 的内置图像服务具有实验性支持: ```js title="my-adapter.mjs" ins={9-11} export default function createIntegration() { @@ -513,8 +808,8 @@ export default function createIntegration() { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', - adapterFeatures: { - edgeMiddleware: true + supportedAstroFeatures: { + sharpImageService: 'experimental' } }); }, @@ -523,9 +818,17 @@ export default function createIntegration() { } ``` -然后,使用 [`astro:build:ssr`](/zh-cn/reference/integrations-reference/#astrobuildssr) 钩子,它将为你提供一个 `middlewareEntryPoint`,一个指向文件系统上物理文件的 `URL`。 +如果使用了 Sharp 图像服务,Astro 将根据适配器的支持情况向终端记录警告和错误: + +``` +[@example/my-adapter] The feature is experimental and subject to issues or changes. + +[@example/my-adapter] The currently selected adapter `@example/my-adapter` is not compatible with the service "Sharp". Your project will NOT be able to build. +``` + +还可以提供一条消息,向用户提供更多上下文: -```js title="my-adapter.mjs" ins={15-19} +```js title="my-adapter.mjs" ins={9-14} export default function createIntegration() { return { name: '@example/my-adapter', @@ -534,38 +837,69 @@ export default function createIntegration() { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', - adapterFeatures: { - edgeMiddleware: true + supportedAstroFeatures: { + sharpImageService: { + support: 'limited', + message: 'This adapter has limited support for Sharp. Certain features may not work as expected.' + } } }); }, - - 'astro:build:ssr': ({ middlewareEntryPoint }) => { - // 请记住检查此属性是否退出,如果适配器未选择加入该功能,则它将是 `undefined` - if (middlewareEntryPoint) { - createEdgeMiddleware(middlewareEntryPoint) - } - } }, }; } - -function createEdgeMiddleware(middlewareEntryPoint) { - // 通过你的打包工具生成一个新的物理文件 -} ``` +该对象包含以下可配置的功能: -### envGetSecret +### `staticOutput`

-**类型:** `AdapterSupportsKind` +**类型:** [`AdapterSupport`](#adaptersupport)

-此功能允许你的适配器获取用户在 `env.schema` 中配置的密钥。 +定义适配器是否能够提供静态页面。 -通过任何有效的 `AdapterSupportsKind` 值传递给适配器来启用此功能: +### `hybridOutput` + +

+ +**类型:** [`AdapterSupport`](#adaptersupport) +

+ +定义适配器是否能够提供包含静态和按需渲染页面混合的站点。 + +### `serverOutput` + +

+ +**类型:** [`AdapterSupport`](#adaptersupport) +

+ +定义适配器是否能够提供按需渲染的页面。 + +### `i18nDomains` + +

+ +**类型:** [`AdapterSupport`](#adaptersupport)
+ +

+ +定义适配器是否能够支持 i18n 域名。 + +### `envGetSecret` + +

+ +**类型:** [`AdapterSupport`](#adaptersupport)
+ +

+ +定义适配器是否能够支持从 [`astro:env/server`](/zh-cn/reference/modules/astro-env/) 导出的 `getSecret()`。启用后,此功能允许你的适配器检索用户在 `env.schema` 中配置的密钥。 + +以下示例通过向适配器传递 [有效的 `AdapterSupportsKind` 值](#adaptersupportskind) 来启用该功能: ```js title="my-adapter.mjs" ins={9-11} export default function createIntegration() { @@ -576,8 +910,8 @@ export default function createIntegration() { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', - adapterFeatures: { - envGetSecret: 'stable' + supportedAstroFeatures: { + envGetSecret: 'stable' } }); }, @@ -586,7 +920,7 @@ export default function createIntegration() { } ``` -`astro/env/setup` 模块允许你为 `getSecret()` 提供一个实现。在你的服务器入口中,尽早调用 `setGetEnv()`: +`astro/env/setup` 模块允许你为 `getSecret()` 提供一个实现。在 [你的服务器入口](#构建服务器入口点) 中,尽早调用 `setGetEnv()`: ```js ins={2,4} import { App } from 'astro/app'; @@ -605,7 +939,7 @@ export function createExports(manifest) { } ``` -如果你支持密钥,请确保在请求时将 `setGetEnv()` 调用在 `getSecret()` 之前: +如果适配器支持密钥,请确保在环境变量与请求绑定时,先调用 `setGetEnv()`,再调用 `getSecret()`: ```js ins={3,14} import type { SSRManifest } from 'astro'; @@ -632,15 +966,30 @@ export function createExports(manifest: SSRManifest) { } ``` -### buildOutput +### `sharpImageService`

-**类型:** `'static' | 'server'`
+**类型:** [`AdapterSupport`](#adaptersupport)

-此属性允许你强制指定构建的特定输出形态。这对于只能使用特定输出类型的适配器非常有用,例如,你的适配器可能期望一个静态网站,但使用适配器来创建特定于主机的文件。如果未指定,则默认为 `server`。 +定义适配器是否支持使用内置 Sharp 图像服务进行图像转换。 + +## 适配器特性 + +一组改变输出文件内容的特性。当适配器选择使用这些特性时,它们将在特定钩子中获得额外信息,并且必须实现适当的逻辑来处理不同的输出。 + +### `edgeMiddleware` + +

+ +**类型:** `boolean` +

+ +定义构建时是否将打包任何按需渲染的中间件代码。 + +启用后,这会阻止中间件代码在构建期间被所有页面打包和导入: ```js title="my-adapter.mjs" ins={9-11} export default function createIntegration() { @@ -652,28 +1001,86 @@ export default function createIntegration() { name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', adapterFeatures: { - buildOutput: 'static' + edgeMiddleware: true + } + }); + }, + }, + }; +} +``` + +然后,使用钩子 [`astro:build:ssr`](/zh-cn/reference/integrations-reference/#astrobuildssr),它将给你一个 `middlewareEntryPoint`,即文件系统上物理文件的 `URL`。 + +```js title="my-adapter.mjs" ins={15-20} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + adapterFeatures: { + edgeMiddleware: true } }); }, + + 'astro:build:ssr': ({ middlewareEntryPoint }) => { + // 记得检查此属性是否存在,如果适配器未选择使用该功能,它将返回 `undefined` + if (middlewareEntryPoint) { + createEdgeMiddleware(middlewareEntryPoint) + } + } }, }; } + +function createEdgeMiddleware(middlewareEntryPoint) { + // 使用你的打包器发出一个新的物理文件 +} ``` -### experimentalStaticHeaders +### `buildOutput`

-**类型:** `true | false`
- +**类型:** `"static" | "server"`
+**默认值:** `"server"`
+

-启用该功能后,Astro 将返回静态页面生成的 `Headers` 映射。该映射 `experimentalRouteToHeaders` 可通过 `astro:build:generated` 构建钩子获取。 +允许你强制使用特定的输出形状进行构建。这对于仅适用于特定输出类型的适配器非常有用。例如,你的适配器可能期望静态网站,但使用适配器来创建特定于托管平台的文件。如果未指定,默认为 `server`。 -Headers 的具体值会随应用启用/调用的功能而动态变化。 +```js title="my-adapter.mjs" ins={9-11} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + adapterFeatures: { + buildOutput: 'static' + } + }); + }, + }, + }; +} +``` + +### `experimentalStaticHeaders` + +

-例如,当启用 CSP(内容安全策略)时,`` 元素不会被添加至静态页面。取而代之的是,其 `content` 可在 `experimentalRouteToHeaders` 映射中获取。 +**类型:** `boolean`
+ +

+ +适配器是否为静态页面设置响应头提供实验性支持。启用此功能后,Astro 将返回静态页面发出的 `Headers` 的映射。此映射 `experimentalRouteToHeaders` 在 [`astro:build:generated` 钩子](/zh-cn/reference/integrations-reference/#astrobuildgenerated) 中可用,用于生成诸如 `_headers` 之类的文件,允许你对默认 HTTP 请求头进行更改。 ```js title="my-adapter.mjs" ins={9-11} export default function createIntegration() { @@ -690,10 +1097,137 @@ export default function createIntegration() { }); }, 'astro:build:generated': ({ experimentalRouteToHeaders }) => { - // 为你所选择的虚拟主机, - // 使用 `experimentalRouteToHeaders` 来生成一个配置文件 + // 使用 `experimentalRouteToHeaders` 为你选择的虚拟主机生成配置文件 }, }, }; } ``` + +请求头的值可能会根据应用程序启用/使用的功能而变化。例如,如果 [启用了 CSP](/zh-cn/reference/experimental-flags/csp/),则 `` 元素不会添加到静态页面。相反,其 `content` 在 `experimentalRouteToHeaders` 映射中可用。 + +## 适配器类型引用 + +### `AdapterSupport` + +

+ +**类型:** AdapterSupportsKind | AdapterSupportWithMessage
+ +

+ +描述特性支持级别的有效格式的联合类型。 + +### `AdapterSupportsKind` + +

+ +**类型:** `"deprecated" | "experimental" | "limited" | "stable" | "unsupported"` +

+ +定义适配器对特性的支持级别: +* 当你的适配器在未来版本中完全移除某个特性之前弃用对该特性的支持时,使用 `"deprecated"`。 +* 当你的适配器添加了对某个特性的支持,但预计会出现问题或重大更改时,使用 `"experimental"`。 +* 当你的适配器仅支持完整特性的子集时,使用 `"limited"`。 +* 当你的适配器完全支持该特性时,使用 `"stable"`。 +* 使用 `"unsupported"` 警告用户他们的项目可能会遇到构建问题,因为你的适配器不支持此特性。 + +### `AdapterSupportWithMessage` + +

+ + +

+ +一个对象,允许你定义特性的支持程度和要在用户控制台中记录的消息。此对象包含以下属性: + +#### `support` + +

+ +**类型:** Exclude\<AdapterSupportsKind, "stable"\> +

+ +定义适配器对功能的支持程度。 + +#### `message` + +

+ +**类型:** `string` +

+ +定义关于适配器对特性支持的自定义消息。 + +#### `suppress` + +

+ +**类型:** `"default" | "all"`
+ +

+ +一个选项,用于阻止显示关于适配器对特性支持的部分或所有已记录消息。 + +如果 Astro 的默认日志消息是多余的,或者与你的 [自定义 `message`](#message) 结合使用时会让用户感到困惑,你可以使用 `suppress: "default"` 来抑制默认消息,仅记录你的消息: + +```js title="my-adapter.mjs" ins={13} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + supportedAstroFeatures: { + sharpImageService: { + support: 'limited', + message: 'The adapter has limited support for Sharp. It will be used for images during build time, but will not work at runtime.', + suppress: 'default' // 自定义消息比默认消息更详细 + } + } + }); + }, + }, + }; +} +``` + +你也可以使用 `suppress: "all"` 来抑制有关特性支持的所有消息。当这些消息在特定上下文中对用户没有帮助时,这非常有用,例如当用户有配置设置意味着他们没有使用该特性时。例如,你可以选择阻止从适配器记录任何关于 Sharp 支持的消息: + +```js title="my-adapter.mjs" ins={13} +export default function createIntegration() { + return { + name: '@example/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@example/my-adapter', + serverEntrypoint: '@example/my-adapter/server.js', + supportedAstroFeatures: { + sharpImageService: { + support: 'limited', + message: 'This adapter has limited support for Sharp. Certain features may not work as expected.', + suppress: 'all' + } + } + }); + }, + }, + }; +} +``` + +## 允许通过 `astro add` 安装 + +[`astro add` 命令](/zh-cn/reference/cli-reference/#astro-add) 允许用户轻松地将集成和适配器添加到他们的项目中。要允许你的适配器通过此命令安装,**将 `astro-adapter` 添加到 `package.json` 的 `keywords` 字段中**: + +```json +{ + "name": "example", + "keywords": ["astro-adapter"], +} +``` + +当你 [将适配器发布到 npm](https://docs.npmjs.com/cli/v8/commands/npm-publish) 后,运行 `astro add example` 将安装你的包以及 `package.json` 中指定的任何对等依赖,并指示用户手动更新其项目配置。 diff --git a/src/content/docs/zh-cn/reference/integrations-reference.mdx b/src/content/docs/zh-cn/reference/integrations-reference.mdx index d7436f179326f..91938f15b65e2 100644 --- a/src/content/docs/zh-cn/reference/integrations-reference.mdx +++ b/src/content/docs/zh-cn/reference/integrations-reference.mdx @@ -194,7 +194,7 @@ export default {

-**类型:** `(renderer:` [`AstroRenderer`](https://github.com/withastro/astro/blob/fdd607c5755034edf262e7b275732519328a33b2/packages/astro/src/%40types/astro.ts#L872-L883) `) => void;`
+**类型:** (renderer: AstroRenderer) => void;
**示例:** [`svelte`](https://github.com/withastro/astro/blob/main/packages/integrations/svelte/src/index.ts)、[`react`](https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts)、[`preact`](https://github.com/withastro/astro/blob/main/packages/integrations/preact/src/index.ts)、[`vue`](https://github.com/withastro/astro/blob/main/packages/integrations/vue/src/index.ts)、[`solid`](https://github.com/withastro/astro/blob/main/packages/integrations/solid/src/index.ts)

@@ -215,7 +215,7 @@ export default {

-如果你的集成依赖于一些 Vite 不监听或者需要完整的开发服务器重启才能生效的配置文件,请用`addWatchFile` 添加它。每当该文件发生变化,Astro 开发服务器将重新加载(你可以用`isRestart`检查何时发生重新加载)。 +如果你的集成依赖于一些 Vite 不监听或者需要完整的开发服务器重启才能生效的配置文件,请用`addWatchFile()` 添加它。每当该文件发生变化,Astro 开发服务器将重新加载(你可以用 [`isRestart`](#isrestart-选项) 检查何时发生重新加载)。 使用示例: ```js @@ -228,7 +228,7 @@ addWatchFile(new URL('./ec.config.mjs', config.root));

-**类型:** `(directive:` [`ClientDirectiveConfig`](https://github.com/withastro/astro/blob/00327c213f74627ac9ca1dec774efa5bf71e9375/packages/astro/src/%40types/astro.ts#L1872-L1875) `) => void;`
+**类型:** (directive: ClientDirectiveConfig) => void;

@@ -352,7 +352,7 @@ export default {

-**类型:** `(middleware:` [`AstroIntegrationMiddleware`](https://github.com/withastro/astro/blob/852ac0f75dfca1b2602e9cdbfa0447d9998e2449/packages/astro/src/%40types/astro.ts#L2124-L2127) `) => void;`
+**类型:** (middleware: AstroIntegrationMiddleware) => void;

@@ -375,7 +375,7 @@ export default () => ({ }); ``` -中间件在一个包中定义,它有一个对应的 `onRequest` 函数,就像用户定义的中间件一样。 +中间件在一个包中定义,它有一个对应的 [`onRequest` 函数](/zh-cn/reference/modules/astro-middleware/#onrequest),就像用户定义的中间件一样。 ```js title="@my-package/middleware.js" import { defineMiddleware } from 'astro:middleware'; @@ -420,7 +420,7 @@ export default () => ({ 用于向 Astro 项目注入路由的回调函数。注入的路由可以是 [`.astro`页面](/zh-cn/basics/astro-pages/) 或 [`.js`和`.ts`路由处理程序](/zh-cn/guides/endpoints/#静态文件端点)。 -`injectRoute` 接收带有 `pattern` 和 `entrypoint` 的对象值。 +`injectRoute()` 接收带有 `pattern` 和 `entrypoint` 的对象值。 - `pattern` - 应该在浏览器中使用的路由,例如 `/foo/bar`。`pattern` 可以使用 Astro 的文件路径语法来表示动态路由,例如 `/foo/[bar]` 或 `/foo/[...bar]`。请注意,在 `pattern` 中**无需**文件扩展名。 - `entrypoint` — 裸模块指定器,指向 `.astro` 页面或 `.js`/`.ts` 路由处理程序,处理`pattern` 中指定路由。 @@ -539,7 +539,7 @@ const integration = {

-**类型:** [`RouteOptions`](https://github.com/withastro/astro/blob/3b10b97a4fecd1dfd959b160a07b5b8427fe40a7/packages/astro/src/types/public/integrations.ts#L14-L27) +**类型:** `{ readonly component: string; prerender?: boolean; }`

具有 `component` 属性的对象用于标识路由,以及以下附加值,以允许你配置生成的路由:`prerender`。 @@ -612,7 +612,7 @@ function setPrerender() {

-**类型:** [`IntegrationResolvedRoute[]`](#integrationroutedata-类型参考) +**类型:** [`IntegrationResolvedRoute[]`](#integrationresolvedroute)

一个包含了所有路由及其关联元数据的列表。 @@ -808,7 +808,7 @@ export default { 一个用于在 `astro dev` 时触发,以更新 content layer 的函数。可以这样使用,例如,要在开发时注册一个 webhook 端点,或者开启一个 socket 来监听 CMS 的改动。 -默认情况下,`refreshContent` 会刷新所有的集合。你可以选择性的提供一个 `loaders` 属性去传递,即一个包含着加载器(loader)名称的数组。如果提供的话,那么就只有使用了这些加载器的集合会被刷新。例如,一个 CMS 集成可以使用该属性来单独刷新它自己的集合。 +默认情况下,`refreshContent()` 会刷新所有的集合。你可以选择性的提供一个 `loaders` 属性去传递,即一个包含着加载器(loader)名称的数组。如果提供的话,那么就只有使用了这些加载器的集合会被刷新。例如,一个 CMS 集成可以使用该属性来单独刷新它自己的集合。 你也可以传递一个 `context` 对象给加载器。它可以用来传递任意数据,例如 webhook body,或者是来自 websocket 的事件。 @@ -871,10 +871,10 @@ export default {

-**类型:** [`AddressInfo`](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules__types_node_net_d_._net_.addressinfo.html) +**类型:** `AddressInfo`

-由 [Node.js Net 模块](https://nodejs.org/api/net.html) 提供的地址、协议族名和端口。 +由 [Node.js Net 模块的 `server.address()` 方法](https://nodejs.org/api/net.html#serveraddress) 提供的地址、协议族名和端口。 ### `astro:server:done` @@ -953,10 +953,10 @@ export default {

-**类型:** Map\PageBuildData\> +**类型:** `Map`

-一个 `Map` 对象,其中将页面列表作为键,将其构建的数据作为值。 +一个 `Map` 对象,其中将页面列表作为键,将[其构建的数据](#页面构建数据)作为值。 可用于在路由和一种准则匹配时,执行一些行为: @@ -975,6 +975,58 @@ export default { } ``` + +#### 页面构建数据 + +一个描述如何构建页面的对象。 + +###### `key` + +

+ +**类型:** `string`
+ +

+ +指定页面的唯一标识符。 + +###### `component` + +

+ +**类型:** `string` +

+ +指定源组件的URL。 + +###### `route` + +

+ +**类型:** [`RouteData`](#routedata) +

+ +描述关于页面路由的信息。 + +###### `moduleSpecifier` + +

+ +**类型:** `string` +

+ +定义一个可以解析为模块文件路径的字符串。 + +###### `styles` + +

+ +**类型:** `Array<{ depth: number; order: number; sheet: { type: 'inline'; content: string } | { type: 'external'; src: string } }>`
+ +

+ +在页面上渲染的样式列表。每个样式包含其在组件树中的 `depth` 以及在页面上的显示 `order`,并指明该样式应作为内联还是外部样式应用。 + #### `target` 选项

@@ -1051,7 +1103,7 @@ export default {

-**类型:** [`SerializedSSRManifest`](https://github.com/withastro/astro/blob/3b10b97a4fecd1dfd959b160a07b5b8427fe40a7/packages/astro/src/core/app/types.ts#L91-L109) +**类型:** [`SerializedSSRManifest`](#已序列化的-ssr-清单属性)

允许你通过访问 SSR 清单来创建自定义构建。 @@ -1070,11 +1122,83 @@ export default { } ``` +##### 已序列化的 SSR 清单属性 + +[`SSRManifest`](#ssrmanifest) 的序列化版本,可通过 [`astro:build:ssr` 钩子](#astrobuildssr) 访问。它包含与 `SSRManifest` 相同的信息,但某些属性已转换为可序列化的格式。 + +###### `routes` + +

+ +**类型:** `SerializedRouteInfo[]` +

+ +定义了一个序列化路由信息的列表。每个路由包含与 [`SSRManifest.routes`](#routes-1) 相同的属性,其中 `routeData` 被转换为 JSON 可序列化格式。 + +###### `assets` + +

+ +**类型:** `string[]` +

+ +定义序列化资源文件路径的列表。 + +###### `componentMetadata` + +

+ +**类型:** [string, SSRComponentMetadata][]
+ +

+ +定义一个键值对数组,其中第一个元素是组件标识符,第二个元素是描述构建元数据的对象。 + +###### `inlinedScripts` + +

+ +**类型:** `[string, string][]` +

+ +定义一组键值对数组,其中每一项都是一个元组。第一个元素是脚本标识符,第二个是脚本内容。 + +###### `clientDirectives` + +

+ +**类型:** `[string, string][]`
+ +

+ +定义一个键值对数组,其中第一个元素是指令名称(例如 `load`、`visible`),第二个是该指令的实现代码。 + + +###### `serverIslandNameMap` + +

+ +**类型:** `[string, string][]`
+ +

+ +定义一个键值对数组,其中每个条目都是一个元组。第一个元素是组件路径,第二个是分配的名称。 + +###### `key` + +

+ +**类型:** `string`
+ +

+ +指定用于加密服务器岛屿属性的加密密钥,以字符串形式序列化。 + #### `entryPoints` 选项

-**类型:** Map\<IntegrationRouteData, URL\>
+**类型:** Map\<IntegrationRouteData, URL\>

@@ -1145,7 +1269,9 @@ export default { **类型:** [`URL`](https://developer.mozilla.org/zh-CN/docs/Web/API/URL)

-一个构建输出目录的 URL 路径。请注意,如果你需要有效的绝对路径字符串,那么你应该使用 Node 内置的 [`fileURLToPath`](https://nodejs.org/api/url.html#urlfileurltopathurl-options) 工具函数。 +一个构建输出目录的 URL 路径。 + +下面的示例使用 Node 内置的 [`fileURLToPath`](https://nodejs.org/api/url.html#urlfileurltopathurl-options) 工具函数来计算由集成提供的文件的有效绝对路径字符串: ```js import { fileURLToPath } from 'node:url'; @@ -1186,7 +1312,9 @@ export default { **类型:** [`URL`](https://developer.mozilla.org/zh-CN/docs/Web/API/URL)

-一个构建输出目录的 URL 路径。注意,如果你需要有效的绝对路径字符串,你应该使用 Node 内置的 [`fileURLToPath`](https://nodejs.org/api/url.html#urlfileurltopathurl-options) 工具函数。 +一个构建输出目录的 URL 路径。 + +下面的示例使用 Node 内置的 [`fileURLToPath()`](https://nodejs.org/api/url.html#urlfileurltopathurl-options) 工具函数来计算集成提供的文件的有效绝对路径字符串,然后再将其写入该文件: ```js import { writeFile } from 'node:fs/promises'; @@ -1214,7 +1342,7 @@ export default function myIntegration() {

-**类型:** [`IntegrationRouteData[]`](#integrationroutedata-类型参考) +**类型:** [`IntegrationRouteData[]`](#integrationroutedata)

所有生成的路由及其相关元数据的列表。 @@ -1232,7 +1360,7 @@ export default function myIntegration() {

-包含了输出文件路径的链接,被 [`IntegrationResolvedRoute`](#integrationresolvedroute-类型参考) 的 `pattern` 属性分组。 +包含了输出文件路径的链接,被 [`IntegrationResolvedRoute`](#integrationresolvedroute) 的 `pattern` 属性分组。 #### `pages` 选项 @@ -1241,7 +1369,7 @@ export default function myIntegration() { **类型:** `{ pathname: string }[]`

-一个包含了所有被生成页面的列表,它是一个对象,且带有一个属性。 +一个包含了所有被生成页面的列表。每个条目是一个对象,且带有一个属性。 - `pathname` - 页面的最终路径。 @@ -1263,7 +1391,33 @@ Astro 为未来的内置钩子保留了 `astro:` 前缀。请在命名时,为 ## 集成类型参考 -## `AstroIntegrationLogger` +以下类型可以从 `astro` 模块中导入: + +```ts +import type { + AstroIntegrationLogger, + AstroIntegrationMiddleware, + AstroMiddlewareInstance, + AstroRenderer, + ClientDirectiveConfig, + HookParameters, + IntegrationResolvedRoute, + RedirectConfig, + RouteData, + RoutePart, + RouteType, + SSRComponentMetadata, + SSRLoadedRenderer, + SSRLoadedRendererValue, + SSRManifest, + SSRManifestCSP, + ValidRedirectStatus, + // 以下内容已被弃用: + IntegrationRouteData, +} from "astro"; +``` + +### `AstroIntegrationLogger` Astro 日志记录器的实例,用于写日志。此日志记录器使用与 CLI 配置的相同的[日志级别](/zh-cn/reference/cli-reference/#--verbose)。 @@ -1325,9 +1479,108 @@ export function formatIntegration(): AstroIntegration { [astro-format/build] Build finished. ``` +### `AstroIntegrationMiddleware` + +

+ +**类型:** `{ order: "pre" | "post"; entrypoint: string | URL; }` +

+ +描述 [由集成添加的中间件](#addmiddleware-选项)。 + +#### `order` + +

+ +**类型:** `"pre" | "post"` +

+ +指定中间件应该在其他中间件之前(`pre`)还是之后(`post`)运行。 + +#### `entrypoint` + +

+ +**类型:** `string | URL` +

+ +定义中间件的导入路径。 + +### `AstroMiddlewareInstance` + +

+ +**类型:** \{ onRequest?: MiddlewareHandler; \} +

+ +一个对象,当项目的中间件函数存在时,包含一个使用该函数定义的 [`onRequest()`](/zh-cn/reference/modules/astro-middleware/#onrequest) 属性。 + +### `AstroRenderer` + +

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

+ +描述 [由集成添加的组件框架渲染器](#addrenderer-选项)。 + +#### `name` + +

+ +**类型:** `string` +

+ +组件框架渲染器的名称。 + +#### `clientEntrypoint` + +

+ +**类型:** `string | URL` +

+ +定义在使用你的组件时,在客户端运行的渲染器的导入路径。 + +#### `serverEntrypoint` + +

+ +**类型:** `string | URL` +

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

+ +**类型:** `{ name: string; entrypoint: string | URL; }` +

+ +描述 [由集成添加的自定义客户端指令](#addclientdirective-选项)。 + +#### `name` + +

+ +**类型:** `string` +

+ +指令触发事件的自定义名称。 + +#### `entrypoint` + +

+ +**类型:** `string | URL` +

+ ### `HookParameters` -你可以通过将钩子的名称传递给 `HookParameters` 实用工具类型来获取钩子参数的类型。在以下示例中,输入了函数的 `options` 参数后,匹配到了 `astro:config:setup` 挂钩的参数: +你可以通过将钩子的名称传递给 `HookParameters` 实用工具类型来获取钩子参数的类型。 + +在以下示例中,输入了函数的 `options` 参数后,匹配到了 [`astro:config:setup` 钩子](#astroconfigsetup) 的参数: ```ts /HookParameters(?:<.+>)?/ import type { HookParameters } from 'astro'; @@ -1337,22 +1590,20 @@ function mySetup(options: HookParameters<'astro:config:setup'>) { } ``` -### `IntegrationResolvedRoute` 类型参考 +### `IntegrationResolvedRoute` + +具有重新映射属性的 [`RouteData`](#routedata) 子集。 ```ts -interface IntegrationResolvedRoute { +interface IntegrationResolvedRoute extends Pick< + RouteData, + 'generate' | 'params' | 'pathname' | 'segments' | 'type' | 'redirect' | 'origin' + > & { pattern: RouteData['route']; patternRegex: RouteData['pattern']; entrypoint: RouteData['component']; isPrerendered: RouteData['prerender']; redirectRoute?: IntegrationResolvedRoute; - generate: (data?: any) => string; - params: string[]; - pathname?: string; - segments: RoutePart[][]; - type: RouteType; - redirect?: RedirectConfig; - origin: 'internal' | 'external' | 'project'; } ``` @@ -1360,7 +1611,7 @@ interface IntegrationResolvedRoute {

-**类型:** `string` +**类型:** [`RouteData['route']`](#route)

允许你根据路由的路径来识别路由的类型。以下是与其格式(pattern)相关联的路径的一些示例: @@ -1372,7 +1623,7 @@ interface IntegrationResolvedRoute {

-**类型:** `RegExp` +**类型:** [`RouteData['pattern']`](#pattern-1)

允许你读取一个正则表达式,该表达式用于将输入的 URL 与请求的路由进行匹配。 @@ -1383,7 +1634,7 @@ interface IntegrationResolvedRoute {

-**类型:** `string` +**类型:** [`RouteData['component']`](#component)

源组件的 URL 路径名。 @@ -1392,7 +1643,7 @@ interface IntegrationResolvedRoute {

-**类型:** `boolean` +**类型:** [`RouteData['prerender']`](#prerender)

确定该路径是否使用 [按需渲染](/zh-cn/guides/on-demand-rendering/)。对于配置了以下内容的项目,该值将为 `true`: @@ -1408,6 +1659,41 @@ interface IntegrationResolvedRoute { 当 `IntegrationResolvedRoute.type` 的值为 `redirect` 时,该值将成为 `IntegrationResolvedRoute` 重定向的目标。否则,该值将为 undefined。 +### `RedirectConfig` + +

+ +**类型:** string | \{ status: ValidRedirectStatus; destination: string; \} +

+ +描述重定向的目标位置。该目标可以是一个字符串,或是一个包含状态码及其目标地址信息的对象。 + +### `RouteData` + +描述路由的相关信息。 + +#### `route` + +

+ +**类型:** `string` +

+ +定义当前路由模式。以下是一些与其模式关联的路径示例: + +* `src/pages/index.astro` 会是 `/` +* `src/pages/blog/[...slug].astro` 会是 `/blog/[...slug]` +* `src/pages/site/[blog]/[...slug].astro` 会是 `/site/[blog]/[...slug]` + +#### `component` + +

+ +**类型:** `string` +

+ +指定源组件的 URL。 + #### `generate()`

@@ -1417,10 +1703,10 @@ interface IntegrationResolvedRoute { 该函数提供路由的可选参数,使用路由的格式对它们进行插值,然后返回路由的路径名。 -例如,对于诸如 `/blog/[...id].astro` 这样的路由,`generate` 函数将返回如下内容: +例如,对于诸如 `/blog/[...id].astro` 这样的路由,`generate()` 函数将返回如下内容: ```js -console.log(generate({ id: 'presentation' })) // 将打印 `/blog/presentation` +generate({ id: 'presentation' }) // 将输出 `/blog/presentation` ``` #### `params` @@ -1441,11 +1727,31 @@ console.log(generate({ id: 'presentation' })) // 将打印 `/blog/presentation` 对于常规的路由,该值即为路径名。而对于使用了 [动态路由](/zh-cn/guides/routing/#动态路由) 的项目(例如:`[dynamic]` 或 `[...spread]`),该路径名将为 undefined。 +#### `distURL` + +

+ +**类型:** `URL[] | undefined`
+ +

+ +定义此路由生成的物理文件的路径。当路由未进行预渲染时,该值为 `undefined` 或空数组。 + +#### `pattern` +

+ +**类型:** `RegExp` +

+ +指定用于将输入 URL 与请求的路由进行匹配的正则表达式。 + +例如,给定一个 `[fruit]/about.astro` 路径,正则表达式将是 `/^/([^/]+?)/about/?$/`。使用 `pattern.test("banana/about")` 将会返回 `true`。 + #### `segments`

-**类型:** RoutePart[][] +**类型:** RoutePart[][]

允许你读取路由的 [`params`](#params),它有着额外的元数据。每个对象都包含了以下属性: @@ -1467,172 +1773,814 @@ console.log(generate({ id: 'presentation' })) // 将打印 `/blog/presentation`

-**类型:** `RouteType` +**类型:** [`RouteType`](#routetype) +

+ +允许你识别 [路由的类型](#routetype)。 + +#### `prerender` + +

+ +**类型:** `boolean`

-允许你辨认路由的类型。该值可能为: -* `page`:基于文件系统的路由,通常为 Astro 组件 -* `endpoint`:基于文件系统的路径,通常为暴露了端点方法的 JS 文件 -* `redirect`:一个指向另一个基于文件系统的路径 -* `fallback`:一个不存在于文件系统中的路径并且需要其他方式来处理,通常是中间件 +确定路由是使用 [按需渲染](/zh-cn/guides/on-demand-rendering/) 还是在构建时静态预渲染。 + +另请参阅路由参考中的 [`prerendered`](/zh-cn/reference/routing-reference/#prerender)。 #### `redirect`

-**类型:** RedirectConfig | undefined +*类型:** RedirectConfig | undefined

-允许你读取要重定向到的路径。它可以是一个字符串,也可以是一个携带了状态码和目的地信息的对象。 +允许你访问要重定向到的路由。 -#### `origin` +#### `redirectRoute`

-**类型:** `'internal' | 'external' | 'project'` +**类型:** `RouteData | undefined`

-确定该路径是来自于 Astro 内核(`internal`),或来自于集成(`external`),还是来自于用户项目(`project`)。 +指定当 [`RouteData.type`](#type) 为 `redirect` 时要重定向到的 `RouteData`。 -##### `IntegrationRouteData` 类型参考 +#### `fallbackRoutes` -:::caution -该类型已于 v5.0 被弃用。请使用 [`IntegrationResolvedRoute`](#integrationresolvedroute-类型参考) 作为代替。 -::: +

-集成中使用的是 `RouteData` 的较小版本。 +**类型:** `RouteData[]`
+ +

-```ts -interface IntegrationRouteData { - type: RouteType; - component: string; - pathname?: string; - pattern: RegExp; - params: string[]; - segments: { content: string; dynamic: boolean; spread: boolean; }[][]; - generate: (data?: any) => string; - prerender: boolean; - distURL?: URL[]; - redirect?: RedirectConfig; - redirectRoute?: IntegrationRouteData; -} -``` +定义一个 `RouteData` 列表,用于在 [`i18n.fallback`](/zh-cn/reference/configuration-reference/#i18nfallback) 包含多个语言区域设置时进行回退。 -#### `type` +#### `isIndex`

-**类型:** `RouteType` +**类型:** `boolean`

-允许你辨认路由的类型。该值可能为: -- `page`:基于文件系统的路由,通常为 Astro 组件 -- `endpoint`:基于文件系统的路由,通常为暴露了端点方法的 JS 文件 -- `redirect`:一个指向另一个基于文件系统的路由 -- `fallback`:一个不存在于文件系统的路由并且需要其他方式来处理,通常是中间件 +指定路由是否为目录索引(例如 `src/pages/index.astro`、`src/pages/blog/index.astro`)。 -#### `component` +#### `origin`

-**类型:** `string` +**类型:** `'internal' | 'external' | 'project'`
+

-允许你读取源组件的 URL 路径名。 +判断路由是来自 Astro 核心(`internal`)、集成(`external`)还是用户项目(`project`)。 -#### `pathname` +### `RoutePart`

-**类型:** `string | undefined` +**类型:** `{ content: string; dynamic: boolean; spread: boolean; }`

-对于常规的路由,该值即为路径名。而对于使用了 [动态路由](/zh-cn/guides/routing/#动态路由) 的项目(例如:`[dynamic]` 或 `[...spread]`),该路径名将为 undefined。 +描述一个路由段。 -#### `pattern` +#### `content`

-**类型:** `RegExp` +**类型:** `string`

-允许你读取一个正则表达式,该表达式用于将输入的 URL 与请求的路由进行匹配。 +指定路由的参数名称。例如: -例如,给定一个 `[fruit]/about.astro` 路径,将生成这样的格式:`/^\/([^/]+?)\/about\/?$/`。那么使用 `pattern.test("banana/about")` 就会返回 `true`。 +* `about.astro` 的名称是 `about` +* `[slug].astro` 的名称是 `slug` +* `[...id].astro` 的名称是 `id` -#### `params` +#### `dynamic`

-**类型:** `string[]` +**类型:** `boolean`

-允许你读取路由的 `params`。例如,当一个项目使用以下的 [动态路由](/zh-cn/guides/routing/#动态路由) `/pages/[lang]/[...slug].astro`时,该值将会是 `['lang', '...slug']`。 +路由是否是动态的。 -#### `segments` +#### `spread`

-**类型:** `{ content: string; dynamic: boolean; spread: boolean; }[][]` +**类型:** `boolean`

-允许你读取路由的 [`params`](#params-1),它有着额外的元数据。每个对象都包含了以下属性: -* `content`:`param` 的名称, -* `dynamic`:路由是否为动态, -* `spread`:动态路由是否使用了展开语法。 - -例如,以下的路由 `/pages/[lang]/index.astro` 将会输出这样的分段(segments)`[[ { content: 'lang', dynamic: true, spread: false } ]]`。 +动态路由是否使用展开语法。 -#### `generate()` +### `RouteType`

-**类型:** `(data?: any) => string` +**类型:** `'page' | 'endpoint' | 'redirect' | 'fallback'`

-该函数提供路由的可选参数,使用路由的格式对它们进行插值,然后返回路由的路径名。 +支持的路由类型的联合类型 -例如,对于诸如 `/blog/[...id].astro` 这样的路由,`generate` 函数将返回如下内容: +* `page`: 位于文件系统中的路由,通常是一个 Astro 组件 +* `endpoint`: 存在于文件系统中的路由,通常是一个暴露端点方法的 JS 文件 +* `redirect`: 一个路由指向文件系统中存在的另一个路由 +* `fallback`: 一个在文件系统中不存在的路由,需要通过其他方式处理,通常使用中间件 -```js -console.log(generate({ id: 'presentation' })) // 将打印 `/blog/presentation` -``` +### `SSRComponentMetadata` -#### `prerender` +

+ +**类型:** `{ propagation: PropagationHint; containsHead: boolean; }` +

+ +描述服务器渲染的组件的构建元数据。 + +#### `propagation`

-**类型:** `boolean` +**类型:** `'none' | 'self' | 'in-tree'`

-确定路由是否被预渲染。 +关于如何从该组件渲染 head 内容的描述,包括 Astro 运行时是否需要等待组件: +- `none`:该组件不传递 head 内容。 +- `self`:该组件追加 head 内容。 +- `in-tree`:该组件的依赖树中的另一个组件追加 head 内容。 -#### `distURL` +#### `containsHead`

-**类型:** `URL[] | undefined` +**类型:**: `boolean`

-该路由所发出的文件的物理路径。当路径 **没有** 被预渲染时,该值可能为 `undefined` 或空数组。 +确定组件是否包含头部内容。 -#### `redirect` +### `SSRLoadedRenderer`

-**类型:** RedirectConfig | undefined +**类型:** `{ name: string; clientEntrypoint?: string | URL; ssr: SSRLoadedRendererValue; }`

-允许你读取要重定向到的路径。它可以是一个字符串,也可以是一个携带了状态码和目的地信息的对象。 +描述服务器可用的渲染器。这是 [`AstroRenderer`](#astrorenderer) 的一个子集,包含额外的属性。 -#### `redirectRoute` +#### `ssr` + +

+ +**类型:** [`SSRLoadedRendererValue`](#ssrloadedrenderervalue) +

+ +定义此框架的服务器使用的函数和配置。 + +### `SSRLoadedRendererValue` + +包含从特定 UI 框架在服务器上渲染组件所需的函数和配置。 + +#### `name` + +

+ +**类型:** `string` +

+ +指定渲染器的名称标识符。 + +#### `check()` + +

+ +**类型:** `AsyncRendererComponentFn` +

+ +确定渲染器是否应该处理该组件。 + +#### `renderToStaticMarkup()` + +

+ +**类型:** `AsyncRendererComponentFn<{ html: string; attrs?: Record; }>` +

+ +在服务器上将框架组件渲染为静态 HTML 标记。 + +#### `supportsAstroStaticSlot` + +

+ +**类型:** `boolean`
+ +

+ +指示渲染器是否支持 Astro 的静态插槽优化。当为 true 时,Astro 会防止移除岛屿内的嵌套插槽。 + +#### `renderHydrationScript()` + +

+ +**类型:** `() => string`
+ +

+ +返回一个特定于框架的水合脚本,该脚本必须在使用此渲染器的第一个组件之前注入到 HTML 中。 + +### `SSRManifest` + +一个包含构建配置和项目元数据的对象,服务器适配器在运行时使用它来提供按需渲染的页面。 + +#### `hrefRoot` + +

+ +**类型:** `string`
+ +

+ +指定用于生成 URL 的根路径。 + +#### `adapterName` + +

+ +**类型:** `string` +

+ +定义用于按需渲染的 [服务器适配器](/zh-cn/guides/on-demand-rendering/#服务器适配器) 名称。 + +#### `routes` + +

+ +**类型:** `RouteInfo[]` +

+ +此项目中可用路由的信息列表。每个条目包含以下属性。 + +##### `routeData` + +

+ +**类型:** [`RouteData`](#routedata) +

+ +一个描述路由已知信息的对象。 + +##### `file` + +

+ +**类型:** `string` +

+ +指定构建路由入口点的文件路径。 + +##### `links` + +

+ +**类型:** `string[]` +

+ +定义此路由所需的 [HTML `link` 元素](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/link) 列表。 + +##### `scripts` + +

+ +**类型:** `Array<{ children: string; stage: string } | { type: 'inline' | 'external'; value: string }>` +

+ +定义与此路由关联的脚本列表。这包括具有 `children` 和 `stage` 属性的集成注入脚本,以及具有 `type` 和 `value` 属性的提升脚本。 + +##### `styles` + +

+ +**类型:** `Array<{ type: "inline"; content: string; } | { type: "external"; src: string; }>`
+ +

+ +定义与此路由关联的样式表列表。这包括内联样式和样式表 URL。 + +#### `site` + +

+ +**类型:** `string` +

+ +指定 [已配置的 `site`](/zh-cn/reference/configuration-reference/#site)。 + +#### `base` + +

+ +**类型:** `string` +

+ +指定 [已配置的 `base` 路径](/zh-cn/reference/configuration-reference/#base)。 + +#### `userAssetsBase` + +

+ +**类型:** `string | undefined`
+ +

+ +指定在开发模式下用于用户生成资源(如脚本和样式)的基础路径。 + +#### `trailingSlash` + +

+ +**类型:** [`AstroConfig['trailingSlash']`](/zh-cn/reference/configuration-reference/#trailingslash)
+ +

+ +指定开发模式和按需渲染页面中 [尾部斜杠的配置行为](/zh-cn/reference/configuration-reference/#trailingslash)。 + +#### `buildFormat` + +

+ +**类型:** [`NonNullable['format']`](/zh-cn/reference/configuration-reference/#buildformat)
+ +

+ +指定 [已配置的输出文件格式](/zh-cn/reference/configuration-reference/#buildformat)。 + +#### `compressHTML` + +

+ +**类型:** `boolean`
+ +

+ +确定 [项目配置中是否启用了 HTML 压缩](/zh-cn/reference/configuration-reference/#compresshtml)。 + +#### `assetsPrefix` + +

+ +**类型:** `string | ({ fallback: string; } & Record) | undefined`
+ +

+ +指定 [Astro 生成的资源链接的配置前缀](/zh-cn/reference/configuration-reference/#buildassetsprefix)。 + +#### `renderers` + +

+ +**类型:** SSRLoadedRenderer[] +

+ +服务器可使用的渲染器列表(例如 React、Vue、Svelte、MDX)。 + +#### `clientDirectives` + +

+ +**类型:** `Map`
+ +

+ +定义客户端指令名称(例如 `load`、`visible`)到其实现代码的映射。这包括 [内置客户端指令](/zh-cn/reference/directives-reference/#客户端指令) 和 [自定义客户端指令](/zh-cn/reference/directives-reference/#自定义客户端指令)。 + +#### `entryModules` + +

+ +**类型:** `Record` +

+ +定义入口点到其输出文件路径的映射。 + +#### `inlinedScripts` + +

+ +**类型:** `Map`
+ +

+ +定义脚本标识符到其内容的映射,用于将脚本内联到 HTML 输出中。 + +#### `assets` + +

+ +**类型:** `Set` +

+ +定义构建中所有资源文件的路径集合。 + +#### `componentMetadata` + +

+ +**类型:** Map\SSRComponentMetadata\>
+ +

+ +定义了组件标识符到其构建元数据的映射。每个条目包含有关 [`propagation`](#propagation) 行为以及是否包含头部元素的信息。 + +#### `pageModule` + +

+ +**类型:** `{ page: ImportComponentInstance; onRequest?: MiddlewareHandler; renderers: SSRLoadedRenderer[]; }`
+ +

+ +指定页面模块的相关信息。 + +##### `page()` + +

+ +**类型:** `() => Promise` +

+ +一个用于检索页面组件实例的函数。 + +##### `onRequest()` + +

+ +**类型:** [`MiddlewareHandler`](/zh-cn/reference/modules/astro-middleware/#middlewarehandler)
+ +

+ +在用户项目中定义的 [Astro 中间件函数](/zh-cn/reference/modules/astro-middleware/#middlewarehandler)。 + +##### `renderers` + +

+ +**类型:** SSRLoadedRenderer[] +

+ +服务器可以用于此页面的渲染器列表。 + +#### `pageMap` + +

+ +**类型:** Map\ Promise\<typeof pageModule\>\> +

+ +定义组件路径到其可导入实例的映射关系。 + +#### `serverIslandMap` + +

+ +**类型:** `Map Promise>`
+ +

+ +定义服务器岛屿ID到其组件实例的映射。 + +#### `serverIslandNameMap` + +

+ +**类型:** `Map`
+ +

+ +定义服务器岛屿组件路径到其指定名称的映射。 + +#### `key` + +

+ +**类型:** `Promise`
+ +

+ +确定用于加密服务器岛屿属性的 [加密密钥](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)。 + +#### `i18n` + +

+ +**类型:** `SSRManifestI18n | undefined`
+ +

+ +确定在项目中启用时已解析的 [`i18n` 配置](/zh-cn/reference/configuration-reference/#i18n)。 + +##### `strategy` + +

+ +**类型:** `"manual" | "pathname-prefix-always" | "pathname-prefix-other-locales" | "pathname-prefix-always-no-redirect" | "domains-prefix-always" | "domains-prefix-other-locales" | "domains-prefix-always-no-redirect"` +

+ +定义已配置的 [i18n 路由策略](/zh-cn/reference/configuration-reference/#i18nrouting)。这决定了如何在 URL 中处理语言区域设置以及是否发生重定向。 + +##### `locales` + +

+ +**类型:** `Locales` +

+ +确定 [项目中配置的受支持语言环境](/zh-cn/reference/configuration-reference/#i18nlocales) 设置列表。 + +##### `defaultLocale` + +

+ +**类型:** `string` +

+ +确定 [项目中配置的默认语言环境](/zh-cn/reference/configuration-reference/#i18ndefaultlocale)。 + +##### `fallback` + +

+ +**类型:** `Record | undefined` +

+ +确定 [在 `i18n.fallback `中配置](/zh-cn/reference/configuration-reference/#i18nfallback) 的语言环境到其回退语言环境的映射。 + +##### `fallbackType` + +

+ +**类型:** `"redirect" | "rewrite"` +

+ +确定 [项目的配置回退策略](/zh-cn/reference/configuration-reference/#i18nroutingfallbacktype)。 + +##### `domainLookupTable` + +

+ +**类型:** `Record` +

+ +[已配置域名](/zh-cn/reference/configuration-reference/#i18ndomains) 到其关联语言区域的映射。 + +#### `middleware` + +

+ +**类型:** () => Promise\<AstroMiddlewareInstance\> | AstroMiddlewareInstance
+ +

+ +定义一个实例来加载中间件。 + +#### `actions` + +

+ +**类型:** () => Promise\<\{ server: Record\ActionClient\>; \}\> | \{ server: Record\ActionClient\>; \}
+ +

+ +一个对象,或者一个返回对象的函数,该对象具有一个 `server` 属性,该属性将 action 名称映射到它们的可调用函数。 + +#### `checkOrigin` + +

+ +**类型:** `boolean`
+ +

+ +确定 [安全配置中是否启用了来源检查](/zh-cn/reference/configuration-reference/#securitycheckorigin)。 + +#### `allowedDomains` + +

+ +**类型:** Partial\<RemotePattern\>[] +

+ +指定在使用按需渲染时,传入请求 [所允许的主机模式配置列表](/zh-cn/reference/configuration-reference/#securityalloweddomains)。 + +#### `sessionConfig` + +

+ +**类型:** SessionConfig\ & \{ driverModule?: () => Promise\<\{ default: () => unstorage.Driver \}\>; }
+ +

+ +一个包含 [已解析的会话配置](/zh-cn/reference/configuration-reference/#session-选项) 和定义正在使用的驱动程序的附加属性的对象。 + +#### `cacheDir` + +

+ +**类型:** `string | URL`
+ +

+ +指定 [用于缓存构建产物的配置目录](/zh-cn/reference/configuration-reference/#cachedir)。 + +#### `srcDir` + +

+ +**类型:** `string | URL`
+ +

+ +指定 [Astro 读取站点的配置目录](/zh-cn/reference/configuration-reference/#srcdir)。 + +#### `outDir` + +

+ +**类型:** `string | URL`
+ +

+ +指定 [用于写入最终构建文件的配置目录](/zh-cn/reference/configuration-reference/#outdir)。 + +#### `publicDir` + +

+ +**类型:** `string | URL`
+ +

+ +指定 [用于静态资产的配置目录](/zh-cn/reference/configuration-reference/#publicdir)。 + +#### `buildClientDir` + +

+ +**类型:** `string | URL`
+ +

+ +确定客户端构建产物(例如 JavaScript、CSS)在构建目录中的输出路径。 + +#### `buildServerDir` + +

+ +**类型:** `string | URL`
+ +

+ +确定服务器端构建产物在构建目录中的输出路径。 + +#### `csp` + +

+ +**类型:** SSRManifestCSP | undefined
+ +

+ +一个描述内容安全策略配置的对象。 + +#### `internalFetchHeaders` + +

+ +**类型:** `Record`
+ +

+ +指定在渲染过程中自动添加到内部 fetch 请求的请求头。 + +### `SSRManifestCSP` + +

+ + +

+ +描述 [内容安全策略配置](/zh-cn/reference/experimental-flags/csp/)。 + +#### `cspDestination` + +

+ +**类型:** `'adapter' | 'meta' | 'header' | undefined` +

+ +指定 CSP 指令应作为 `meta` 元素注入、作为响应 `header` 注入,还是在 [`adapter` 支持设置响应头时](/zh-cn/reference/adapter-reference/#experimentalstaticheaders) 由适配器注入。 + +#### `algorithm` + +

+ +**类型:** `'SHA-256' | 'SHA-384' | 'SHA-512'` +

+ +指定 [配置的哈希函数](/zh-cn/reference/experimental-flags/csp/#algorithm)。 + +#### `scriptHashes` + +

+ +**类型:** `string[]` +

+ +指定项目脚本的生成哈希列表和外部脚本的 [用户提供哈希](/zh-cn/reference/experimental-flags/csp/#hashes)。 + +#### `scriptResources` + +

+ +**类型:** `string[]` +

+ +指定一个有效源列表,该列表结合了 [已配置的脚本资源](/zh-cn/reference/experimental-flags/csp/#resources) 和 [注入的脚本资源](/zh-cn/reference/experimental-flags/csp/#cspinsertstyleresource)。 + +#### `isStrictDynamic` + +

+ +**类型:** `boolean` +

+ +确定 [配置中是否启用了对动态脚本注入的支持](/zh-cn/reference/experimental-flags/csp/#strictdynamic)。 + +#### `styleHashes` + +

+ +**类型:** `string[]` +

+ +指定项目样式的生成哈希列表和外部样式的 [用户提供哈希列表](/zh-cn/reference/experimental-flags/csp/#hashes)。 + +#### `styleResources` + +

+ +**类型:** `string[]` +

+ +指定一个有效来源列表,该列表结合 [了已配置的样式资源](/zh-cn/reference/experimental-flags/csp/#resources) 和 [注入的样式资源](/zh-cn/reference/experimental-flags/csp/#cspinsertstyleresource)。 + +#### `directives` + +

+ +**类型:** `CspDirective[]` +

+ +指定特定内容类型的 [有效来源的配置列表](/zh-cn/reference/experimental-flags/csp/#directives)。 + +### `ValidRedirectStatus` + +

+ +**类型:** `301 | 302 | 303 | 307 | 308 | 300 | 304` +

+ +支持的重定向状态码的联合类型。 + +### 已弃用的类型导入 + +以下类型已被弃用,将在未来的主要版本中移除: + +#### `IntegrationRouteData` + +:::caution +此类型自 v5.0 版本起已弃用。请改用 [`IntegrationResolvedRoute`](#integrationresolvedroute)。 +::: + +在集成中使用的 [`RouteData`](#routedata) 的精简版本。 + +```ts +type IntegrationRouteData = Omit< + RouteData, + 'isIndex' | 'fallbackRoutes' | 'redirectRoute' | 'origin' +> & { + redirectRoute?: IntegrationRouteData; +}; +``` + +##### `redirectRoute`

**类型:** `IntegrationRouteData | undefined`

-当 `RouteData.type` 的值为 `redirect` 时,该值将包含要重定向到的路由的 `IntegrationRouteData`。否则,该值将为 undefined。 +当 [`RouteData.type`](#type) 的值为 `redirect` 时,该值将包含要重定向到的路由的 `IntegrationRouteData`。否则,该值将为 undefined。 ## 使用 `astro add` 安装