Astro 集成 API
Astro 集成只需几行代码即可为你的项目添加新功能和行为。
本参考页面适用于任何想要编写自己集成的开发者。要了解如何在你的项目中使用集成,请查阅我们的使用集成指南。
官方的 Astro 集成可以作为你构建自己集成时的参考。
快速 API 参考
标题为“快速 API 参考”的部分interface AstroIntegration { name: string; hooks: { 'astro:config:setup'?: (options: { config: AstroConfig; command: 'dev' | 'build' | 'preview' | 'sync'; isRestart: boolean; updateConfig: (newConfig: DeepPartial<AstroConfig>) => AstroConfig; addRenderer: (renderer: AstroRenderer) => void; addWatchFile: (path: URL | string) => void; addClientDirective: (directive: ClientDirectiveConfig) => void; addMiddleware: (middleware: AstroIntegrationMiddleware) => void; addDevToolbarApp: (entrypoint: DevToolbarAppEntry) => void; injectScript: (stage: InjectedScriptStage, content: string) => void; injectRoute: (injectedRoute: InjectedRoute) => void; createCodegenDir: () => URL; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:route:setup'?: (options: { route: RouteOptions; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:routes:resolved'?: (options: { routes: IntegrationResolvedRoute[]; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:config:done'?: (options: { config: AstroConfig; setAdapter: (adapter: AstroAdapter) => void; injectTypes: (injectedType: InjectedType) => URL; logger: AstroIntegrationLogger; buildOutput: 'static' | 'server'; }) => void | Promise<void>; 'astro:server:setup'?: (options: { server: vite.ViteDevServer; logger: AstroIntegrationLogger; toolbar: ReturnType<typeof getToolbarServerCommunicationHelpers>; refreshContent?: (options: RefreshContentOptions) => Promise<void>; }) => void | Promise<void>; 'astro:server:start'?: (options: { address: AddressInfo; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:server:done'?: (options: { logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:build:start'?: (options: { logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:build:setup'?: (options: { vite: vite.InlineConfig; pages: Map<string, PageBuildData>; target: 'client' | 'server'; updateConfig: (newConfig: vite.InlineConfig) => void; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:build:ssr'?: (options: { manifest: SerializedSSRManifest; entryPoints: Map<IntegrationRouteData, URL>; middlewareEntryPoint: URL | undefined; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:build:generated'?: (options: { dir: URL; logger: AstroIntegrationLogger; }) => void | Promise<void>; 'astro:build:done'?: (options: { pages: { pathname: string }[]; dir: URL; assets: Map<string, URL[]>; logger: AstroIntegrationLogger; }) => void | Promise<void>;
// ... any custom hooks from integrations };}
Astro 提供了钩子(hooks),集成可以实现这些钩子以在 Astro生命周期的特定部分执行代码。Astro 钩子在 IntegrationHooks
接口中定义,该接口是全局 Astro
命名空间的一部分。每个钩子都有一个logger
选项,允许你使用 Astro 的日志记录器来写入日志。
以下是 Astro 内置的钩子
astro:config:setup
标题为“astro:config:setup”的部分下一个钩子: astro:route:setup
何时: 初始化时,在 Vite 或 Astro 配置解析之前。
为何: 扩展项目配置。这包括更新 Astro 配置、应用 Vite 插件、添加组件渲染器以及向页面注入脚本。
'astro:config:setup'?: (options: { config: AstroConfig; command: 'dev' | 'build' | 'preview' | 'sync'; isRestart: boolean; updateConfig: (newConfig: DeepPartial<AstroConfig>) => AstroConfig; addRenderer: (renderer: AstroRenderer) => void; addClientDirective: (directive: ClientDirectiveConfig) => void; addMiddleware: (middleware: AstroIntegrationMiddleware) => void; addDevToolbarApp: (entrypoint: DevToolbarAppEntry) => void; addWatchFile: (path: URL | string) => void; injectScript: (stage: InjectedScriptStage, content: string) => void; injectRoute: (injectedRoute: InjectedRoute) => void; createCodegenDir: () => URL; logger: AstroIntegrationLogger;}) => void | Promise<void>;
config
选项
标题为“config 选项”的部分类型: AstroConfig
用户提供的 Astro 配置的只读副本。它在任何其他集成运行之前被解析。如果你需要所有集成完成其配置更新后的配置副本,请查看 astro:config:done
钩子。
command
选项
标题为“command 选项”的部分类型: 'dev' | 'build' | 'preview' | 'sync'
dev
- 项目通过astro dev
执行build
- 项目通过astro build
执行preview
- 项目通过astro preview
执行sync
- 项目通过astro sync
执行
isRestart
选项
标题为“isRestart 选项”的部分类型: boolean
astro@1.5.0
开发服务器启动时为 false
,触发重新加载时为 true
。用于检测此函数是否被多次调用。
updateConfig()
选项
标题为“updateConfig() 选项”的部分类型: (newConfig: DeepPartial<AstroConfig>) => AstroConfig;
一个用于更新用户提供的 Astro 配置的回调函数。你提供的任何配置都将与用户配置和其他集成的配置更新合并,所以你可以自由地省略一些键!
例如,假设你需要为用户的项目提供一个 Vite 插件
import bananaCSS from '@vitejs/official-banana-css-plugin';
export default { name: 'banana-css-integration', hooks: { 'astro:config:setup': ({ updateConfig }) => { updateConfig({ vite: { plugins: [bananaCSS()], } }) } }}
addRenderer()
选项
标题为“addRenderer() 选项”的部分类型: (renderer:
AstroRenderer
) => void;
示例: svelte
、 react
、 preact
、 vue
、 solid
一个用于添加组件框架渲染器(如 React、Vue、Svelte 等)的回调函数。你可以浏览上面的示例和类型定义以获取更高级的选项,但这里有两个主要选项需要注意
clientEntrypoint
- 每当使用你的组件时,在客户端执行的文件的路径。这主要用于通过 JS 渲染或注水(hydrate)你的组件。serverEntrypoint
- 每当使用你的组件时,在服务器端请求或静态构建期间执行的文件的路径。这应该将组件渲染为静态标记,并在适用时带有用于注水(hydration)的钩子。 React 的renderToString
回调是一个经典的例子。
添加于: astro@5.0.0
函数 clientEntrypoint
和 serverEntrypoint
接受一个 URL
。
addWatchFile()
选项
标题为“addWatchFile() 选项”的部分类型: (path: URL | string) => void
astro@1.5.0
如果你的集成依赖于某些 Vite 不会监视的配置文件,和/或需要完全重启开发服务器才能生效,请使用 addWatchFile
添加它。每当该文件更改时,Astro 开发服务器将重新加载(你可以使用 isRestart
检查何时发生重新加载)。
用法示例
// Must be an absolute path!addWatchFile('/home/user/.../my-config.json');addWatchFile(new URL('./ec.config.mjs', config.root));
addClientDirective()
选项
标题为“addClientDirective() 选项”的部分类型: (directive:
ClientDirectiveConfig
) => void;
astro@2.6.0
添加一个自定义客户端指令,用于 .astro
文件中。
请注意,指令的入口点仅通过 esbuild 进行打包,应保持较小体积,以免减慢组件的注水(hydration)速度。
用法示例
import { defineConfig } from 'astro/config';import clickDirective from './astro-click-directive/register.js'
// https://astro.js.cn/configexport default defineConfig({ integrations: [ clickDirective() ],});
/** * @type {() => import('astro').AstroIntegration} */export default () => ({ name: "client:click", hooks: { "astro:config:setup": ({ addClientDirective }) => { addClientDirective({ name: "click", entrypoint: "./astro-click-directive/click.js", }); }, },});
/** * Hydrate on first click on the window * @type {import('astro').ClientDirective} */export default (load, opts, el) => { window.addEventListener('click', async () => { const hydrate = await load() await hydrate() }, { once: true })}
你也可以在库的类型定义文件中为指令添加类型
import 'astro'declare module 'astro' { interface AstroClientDirectives { 'client:click'?: boolean }}
addDevToolbarApp()
选项
标题为“addDevToolbarApp() 选项”的部分类型: (entrypoint: DevToolbarAppEntry) => void;
astro@3.4.0
添加一个自定义的开发工具栏应用。
用法示例
import { defineConfig } from 'astro/config';import devToolbarIntegration from './astro-dev-toolbar-app/integration.js'
// https://astro.js.cn/configexport default defineConfig({ integrations: [ devToolbarIntegration() ],});
/** * @type {() => import('astro').AstroIntegration} */export default () => ({ name: "dev-toolbar-app", hooks: { "astro:config:setup": ({ addDevToolbarApp }) => { addDevToolbarApp({ entrypoint: "./astro-dev-toolbar-app/plugin.js", id: "my-plugin", name: "My Plugin" }); }, },});
/** * @type {import('astro').DevToolbarApp} */export default { id: "my-plugin", name: "My Plugin", icon: "<svg>...</svg>", init() { console.log("I'm a dev toolbar app!") },};
addMiddleware()
选项
标题为“addMiddleware() 选项”的部分类型: (middleware:
AstroIntegrationMiddleware
) => void;
astro@3.5.0
添加在每个请求上运行的中间件。它接受包含中间件的 entrypoint
模块,以及一个 order
来指定它应该在其他中间件之前(pre
)还是之后(post
)运行。
/** * @type {() => import('astro').AstroIntegration} */export default () => ({ name: "my-middleware-package", hooks: { "astro:config:setup": ({ addMiddleware }) => { addMiddleware({ entrypoint: '@my-package/middleware', order: 'pre' }); }, },});
中间件在一个包中定义,带有一个 onRequest
函数,就像用户定义的中间件一样。
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(async (context, next) => { if(context.url.pathname === '/some-test-path') { return Response.json({ ok: true }); }
return next();});
添加于: astro@5.0.0
该函数也接受一个 URL
作为 entrypoint
/** * @type {() => import('astro').AstroIntegration} */export default () => ({ name: "my-middleware-package", hooks: { "astro:config:setup": ({ addMiddleware }) => { addMiddleware({ entrypoint: new URL('./middleware.js', import.meta.url), order: 'pre' }); }, },});
injectRoute()
选项
标题为“injectRoute() 选项”的部分类型: ({ pattern: string; entrypoint: string | URL; prerender?: boolean }) => void;
一个用于向 Astro 项目中注入路由的回调函数。注入的路由可以是 .astro
页面或 .js
和 .ts
路由处理程序。
injectRoute
接受一个带有 pattern
和 entrypoint
的对象。
pattern
- 路由在浏览器中输出的位置,例如/foo/bar
。`pattern` 可以使用 Astro 的文件路径语法来表示动态路由,例如/foo/[bar]
或/foo/[...bar]
。请注意,在pattern
中不需要文件扩展名。entrypoint
- 一个裸模块说明符,指向处理pattern
中所表示路由的.astro
页面或.js
/.ts
路由处理程序。prerender
- 一个布尔值,用于在 Astro 无法检测到你的prerender
导出时进行设置。
用法示例
标题为“用法示例”的部分injectRoute({ // Use Astro’s pattern syntax for dynamic routes. pattern: '/subfolder/[dynamic]', // Use relative path syntax for a local route. entrypoint: './src/dynamic-page.astro', // Use only if Astro can't detect your prerender export prerender: false});
对于设计用于安装在其他项目中的集成,请使用其包名来引用路由入口点。以下示例展示了一个发布到 npm 上的名为 @fancy/dashboard
的包注入了一个仪表盘路由
injectRoute({ pattern: '/fancy-dashboard', entrypoint: '@fancy/dashboard/dashboard.astro'});
当将你的包(在本例中为 @fancy/dashboard
)发布到 npm 时,你必须在 package.json
中导出 dashboard.astro
{ "name": "@fancy/dashboard", // ... "exports": { "./dashboard.astro": "./dashboard.astro" }}
添加于: astro@5.0.0
该函数也接受一个 URL
作为 entrypoint
injectRoute({ pattern: '/fancy-dashboard', entrypoint: new URL('./dashboard.astro', import.meta.url)});
injectScript()
选项
标题为“injectScript() 选项”的部分类型: (stage: InjectedScriptStage, content: string) => void;
一个用于在每个页面上注入一段 JavaScript 内容字符串的回调函数。
stage
表示该脚本(content
)应如何插入。一些阶段允许不经修改地插入脚本,而另一些阶段则允许在 Vite 的打包步骤中进行优化
-
"head-inline"
:注入到每个页面的<head>
中的一个 script 标签内。不会被 Vite 优化或解析。 -
"before-hydration"
:在注水脚本运行之前,在客户端导入。会被 Vite 优化和解析。 -
"page"
:类似于head-inline
,但注入的代码段由 Vite 处理,并与页面上 Astro 组件内定义的任何其他<script>
标签一起打包。该脚本将在最终页面输出中通过<script type="module">
加载,并由 Vite 进行优化和解析。 -
"page-ssr"
:在每个 Astro 页面组件的 frontmatter 中作为单独的模块导入。因为这个阶段会导入你的脚本,所以Astro
全局变量不可用,你的脚本只会在import
首次被求值时运行一次。page-ssr
阶段的主要用途是向每个页面注入一个 CSSimport
,以便由 Vite 进行优化和解析injectScript('page-ssr', 'import "global-styles.css";');
createCodegenDir
标题为“createCodegenDir”的部分类型: () => URL;
astro@5.0.0
一个创建 <root>/.astro/integrations/<normalized_integration_name>
文件夹并返回其路径的函数。
它允许你拥有一个专用文件夹,从而避免与另一个集成或 Astro 本身发生冲突。这个目录是通过调用此函数创建的,因此可以直接向其中写入文件
import { writeFileSync } from 'node:fs'
const integration = { name: 'my-integration', hooks: { 'astro:config:setup': ({ createCodegenDir }) => { const codegenDir = createCodegenDir() writeFileSync(new URL('cache.json', codegenDir), '{}', 'utf-8') } }}
astro:route:setup
标题为“astro:route:setup”的部分
添加于: astro@4.14.0
上一个钩子: astro:config:setup
下一个钩子: astro:routes:resolved
何时: 在 astro build
中,打包开始之前。在 astro dev
中,在构建模块图时以及每当基于文件的路由发生变化(添加/删除/更新)时。
为何: 在构建时或请求时为路由设置选项,例如启用按需服务器渲染。
'astro:route:setup'?: (options: { route: RouteOptions; logger: AstroIntegrationLogger;}) => void | Promise<void>;
route
选项
标题为“route 选项”的部分类型: RouteOptions
一个包含 component
属性来识别路由的对象,以及以下附加值,允许你配置生成的路由:prerender
。
route.component
标题为“route.component”的部分类型: string
astro@4.14.0
component
属性指示将在该路由上渲染的入口点。你可以在路由构建之前访问此值,以便为该页面配置按需服务器渲染。
route.prerender
标题为“route.prerender”的部分类型: boolean
默认值: undefined
astro@4.14.0
prerender
属性用于为一个路由配置按需服务器渲染。如果路由文件包含一个明确的 export const prerender
值,该值将被用作默认值,而不是 undefined
。
import { defineConfig } from 'astro/config';
export default defineConfig({ integrations: [setPrerender()],});
function setPrerender() { return { name: 'set-prerender', hooks: { 'astro:route:setup': ({ route }) => { if (route.component.endsWith('/blog/[slug].astro')) { route.prerender = true; } }, }, };}
如果在运行所有钩子后的最终值为 undefined
,路由将根据 output
选项回退到预渲染默认值:static
模式下为预渲染,server
模式下为按需渲染。
astro:routes:resolved
标题为“astro:routes:resolved”的部分
添加于: astro@5.0.0
上一个钩子: astro:route:setup
下一个钩子: astro:config:done
(仅在设置期间)
何时: 在 astro dev
中,它也会在每次基于文件的路由发生更改(添加/删除/更新)时运行。
为何: 访问路由及其元数据
'astro:routes:resolved'?: (options: { routes: IntegrationResolvedRoute[]; logger: AstroIntegrationLogger;}) => void | Promise<void>;
routes
选项
标题为“routes 选项”的部分类型: IntegrationResolvedRoute[]
所有路由及其关联元数据的列表。
用法示例
const integration = () => { return { name: 'my-integration', hooks: { 'astro:routes:resolved': ({ routes }) => { const projectRoutes = routes.filter(r => r.origin === 'project').map(r => r.pattern)
console.log(projectRoutes) }, } }}
astro:config:done
标题为“astro:config:done”的部分上一个钩子: astro:routes:resolved
下一个钩子: 在“dev”模式下运行时为 astro:server:setup
,或在生产构建期间为 astro:build:start
何时: 在 Astro 配置已解析并且其他集成已运行其 astro:config:setup
钩子之后。
为何: 获取最终配置以在其他钩子中使用。
'astro:config:done'?: (options: { config: AstroConfig; setAdapter: (adapter: AstroAdapter) => void; injectTypes: (injectedType: InjectedType) => URL; logger: AstroIntegrationLogger; buildOutput: 'static' | 'server';}) => void | Promise<void>;
config
选项
标题为“config 选项”的部分类型: AstroConfig
用户提供的 Astro 配置的只读副本。它在其他集成运行之后被解析。
setAdapter()
选项
标题为“setAdapter() 选项”的部分类型: (adapter: AstroAdapter) => void;
使集成成为一个适配器。请在适配器 API中阅读更多信息。
injectTypes()
选项
标题为“injectTypes() 选项”的部分类型: (injectedType: { filename: string; content: string }) => URL
astro@4.14.0
允许你通过添加一个新的 *.d.ts
文件来向用户的项目中注入类型。
filename
属性将用于在 /.astro/integrations/<normalized_integration_name>/<normalized_filename>.d.ts
生成一个文件,并且必须以 ".d.ts"
结尾。
content
属性将创建文件的内容,并且必须是有效的 TypeScript。
此外,injectTypes()
会返回一个指向规范化路径的 URL,以便你以后可以覆盖其内容,或以任何你想要的方式操作它。
const path = injectTypes({ filename: "types.d.ts", content: "declare module 'virtual:integration' {}"})console.log(path) // URL
buildOutput
选项
标题为“buildOutput 选项”的部分类型: 'static' | 'server'
astro@5.0.0
允许你根据用户项目的输出来调整你的集成逻辑。
astro:server:setup
标题为“astro:server:setup”的部分上一个钩子: astro:config:done
下一个钩子: astro:server:start
何时: 在“dev”模式下创建 Vite 服务器之后,但在 listen()
事件触发之前。 更多信息请参见 Vite 的 createServer API。
为何: 更新 Vite 服务器选项和中间件,或启用对内容层刷新的支持。
'astro:server:setup'?: (options: { server: vite.ViteDevServer; logger: AstroIntegrationLogger; toolbar: ReturnType<typeof getToolbarServerCommunicationHelpers>; refreshContent: (options: { loaders?: Array<string>; context?: Record<string, any>; }) => Promise<void>;}) => void | Promise<void>;
server
选项
标题为“server 选项”的部分类型: ViteDevServer
在“dev”模式下使用的 Vite 服务器的可变实例。例如,我们的 Partytown 集成用它来将 Partytown 服务器作为中间件注入。
export default { name: 'partytown', hooks: { 'astro:server:setup': ({ server }) => { server.middlewares.use( function middleware(req, res, next) { // handle requests } ); } }}
toolbar
选项
标题为“toolbar 选项”的部分类型: ReturnType<typeof getToolbarServerCommunicationHelpers>
astro@4.7.0
一个提供回调函数的对象,用于与开发工具栏进行交互
on()
标题为“on()”的部分类型: <T>(event: string, callback: (data: T) => void) => void
一个函数,接受一个事件名称作为第一个参数,一个回调函数作为第二个参数。这允许你从开发工具栏应用接收与该事件相关联的数据的消息。
onAppInitialized()
标题为“onAppInitialized()”的部分类型: (appId: string, callback: (data: Record<string, never>) => void) => void
当开发工具栏应用初始化时触发的函数。第一个参数是已初始化的应用的 ID。第二个参数是当应用初始化时要运行的回调函数。
onAppToggled()
标题为“onAppToggled()”的部分类型: (appId: string, callback: (data: { state: boolean; }) => void) => void
当开发工具栏应用被打开或关闭时触发的函数。第一个参数是被切换的应用的 ID。第二个参数是一个回调函数,提供在应用切换时要执行的状态。
send()
标题为“send()”的部分类型: <T>(event: string, payload: T) => void
一个向开发工具栏发送消息的函数,应用可以监听这个消息。它接受一个事件名称作为第一个参数,一个有效载荷作为第二个参数,有效载荷可以是任何可序列化的数据。
refreshContent()
选项
标题为“refreshContent() 选项”的部分类型: (options: { loaders?: Array<string>; context?: Record<string, any>; }) => Promise<void>
astro@5.0.0
一个供集成在 astro dev
期间触发内容层更新的函数。例如,这可以用于在开发期间注册一个 webhook 端点,或者打开一个到 CMS 的套接字(socket)以监听变更。
默认情况下,refreshContent
将刷新所有内容集合。你可以选择性地传递一个 loaders
属性,它是一个加载器名称的数组。如果提供了该属性,则只有使用这些加载器的内容集合才会被刷新。例如,CMS 集成可以使用此属性仅刷新其自己的内容集合。
你也可以向加载器传递一个 context
对象。这可以用来传递任意数据,比如 webhook 的主体,或者来自 websocket 的事件。
{ name: 'my-integration', hooks: { 'astro:server:setup': async ({ server, refreshContent }) => { // Register a dev server webhook endpoint server.middlewares.use('/_refresh', async (req, res) => { if(req.method !== 'POST') { res.statusCode = 405 res.end('Method Not Allowed'); return } let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', async () => { try { const webhookBody = JSON.parse(body); await refreshContent({ context: { webhookBody }, loaders: ['my-loader'] }); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ message: 'Content refreshed successfully' })); } catch (error) { res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Failed to refresh content: ' + error.message })); } }); }); } }}
然后加载器可以访问 refreshContextData
属性来获取 webhook 的主体。更多信息请参见 refreshContextData
属性。
astro:server:start
标题为“astro:server:start”的部分上一个钩子: astro:server:setup
下一个钩子: astro:server:done
何时: 在服务器的 listen()
事件触发之后。
为何: 在指定地址拦截网络请求。如果你打算将此地址用于中间件,请考虑改用 astro:server:setup
。
'astro:server:start'?: (options: { address: AddressInfo; logger: AstroIntegrationLogger;}) => void | Promise<void>;
address
选项
标题为“address 选项”的部分类型: AddressInfo
Node.js Net 模块提供的地址、族和端口号。
astro:server:done
标题为“astro:server:done”的部分上一个钩子: astro:server:start
何时: 在开发服务器关闭之后。
为何: 运行你在 astro:server:setup
或 astro:server:start
钩子中可能触发的任何清理事件。
'astro:server:done'?: (options: { logger: AstroIntegrationLogger;}) => void | Promise<void>;
astro:build:start
标题为“astro:build:start”的部分上一个钩子: astro:config:done
下一个钩子: astro:build:setup
何时: 在 astro:config:done
事件之后,但在生产构建开始之前。
为何: 设置生产构建期间所需的任何全局对象或客户端。这也可以扩展适配器 API中的构建配置选项。
'astro:build:start'?: (options: { logger: AstroIntegrationLogger;}) => void | Promise<void>;
astro:build:setup
标题为“astro:build:setup”的部分上一个钩子: astro:build:start
下一个钩子: astro:build:ssr
何时: 在 astro:build:start
钩子之后,构建前立即运行。
为何: 此时,构建的 Vite 配置已完全构建,这是你修改它的最后机会。例如,这对于覆盖某些默认值很有用。如果你不确定应该使用此钩子还是 astro:build:start
,请改用 astro:build:start
。
'astro:build:setup'?: (options: { vite: vite.InlineConfig; pages: Map<string, PageBuildData>; target: 'client' | 'server'; updateConfig: (newConfig: vite.InlineConfig) => void; logger: AstroIntegrationLogger;}) => void | Promise<void>;
vite
选项
标题为“vite 选项”的部分类型: InlineConfig
一个允许你访问构建中使用的 Vite 配置的对象。
如果你需要在集成中访问配置选项,这将非常有用
export default { name: 'my-integration', hooks: { 'astro:build:setup': ({ vite }) => { const { publicDir, root } = vite; }, }}
pages
选项
标题为“pages 选项”的部分类型: Map<string, PageBuildData>
一个 Map
,其中键是页面列表,值是它们的构建数据。
这可以用来在路由匹配某个标准时执行操作
export default { name: 'my-integration', hooks: { 'astro:build:setup': ({ pages }) => { pages.forEach((data) => { if (data.route.pattern.test("/blog")) { console.log(data.route.type); } }); }, }}
target
选项
标题为“target 选项”的部分类型: 'client' | 'server'
构建分为两个不同的阶段:client
和 server
。这个选项允许你确定当前的构建阶段。
这可以用来仅在特定阶段执行操作
export default { name: 'my-integration', hooks: { 'astro:build:setup': ({ target }) => { if (target === "server") { // do something in server build phase } }, }}
updateConfig()
选项
标题为“updateConfig() 选项”的部分类型: (newConfig: InlineConfig) => void
一个回调函数,用于更新构建中使用的 Vite 选项。你提供的任何配置都将与用户配置和其他集成的配置更新合并,所以你可以自由地省略一些键!
例如,这可以用于向用户的项目提供一个插件
import awesomeCssPlugin from 'awesome-css-vite-plugin';
export default { name: 'my-integration', hooks: { 'astro:build:setup': ({ updateConfig }) => { updateConfig({ plugins: [awesomeCssPlugin()], }) } }}
astro:build:ssr
标题为“astro:build:ssr”的部分上一个钩子: astro:build:setup
下一个钩子: astro:build:generated
何时: 生产 SSR 构建完成之后。
为何: 访问 SSR 清单和发出的入口点映射。这在插件或集成中创建自定义 SSR 构建时很有用。
entryPoints
将页面路由映射到构建后发出的物理文件;middlewareEntryPoint
是中间件文件的文件系统路径;
'astro:build:ssr'?: (options: { manifest: SerializedSSRManifest; entryPoints: Map<IntegrationRouteData, URL>; middlewareEntryPoint: URL | undefined; logger: AstroIntegrationLogger;}) => void | Promise<void>;
manifest
选项
标题为“manifest 选项”的部分允许你通过访问 SSR 清单来创建自定义构建。
export default { name: 'my-integration', hooks: { 'astro:build:ssr': ({ manifest }) => { const { i18n } = manifest; if (i18n?.strategy === "domains-prefix-always") { // do something } }, },}
entryPoints
选项
标题为“entryPoints 选项”的部分类型: Map<IntegrationRouteData, URL>
astro@2.7.0
一个已发出的入口点的 Map
,以 IntegrationRouteData
为键,物理文件 URL 为值。
export default { name: 'my-integration', hooks: { 'astro:build:ssr': ({ entryPoints }) => { entryPoints.forEach((url) => { console.log(url.href); }); }, },}
middlewareEntryPoint
选项
标题为“middlewareEntryPoint 选项”的部分类型: URL | undefined
astro@2.8.0
公开中间件文件路径。
export default { name: 'my-integration', hooks: { 'astro:build:ssr': ({ middlewareEntryPoint }) => { if (middlewareEntryPoint) { // do some operations if a middleware exist } }, },}
astro:build:generated
标题为“astro:build:generated”的部分
添加于: astro@1.3.0
上一个钩子: astro:build:ssr
下一个钩子: astro:build:done
何时: 在静态生产构建完成生成路由和资产之后。
为何: 在构建产物被清理之前访问生成的路由和资产。这是一个非常不常见的用例。我们建议使用 astro:build:done
,除非你真的需要在清理前访问生成的文件。
'astro:build:generated'?: (options: { dir: URL; logger: AstroIntegrationLogger;}) => void | Promise<void>;
dir
选项
标题为“dir 选项”的部分类型: URL
一个指向构建输出目录的 URL 路径。请注意,如果你需要一个有效的绝对路径字符串,你应该使用 Node 的内置 fileURLToPath
工具。
import { fileURLToPath } from 'node:url';
export default { name: 'my-integration', hooks: { 'astro:build:generated': ({ dir }) => { const outFile = fileURLToPath(new URL('./my-integration.json', dir)); } }}
astro:build:done
标题为“astro:build:done”的部分上一个钩子: astro:build:generated
何时: 在生产构建(SSG 或 SSR)完成之后。
为何: 访问生成的路由和资产以进行扩展(例如,将内容复制到生成的 /assets
目录中)。如果你计划转换生成的资产,我们建议探索 Vite 插件 API 并通过 astro:config:setup
进行配置。
'astro:build:done'?: (options: { pages: { pathname: string }[]; dir: URL; /** @deprecated Use the `assets` map and the new `astro:routes:resolved` hook */ routes: IntegrationRouteData[]; assets: Map<string, URL[]>; logger: AstroIntegrationLogger;}) => void | Promise<void>;
dir
选项
标题为“dir 选项”的部分类型: URL
一个指向构建输出目录的 URL 路径。请注意,如果你需要一个有效的绝对路径字符串,你应该使用 Node 的内置 fileURLToPath
工具。
import { writeFile } from 'node:fs/promises';import { fileURLToPath } from 'node:url';
export default function myIntegration() { return { hooks: { 'astro:build:done': async ({ dir }) => { const metadata = await getIntegrationMetadata(); // Use fileURLToPath to get a valid, cross-platform absolute path string const outFile = fileURLToPath(new URL('./my-integration.json', dir)); await writeFile(outFile, JSON.stringify(metadata)); } } }}
routes
选项
标题为“routes 选项”的部分此属性自 v5.0 起已弃用。请查看迁移指南。
所有生成的路由及其关联元数据的列表。
你可以在下面参考完整的 IntegrationRouteData
类型,但最常见的属性是
component
- 相对于项目根目录的输入文件路径pathname
- 输出文件 URL(对于使用[dynamic]
和[...spread]
参数的路由为 undefined)
assets
选项
标题为“assets 选项”的部分类型: Map<string, URL[]>
astro@5.0.0
包含输出文件路径的 URL,按 IntegrationResolvedRoute
的 pattern
属性分组。
pages
选项
标题为“pages 选项”的部分类型: { pathname: string }[]
所有已生成页面的列表。它是一个只有一个属性的对象。
pathname
- 页面的最终路径。
自定义钩子
标题为“自定义钩子”的部分通过全局增强扩展 IntegrationHooks
接口,可以为集成添加自定义钩子。
declare global { namespace Astro { export interface IntegrationHook { 'your:hook': (params: YourHookParameters) => Promise<void> } }}
Astro 保留了 astro:
前缀用于未来的内置钩子。在命名你的自定义钩子时,请选择一个不同的前缀。
集成类型参考
标题为“集成类型参考”的部分AstroIntegrationLogger
标题为“AstroIntegrationLogger”的部分Astro 日志记录器的一个实例,可用于写入日志。此日志记录器使用通过 CLI 配置的相同日志级别。
可用方法,用于向终端写入信息
logger.info("消息")
;logger.warn("消息")
;logger.error("消息")
;logger.debug("消息")
;
所有消息都会前置一个标签,该标签的值与集成的名称相同。
import type { AstroIntegration } from "astro";export function formatIntegration(): AstroIntegration { return { name: "astro-format", hooks: { "astro:build:done": ({ logger }) => { // do something logger.info("Integration ready."); } } }}
上面的例子会记录一条包含所提供的 info
消息的日志
[astro-format] Integration ready.
要使用不同的标签记录某些消息,请使用 .fork
方法来指定一个不同于默认 name
的备用标签
import type { AstroIntegration } from "astro";export function formatIntegration(): AstroIntegration { return { name: "astro-format", hooks: { "astro:config:done": ({ logger }) => { // do something logger.info("Integration ready."); }, "astro:build:done": ({ logger }) => { const buildLogger = logger.fork("astro-format/build"); // do something buildLogger.info("Build finished.") } } }}
上面的示例默认会生成带有 [astro-format]
的日志,在指定时则会生成带有 [astro-format/build]
的日志
[astro-format] Integration ready.[astro-format/build] Build finished.
HookParameters
标题为“HookParameters”的部分你可以通过将钩子的名称传递给 HookParameters
工具类型来获取钩子参数的类型。在下面的示例中,一个函数的 options
参数的类型被设置为与 astro:config:setup
钩子的参数相匹配
import type { HookParameters } from 'astro';
function mySetup(options: HookParameters<'astro:config:setup'>) { options.updateConfig({ /* ... */ });}
IntegrationResolvedRoute
类型参考
标题为“IntegrationResolvedRoute 类型参考”的部分interface IntegrationResolvedRoute { 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';}
pattern
标题为“pattern”的部分类型: string
允许你根据路径识别路由类型。以下是一些路径及与其关联的模式的示例
src/pages/index.astro
对应/
src/pages/blog/[...slug].astro
对应/blog/[...slug]
src/pages/site/[blog]/[...slug].astro
对应/site/[blog]/[...slug]
patternRegex
标题为“patternRegex”的部分类型: RegExp
允许你访问一个用于将输入 URL 与请求路由进行匹配的正则表达式。
例如,对于路径 [fruit]/about.astro
,其正则表达式将是 /^\/([^/]+?)\/about\/?$/
。使用 pattern.test("banana/about")
将返回 true
。
entrypoint
标题为“entrypoint”的部分类型: string
源组件的 URL 路径名。
isPrerendered
标题为“isPrerendered”的部分类型: boolean
确定路由是否使用按需渲染。对于配置了以下选项的项目,该值为 true
output: 'static'
,且路由未导出const prerender = true
output: 'server'
,且路由导出了const prerender = false
redirectRoute
标题为“redirectRoute”的部分类型: IntegrationResolvedRoute | undefined
当 IntegrationResolvedRoute.type
的值为 redirect
时,该值将是重定向目标的 IntegrationResolvedRoute
。否则,该值为 undefined。
generate()
标题为“generate()”的部分类型: (data?: any) => string
一个函数,它接收路由的可选参数,将它们与路由模式进行插值,并返回路由的路径名。
例如,对于像 /blog/[...id].astro
这样的路由,generate
函数可以返回
console.log(generate({ id: 'presentation' })) // will log `/blog/presentation`
params
标题为“params”的部分类型: string[]
允许你访问路由的 params
。例如,当一个项目使用以下动态路由 /pages/[lang]/[...slug].astro
时,其值将是 ['lang', '...slug']
。
pathname
标题为“pathname”的部分类型: string | undefined
对于常规路由,该值将是此路由提供服务的 URL 路径名。当项目使用动态路由(即 [dynamic]
或 [...spread]
)时,pathname 将为 undefined。
segments
标题为“segments”的部分类型: RoutePart[][]
允许你访问带有附加元数据的路由 params
。每个对象包含以下属性
content
:param
的名称,dynamic
:路由是否为动态路由,spread
:动态路由是否使用扩展语法。
例如,以下路由 /pages/[blog]/[...slug].astro
将输出以下 segments
[ [ { content: 'pages', dynamic: false, spread: false } ], [ { content: 'blog', dynamic: true, spread: false } ], [ { content: '...slug', dynamic: true, spread: true } ]]
type
标题为“type”的部分类型: RouteType
允许你识别路由的类型。可能的值有
page
:存在于文件系统中的路由,通常是一个 Astro 组件endpoint
:存在于文件系统中的路由,通常是暴露端点方法的 JS 文件redirect
:指向文件系统中另一个路由的路由fallback
:一个不存在于文件系统中的路由,需要通过其他方式处理,通常是中间件
redirect
标题为“redirect”的部分类型: RedirectConfig | undefined
允许你访问要重定向到的路由。这可以是一个字符串,也可以是一个包含状态码及其目标信息的对象。
origin
标题为“origin”的部分类型: 'internal' | 'external' | 'project'
确定一个路由是来自 Astro 核心(internal
)、一个集成(external
)还是用户的项目(project
)。
IntegrationRouteData
类型参考
标题为“IntegrationRouteData 类型参考”的部分此类型自 v5.0 起已弃用。请改用 IntegrationResolvedRoute
。
这是 RouteData
的一个精简版本,用于集成中。
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;}
type
标题为“type”的部分类型: RouteType
允许你识别路由的类型。其值可以是
page
:存在于文件系统中的路由,通常是一个 Astro 组件endpoint
:存在于文件系统中的路由,通常是暴露端点方法的 JS 文件redirect
:一个指向文件系统中另一个路由的路由fallback
:一个不存在于文件系统中的路由,需要通过其他方式处理,通常是中间件
component
标题为“component”的部分类型: string
允许你访问源组件的 URL 路径名。
pathname
标题为“pathname”的部分类型: string | undefined
对于常规路由,该值将是此路由提供服务的 URL 路径名。当项目使用动态路由(即 [dynamic]
或 [...spread]
)时,pathname 将为 undefined。
pattern
标题为“pattern”的部分类型: RegExp
允许你访问一个用于将输入 URL 与请求路由进行匹配的正则表达式。
例如,对于路径 [fruit]/about.astro
,其正则表达式将是 /^\/([^/]+?)\/about\/?$/
。使用 pattern.test("banana/about")
将返回 true
。
params
标题为“params”的部分类型: string[]
允许你访问路由的 params
。例如,当一个项目使用以下动态路由 /pages/[lang]/[...slug].astro
时,其值将是 ['lang', '...slug']
。
segments
标题为“segments”的部分类型: { content: string; dynamic: boolean; spread: boolean; }[][]
允许你访问带有附加元数据的路由 params
。每个对象包含以下属性
content
:param
,dynamic
:路由是否为动态路由,spread
:动态路由是否使用扩展语法。
例如,以下路由 /pages/[lang]/index.astro
将输出 segments [[ { content: 'lang', dynamic: true, spread: false } ]]
。
generate()
标题为“generate()”的部分类型: (data?: any) => string
一个函数,它接收路由的可选参数,将它们与路由模式进行插值,并返回路由的路径名。
例如,对于像 /blog/[...id].astro
这样的路由,generate
函数可以返回
console.log(generate({ id: 'presentation' })) // will log `/blog/presentation`
prerender
标题为“prerender”的部分类型: boolean
确定路由是否被预渲染。
distURL
标题为“distURL”的部分类型: URL[] | undefined
此路由生成的物理文件的路径。当路由未预渲染时,该值为 undefined
或空数组。
redirect
标题为“redirect”的部分类型: RedirectConfig | undefined
允许你访问要重定向到的路由。这可以是一个字符串,也可以是一个包含状态码及其目标信息的对象。
redirectRoute
标题为“redirectRoute”的部分类型: IntegrationRouteData | undefined
当 RouteData.type
的值为 redirect
时,该值将包含要重定向到的路由的 IntegrationRouteData
。否则,该值为 undefined。
允许使用 astro add
安装
标题为“允许使用 astro add 安装”的部分astro add
命令允许用户轻松地将集成和适配器添加到他们的项目中。如果你希望你的集成能通过此工具安装,请将 astro-integration
添加到你的 package.json
文件的 keywords
字段中。
{ "name": "example", "keywords": ["astro-integration"],}
一旦你将你的集成发布到 npm,运行 astro add example
将会安装你的包以及在 package.json
中指定的任何同级依赖。这也会将你的集成应用到用户的 astro.config.*
文件中,如下所示
import { defineConfig } from 'astro/config';import example from 'example';
export default defineConfig({ integrations: [example()],})
这假设你的集成定义是 1) 一个 default
导出和 2) 一个函数。在添加 astro-integration
关键字之前,请确保这一点!
集成顺序
标题为“集成排序”的部分所有集成都按照它们配置的顺序运行。例如,对于用户 astro.config.*
文件中的数组 [react(), svelte()]
,react
将在 svelte
之前运行。
理想情况下,你的集成应该能以任何顺序运行。如果这不可能,我们建议你在文档中说明你的集成需要在用户的 integrations
配置数组中排在最前或最后。
将集成组合成预设
标题为“将集成组合成预设”的部分一个集成也可以写成多个较小集成的集合。我们称这些集合为预设(presets)。预设不是创建一个返回单个集成对象的工厂函数,而是返回一个集成对象的数组。这对于用多个集成构建复杂功能非常有用。
integrations: [ // Example: where examplePreset() returns: [integrationOne, integrationTwo, ...etc] examplePreset()]
社区资源
标题为“社区资源”的部分- 构建你自己的 Astro 集成 - 作者 Emmanuel Ohans,发布于 FreeCodeCamp
- Astro 集成模板 - 作者 Florian Lefebvre,发布于 GitHub