Skip to content

Astro 集成与部署

集成系统概述#

🙋 Astro 的强大之处不仅在于框架本身,更在于其丰富的集成生态。从 MDX 支持到站点地图生成,从 React 组件到图片优化,几乎所有常见需求都有现成的集成可用。

什么是 Astro 集成?#

集成(Integration)是扩展 Astro 功能的插件系统。它们可以:

官方集成 vs 社区集成#

类型特点示例
官方集成Astro 团队维护,稳定可靠@astrojs/mdx, @astrojs/sitemap
社区集成社区贡献,功能丰富astro-robots-txt, astro-expressive-code

查找集成:

astro add 命令快速安装#

最简单的安装方式是使用 astro add 命令:

Terminal window
# 安装单个集成
pnpm astro add mdx
# 安装多个集成
pnpm astro add react sitemap tailwind
# 使用 npm
npx astro add mdx
# 使用 yarn
yarn astro add mdx

astro add 会自动:

  1. 安装 npm 包
  2. 更新 astro.config.ts 配置
  3. 安装必要的依赖

常用官方集成#

@astrojs/mdx - MDX 支持#

MDX 让你在 Markdown 中使用 JSX 组件:

Terminal window
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}

配置选项

astro.config.ts
import mdx from '@astrojs/mdx'
export default defineConfig({
integrations: [
mdx({
// 自定义 remark 插件
remarkPlugins: [remarkGfm],
// 自定义 rehype 插件
rehypePlugins: [rehypeSlug],
// 优化选项
optimize: true,
}),
],
})

@astrojs/sitemap - 站点地图#

自动生成 sitemap.xml,帮助搜索引擎索引网站:

Terminal window
pnpm astro add sitemap

配置

astro.config.ts
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',
},
},
}),
],
})

构建后会生成:

@astrojs/rss - RSS 订阅#

生成 RSS feed,让读者订阅你的内容:

Terminal window
pnpm astro add rss

创建 RSS 端点:

src/pages/rss.xml.ts
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:

Terminal window
pnpm astro add react
astro.config.ts
import react from '@astrojs/react'
export default defineConfig({
integrations: [react()],
})

Vue:

Terminal window
pnpm astro add vue

Svelte:

Terminal window
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"
/>

配置图片优化

astro.config.ts
export default defineConfig({
image: {
// 允许的远程图片域名
domains: ['cdn.example.com', 'images.unsplash.com'],
// 响应式图片行为
layout: 'constrained',
responsiveStyles: true,
},
})

预取链接 (Prefetch)#

Astro 内置链接预取功能,提升导航速度:

astro.config.ts
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):

Terminal window
pnpm add astro-compress
astro.config.ts
import 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.js

View Transitions#

Astro 内置 View Transitions API 支持,实现页面过渡动画:

src/layouts/Layout.astro
---
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

Terminal window
# 安装适配器(可选,用于边缘优化)
pnpm astro add vercel

推送到 GitHub 后,在 Vercel 导入项目即可。

Netlify

Terminal window
pnpm astro add netlify

配置 netlify.toml

[build]
command = "pnpm build"
publish = "dist"

Cloudflare Pages

Terminal window
pnpm astro add cloudflare

在 Cloudflare Dashboard 连接 Git 仓库,设置:

服务端渲染 (SSR)#

需要动态内容时,使用 SSR 模式:

astro.config.ts
export default defineConfig({
output: 'server', // 或 'hybrid'
adapter: /* 适配器 */,
})

Node.js 适配器

Terminal window
pnpm astro add node
import node from '@astrojs/node'
export default defineConfig({
output: 'server',
adapter: node({
mode: 'standalone', // 或 'middleware'
}),
})

构建后运行:

Terminal window
pnpm build
node ./dist/server/entry.mjs

Vercel 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 的页面:

src/pages/api/search.astro
---
export const prerender = false // 禁用预渲染
---

或者标记静态页面:

src/pages/about.astro
---
export const prerender = true // 强制预渲染
---

部署实战#

环境变量配置#

Astro 支持 .env 文件:

.env
PUBLIC_SITE_URL=https://example.com
API_SECRET=your-secret-key

在代码中访问:

// 公开变量(客户端可访问)
const siteUrl = import.meta.env.PUBLIC_SITE_URL
// 私有变量(仅服务端)
const apiSecret = import.meta.env.API_SECRET
// 内置变量
const isDev = import.meta.env.DEV
const isProd = import.meta.env.PROD
const mode = import.meta.env.MODE // 'development' | 'production'

类型声明

src/env.d.ts
/// <reference types="astro/client" />
interface ImportMetaEnv {
readonly PUBLIC_SITE_URL: string
readonly API_SECRET: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}

构建命令与输出目录#

package.json
{
"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

astro.config.ts
export default defineConfig({
site: 'https://wangshengliang.cn',
base: '/', // 如果部署在子路径
})

DNS 配置(以 Vercel 为例):

  1. 在 Vercel 项目设置中添加域名
  2. 在域名 DNS 添加记录:
    • A 记录指向 76.76.19.19
    • 或 CNAME 指向 cname.vercel-dns.com

CI/CD 自动部署#

GitHub Actions 示例

.github/workflows/deploy.yml
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 配置分析#

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/mdxMDX 支持
astro-robots-txt生成 robots.txt
unocss/astro原子化 CSS 框架
astro-expressive-code代码块语法高亮和增强

Remark/Rehype 插件链#

Remark 和 Rehype 插件用于处理 Markdown 内容:

plugins/index.ts
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 实现全站搜索:

package.json
{
"scripts": {
"build": "astro build && pagefind --site dist"
}
}

Pagefind 特点:

评论系统 (Giscus)#

基于 GitHub Discussions 的评论系统:

src/config.ts
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 组件:

src/components/Giscus.astro
---
import { FEATURES } from '~/config'
const [enabled, config] = FEATURES.giscus
if (!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)图片用于社交媒体分享预览:

plugins/og-image.ts
// 自动为每篇文章生成 OG 图片
// 使用 Satori 或 @vercel/og 生成 SVG/PNG

部署检查清单#

部署前确认:

性能优化总结#

🎯 当前博客的性能优化策略:

  1. 零 JavaScript 默认 - 只有交互组件加载 JS
  2. 图片优化 - 自动压缩、格式转换、响应式
  3. 资源哈希 - 长期缓存静态资源
  4. 预取链接 - 提升页面导航速度
  5. 内容索引 - Pagefind 离线搜索
  6. 原子化 CSS - UnoCSS 按需生成

系列总结#

🎉 恭喜你完成了 Astro 系列的学习!回顾一下我们学到的内容:

  1. 入门指南 - Astro 核心理念、岛屿架构、项目创建
  2. 路由与页面 - 文件路由、动态路由、分页实现
  3. 组件与样式 - 组件系统、框架集成、样式方案
  4. 内容集合 - Content Layer API、Schema 验证
  5. 集成与部署 - 官方集成、构建优化、部署方案

现在你已经具备了用 Astro 构建内容驱动网站的完整知识。动手实践吧!

参考资料#