借着 Astro 加入 Cloudflare 的热度,决定写一篇关于它的文章。同时也算是我们自己在用它做了若干项目之后的的踩坑总结,两年间,我们用它做了若干尝试:中英文技术站点,开源的 Astro Theme,以及若干 Astro Integration和项目。
一句话总结:Astro 值得你花时间尝试,但需要了解它的一些限制,它的设计哲学也很简单:内容优先,JavaScript 能少则少。
为什么选择 Astro
在众多 Web 框架中,Astro 有三个特性让我印象深刻。
默认零 JS
Astro 默认输出纯 HTML,不会自动打包一堆 JavaScript 到客户端。
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
需要交互?通过 Islands Architecture 按需添加。这意味着你的页面加载速度会快得多,尤其是对于内容为主的站点。
内置 Content Collections
类型安全的内容管理是 Astro 的一大亮点。
// src/content.config.ts
const blog = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
schema: z.object({
title: z.string(),
pubDate: z.date(),
tags: z.array(z.string()),
}),
});
定义好 schema,Astro 会自动校验你的 Markdown frontmatter,IDE 里还能获得完整的类型提示。告别运行时才发现字段拼错的尴尬。
开发体验一流
- 热更新快到飞起
- 图片、CSS 等静态资源自动优化
- 丰富的集成生态,一条命令搞定
快速开始
四步创建你的第一个 Astro 站点:
# 1. 创建项目
npm create astro@latest
# 2. 安装依赖
pnpm install
# 3. 在 src/content/ 下写 Markdown
# 4. 启动开发服务器
pnpm dev
就这么简单。不需要写一行 JavaScript,只管写 Markdown。
核心概念
Astro 的架构围绕四个核心模块展开:
- Content:Collections、Loaders、Schemas,负责内容管理
- Components:.astro 文件、Islands、Layouts,负责 UI 构建
- Routing:基于文件系统、动态路由、API Routes
- Server:Middleware、Actions、SSR/Hybrid 渲染模式
基本开发流程:定义 Schema → 创建页面 → 添加组件 → 部署。路由、优化、构建这些事情 Astro 帮你处理。
集成系统
Astro 的扩展能力很强,一条命令就能添加新功能:
# 添加 React 支持
npx astro add react
官方集成
| 类别 | 示例 |
|---|---|
| UI 框架 | React, Vue, Svelte, Solid |
| 部署适配器 | Vercel, Cloudflare, Node |
| 工具 | MDX, Sitemap, Partytown |
自定义集成
也可以编写自己的集成:
// integrations/analytics/index.ts
export default function analytics(): AstroIntegration {
return {
name: "my-analytics",
hooks: {
"astro:config:setup": ({ injectScript }) => {
injectScript("page", `console.log("page view")`);
},
},
};
}
然后在配置中引入:
// astro.config.mjs
import analytics from "./integrations/analytics";
export default defineConfig({
integrations: [analytics()],
});
集成是基于源码的,可以从本地文件或 npm 包导入。
五个常见坑点
用 Astro 开发时,这些坑要注意。
1. 环境变量泄露
PUBLIC_* 前缀的变量会被打包进客户端 JS,任何人都能在浏览器 DevTools 里看到。
// ❌ 危险 - 密钥暴露给客户端
const key = import.meta.env.PUBLIC_API_KEY;
// ✅ 安全 - 仅服务端可见
const key = import.meta.env.API_KEY;
2. Server Hooks 只在开发环境运行
astro:server:* 钩子只在开发服务器中执行,生产环境不会触发。
hooks: {
"astro:server:setup": ({ server }) => {
// 这里的代码只在 dev 模式运行!
}
}
生产环境的请求处理请使用 middleware。
3. 集成的心智模型
集成是源码级别的,不是包级别的:
- 代码在构建时运行,不是运行时
- 配置在构建时就固定了
- 把它想象成编译过程,而非执行过程
4. 运行时配置的陷阱
集成配置在构建时就锁定了:
// ❌ 不行 - 配置在构建时锁定,astro.config.mjs
export default defineConfig({
integrations: [myIntegration({ apiKey: process.env.API_KEY })]
});
// ✅ 使用运行时配置文件,config/my-integration.ts
export default {
apiKey: process.env.API_KEY,
};
5. 部署前务必 Preview
pnpm dev 和生产环境不一样。部署前一定要本地测试构建产物:
pnpm build && pnpm preview
这能帮你提前发现 SSR/hybrid 渲染、环境变量、构建时与运行时行为差异等问题。
生态与基础设施
推荐的技术栈
- UI:React, TailwindCSS, shadcn/ui
- 存储:Flydrive
- 认证:Better Auth
部署方案
- 托管:Vercel, Cloudflare
- 数据库:Supabase, D1, Turso
- 对象存储:Cloudflare R2
项目模板
不想从零开始?astro.build/themes 提供了大量预置模板,涵盖博客、文档、作品集、电商等场景。
如果你对本站的样式感兴趣,欢迎试试我们开源的 MonaKit 主题。
Astro vs Next.js
| 维度 | Astro | Next.js |
|---|---|---|
| 设计理念 | 内容优先,零 JS | 应用优先,React 运行时 |
| 默认 JS | 无 | React hydration |
| UI 框架 | 任选(React, Vue, Svelte 等) | 仅 React |
| 适用场景 | 博客、文档、营销站 | Web 应用、后台系统 |
选择建议:
- Astro:内容站点、追求性能、需要混用多框架
- Next.js:复杂交互应用、深度依赖 React 生态
总结
如果你的网站以内容为核心,追求加载性能,又不想被单一框架绑定,Astro 是个靠谱的选择。
它不会取代 Next.js 或其他全栈框架,但在内容驱动的场景下,Astro 做到了简单与强大的平衡。