集成系统概述#
🙋 Astro 的强大之处不仅在于框架本身,更在于其丰富的集成生态。从 MDX 支持到站点地图生成,从 React 组件到图片优化,几乎所有常见需求都有现成的集成可用。
什么是 Astro 集成?#
集成(Integration)是扩展 Astro 功能的插件系统。它们可以:
- 🔧 添加新的文件类型支持(MDX、Svelte、Vue)
- 📦 注入构建时处理逻辑(图片优化、站点地图)
- 🎨 集成 CSS 框架(Tailwind、UnoCSS)
- 🚀 配置部署适配器(Vercel、Netlify、Node.js)
官方集成 vs 社区集成#
| 类型 | 特点 | 示例 |
|---|---|---|
| 官方集成 | Astro 团队维护,稳定可靠 | @astrojs/mdx, @astrojs/sitemap |
| 社区集成 | 社区贡献,功能丰富 | astro-robots-txt, astro-expressive-code |
查找集成:
- Astro 集成目录
- npm 搜索
astro-或@astrojs/
astro add 命令快速安装#
最简单的安装方式是使用 astro add 命令:
# 安装单个集成pnpm astro add mdx
# 安装多个集成pnpm astro add react sitemap tailwind
# 使用 npmnpx astro add mdx
# 使用 yarnyarn astro add mdxastro add 会自动:
- 安装 npm 包
- 更新
astro.config.ts配置 - 安装必要的依赖
常用官方集成#
@astrojs/mdx - MDX 支持#
MDX 让你在 Markdown 中使用 JSX 组件:
pnpm astro add mdx安装后可以在 .mdx 文件中:
---title: '我的文章'---
import Chart from '../components/Chart.jsx'import { Button } from '../components/Button.astro'
# 标题
这是普通的 Markdown 内容。
<Chart data={[1, 2, 3]} client:visible />
<Button>点击我</Button>
export const year = 2025
当前年份是 {year}。配置选项:
import mdx from '@astrojs/mdx'
export default defineConfig({ integrations: [ mdx({ // 自定义 remark 插件 remarkPlugins: [remarkGfm], // 自定义 rehype 插件 rehypePlugins: [rehypeSlug], // 优化选项 optimize: true, }), ],})@astrojs/sitemap - 站点地图#
自动生成 sitemap.xml,帮助搜索引擎索引网站:
pnpm astro add sitemap配置:
import sitemap from '@astrojs/sitemap'
export default defineConfig({ site: 'https://example.com', // 必须设置 integrations: [ sitemap({ // 自定义过滤 filter: (page) => !page.includes('/admin/'), // 更改频率 changefreq: 'weekly', // 优先级 priority: 0.7, // 多语言支持 i18n: { defaultLocale: 'zh', locales: { zh: 'zh-Hans', en: 'en-US', }, }, }), ],})构建后会生成:
dist/sitemap-index.xmldist/sitemap-0.xml
@astrojs/rss - RSS 订阅#
生成 RSS feed,让读者订阅你的内容:
pnpm astro add rss创建 RSS 端点:
import rss from '@astrojs/rss'import { getCollection } from 'astro:content'import { SITE } from '~/config'
export async function GET(context) { const posts = await getCollection('blog')
const sortedPosts = posts .filter((post) => !post.data.draft) .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf())
return rss({ title: SITE.title, description: SITE.description, site: context.site, items: sortedPosts.map((post) => ({ title: post.data.title, description: post.data.description, pubDate: post.data.pubDate, link: `/blog/${post.id}/`, })), customData: `<language>zh-Hans</language>`, })}UI 框架集成#
React:
pnpm astro add reactimport react from '@astrojs/react'
export default defineConfig({ integrations: [react()],})Vue:
pnpm astro add vueSvelte:
pnpm astro add svelte安装后即可导入对应框架的组件:
---import ReactComponent from '../components/React.jsx'import VueComponent from '../components/Vue.vue'import SvelteComponent from '../components/Svelte.svelte'---
<ReactComponent client:load /><VueComponent client:idle /><SvelteComponent client:visible />构建优化#
图片优化#
Astro 内置图片优化功能,自动处理图片:
---import { Image } from 'astro:assets'import myImage from '../assets/hero.png'---
<!-- 自动优化:压缩、生成多种格式、响应式 --><Image src={myImage} alt="Hero image" />
<!-- 指定尺寸 --><Image src={myImage} width={800} height={600} alt="Sized image" />
<!-- 远程图片 --><Image src="https://example.com/image.jpg" width={800} height={600} alt="Remote image"/>配置图片优化:
export default defineConfig({ image: { // 允许的远程图片域名 domains: ['cdn.example.com', 'images.unsplash.com'], // 响应式图片行为 layout: 'constrained', responsiveStyles: true, },})预取链接 (Prefetch)#
Astro 内置链接预取功能,提升导航速度:
export default defineConfig({ prefetch: { // 预取策略 defaultStrategy: 'viewport', // 进入视口时预取 // 或 'hover' - 鼠标悬停时预取 // 或 'load' - 页面加载后预取所有 },})在链接上控制预取:
<!-- 使用默认策略 --><a href="/about">关于</a>
<!-- 强制预取 --><a href="/contact" data-astro-prefetch>联系</a>
<!-- 禁用预取 --><a href="/external" data-astro-prefetch="false">外部链接</a>
<!-- 指定策略 --><a href="/heavy-page" data-astro-prefetch="hover">悬停预取</a>压缩与缓存策略#
HTML 压缩(使用 astro-compress):
pnpm add astro-compressimport compress from 'astro-compress'
export default defineConfig({ integrations: [ compress({ CSS: true, HTML: true, JavaScript: true, Image: false, // 已有内置优化 SVG: true, }), ],})资源哈希:
Astro 构建时自动为资源添加内容哈希,实现长期缓存:
dist/├── _astro/│ ├── index.a1b2c3d4.css│ └── script.e5f6g7h8.jsView Transitions#
Astro 内置 View Transitions API 支持,实现页面过渡动画:
---import { ViewTransitions } from 'astro:transitions'---
<html> <head> <ViewTransitions /> </head> <body> <slot /> </body></html>自定义过渡动画:
---import { fade, slide } from 'astro:transitions'---
<header transition:animate={fade({ duration: '0.3s' })}> <nav>...</nav></header>
<main transition:animate={slide({ duration: '0.5s' })}> <slot /></main>部署方式#
静态托管 (SSG)#
默认情况下,Astro 生成静态 HTML 文件,可以部署到任何静态托管服务。
Vercel:
# 安装适配器(可选,用于边缘优化)pnpm astro add vercel推送到 GitHub 后,在 Vercel 导入项目即可。
Netlify:
pnpm astro add netlify配置 netlify.toml:
[build] command = "pnpm build" publish = "dist"Cloudflare Pages:
pnpm astro add cloudflare在 Cloudflare Dashboard 连接 Git 仓库,设置:
- Build command:
pnpm build - Build output directory:
dist
服务端渲染 (SSR)#
需要动态内容时,使用 SSR 模式:
export default defineConfig({ output: 'server', // 或 'hybrid' adapter: /* 适配器 */,})Node.js 适配器:
pnpm astro add nodeimport node from '@astrojs/node'
export default defineConfig({ output: 'server', adapter: node({ mode: 'standalone', // 或 'middleware' }),})构建后运行:
pnpm buildnode ./dist/server/entry.mjsVercel SSR:
import vercel from '@astrojs/vercel'
export default defineConfig({ output: 'server', adapter: vercel({ // Edge Functions edgeMiddleware: true, // 图片优化服务 imageService: true, }),})Netlify SSR:
import netlify from '@astrojs/netlify'
export default defineConfig({ output: 'server', adapter: netlify({ // Edge Functions edgeMiddleware: true, }),})混合模式 (Hybrid)#
大部分页面静态,少数页面 SSR:
export default defineConfig({ output: 'hybrid', // 默认静态 adapter: vercel(),})标记需要 SSR 的页面:
---export const prerender = false // 禁用预渲染---或者标记静态页面:
---export const prerender = true // 强制预渲染---部署实战#
环境变量配置#
Astro 支持 .env 文件:
PUBLIC_SITE_URL=https://example.comAPI_SECRET=your-secret-key在代码中访问:
// 公开变量(客户端可访问)const siteUrl = import.meta.env.PUBLIC_SITE_URL
// 私有变量(仅服务端)const apiSecret = import.meta.env.API_SECRET
// 内置变量const isDev = import.meta.env.DEVconst isProd = import.meta.env.PRODconst mode = import.meta.env.MODE // 'development' | 'production'类型声明:
/// <reference types="astro/client" />
interface ImportMetaEnv { readonly PUBLIC_SITE_URL: string readonly API_SECRET: string}
interface ImportMeta { readonly env: ImportMetaEnv}构建命令与输出目录#
{ "scripts": { "dev": "astro dev", "build": "astro build", "preview": "astro preview", "check": "astro check" }}输出目录结构:
dist/├── _astro/ # 静态资源(带哈希)│ ├── index.css│ └── script.js├── blog/ # 博客页面│ └── hello-world/│ └── index.html├── index.html # 首页├── sitemap-index.xml├── sitemap-0.xml└── robots.txt自定义域名配置#
设置站点 URL:
export default defineConfig({ site: 'https://wangshengliang.cn', base: '/', // 如果部署在子路径})DNS 配置(以 Vercel 为例):
- 在 Vercel 项目设置中添加域名
- 在域名 DNS 添加记录:
- A 记录指向
76.76.19.19 - 或 CNAME 指向
cname.vercel-dns.com
- A 记录指向
CI/CD 自动部署#
GitHub Actions 示例:
name: Deploy
on: push: branches: [main]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 8
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: pnpm
- name: Install dependencies run: pnpm install
- name: Build run: pnpm build
- name: Deploy to Vercel uses: amondnet/vercel-action@v25 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} vercel-args: '--prod'实战:当前博客的技术栈#
让我们分析当前博客使用的完整技术栈。
astro.config.ts 配置分析#
import { defineConfig } from 'astro/config'import sitemap from '@astrojs/sitemap'import robotsTxt from 'astro-robots-txt'import unocss from 'unocss/astro'import astroExpressiveCode from 'astro-expressive-code'import mdx from '@astrojs/mdx'
import { remarkPlugins, rehypePlugins } from './plugins'import { SITE } from './src/config'
export default defineConfig({ site: SITE.website, // https://wangshengliang.cn/ base: SITE.base, // /
integrations: [ sitemap(), // 站点地图 robotsTxt(), // robots.txt unocss({ injectReset: true }), // 原子化 CSS astroExpressiveCode(), // 代码块增强 mdx(), // MDX 支持 ],
markdown: { syntaxHighlight: false, // 使用 Expressive Code remarkPlugins, // Remark 插件 rehypePlugins, // Rehype 插件 },
image: { domains: SITE.imageDomains, layout: 'constrained', responsiveStyles: true, },
experimental: { contentIntellisense: true, // 内容集合智能提示 },})使用的集成清单#
| 集成 | 用途 |
|---|---|
@astrojs/sitemap | 自动生成站点地图 |
@astrojs/mdx | MDX 支持 |
astro-robots-txt | 生成 robots.txt |
unocss/astro | 原子化 CSS 框架 |
astro-expressive-code | 代码块语法高亮和增强 |
Remark/Rehype 插件链#
Remark 和 Rehype 插件用于处理 Markdown 内容:
import remarkGfm from 'remark-gfm'import remarkMath from 'remark-math'import rehypeKatex from 'rehype-katex'import rehypeSlug from 'rehype-slug'import rehypeAutolinkHeadings from 'rehype-autolink-headings'
export const remarkPlugins = [ remarkGfm, // GitHub 风格 Markdown remarkMath, // 数学公式语法]
export const rehypePlugins = [ rehypeKatex, // KaTeX 数学渲染 rehypeSlug, // 为标题添加 id rehypeAutolinkHeadings, // 标题锚点链接]搜索功能 (Pagefind)#
当前博客使用 Pagefind 实现全站搜索:
{ "scripts": { "build": "astro build && pagefind --site dist" }}Pagefind 特点:
- 构建时生成搜索索引
- 极小的 JavaScript 体积(~10KB)
- 支持中文分词
- 无需后端服务
评论系统 (Giscus)#
基于 GitHub Discussions 的评论系统:
export const FEATURES = { giscus: [ true, { 'data-repo': 'wangshengliang-wsl/blog', 'data-repo-id': 'R_kgDOP4yOiQ', 'data-category': 'Announcements', 'data-category-id': 'DIC_kwDOP4yOic4CwBgk', 'data-mapping': 'pathname', 'data-lang': 'zh-CN', }, ],}Giscus 组件:
---import { FEATURES } from '~/config'
const [enabled, config] = FEATURES.giscusif (!enabled) return null---
<section class="giscus-container mt-8"> <script src="https://giscus.app/client.js" data-repo={config['data-repo']} data-repo-id={config['data-repo-id']} data-category={config['data-category']} data-category-id={config['data-category-id']} data-mapping={config['data-mapping']} data-lang={config['data-lang']} crossorigin="anonymous" async></script></section>OG 图片生成#
OG(Open Graph)图片用于社交媒体分享预览:
// 自动为每篇文章生成 OG 图片// 使用 Satori 或 @vercel/og 生成 SVG/PNG部署检查清单#
部署前确认:
-
astro.config.ts中设置了正确的siteURL - 环境变量已配置(本地
.env和部署平台) - 运行
pnpm build无错误 - 运行
pnpm preview本地预览正常 -
robots.txt和sitemap.xml正确生成 - 图片优化正常工作
- 搜索功能(如有)索引完成
- 评论系统(如有)配置正确
性能优化总结#
🎯 当前博客的性能优化策略:
- 零 JavaScript 默认 - 只有交互组件加载 JS
- 图片优化 - 自动压缩、格式转换、响应式
- 资源哈希 - 长期缓存静态资源
- 预取链接 - 提升页面导航速度
- 内容索引 - Pagefind 离线搜索
- 原子化 CSS - UnoCSS 按需生成
系列总结#
🎉 恭喜你完成了 Astro 系列的学习!回顾一下我们学到的内容:
- 入门指南 - Astro 核心理念、岛屿架构、项目创建
- 路由与页面 - 文件路由、动态路由、分页实现
- 组件与样式 - 组件系统、框架集成、样式方案
- 内容集合 - Content Layer API、Schema 验证
- 集成与部署 - 官方集成、构建优化、部署方案
现在你已经具备了用 Astro 构建内容驱动网站的完整知识。动手实践吧!