2026 年 3 月,我决定把自己用 Claude Code 的经验整理成一个教程站。选型上考虑了 Next.js、Hugo 和 Astro,最后选了 Astro——原因很简单:纯静态、构建快、对 Markdown 内容支持好,而且我之前没用过,正好拿来当实战素材。
这篇文章完整记录了我用 Claude Code 从零搭建这个站的过程。不是事后美化的”最佳实践”,而是当时实际的操作流程,包括走的弯路和浪费的时间。
$ claude "用 Astro 创建一个新项目,要求:
- TypeScript
- 不用任何 UI 框架(纯 Astro 组件)
- 内容用 Markdown,放在 content 目录
- 需要 RSS 和 sitemap 支持
项目名叫 claude-code-mastery"
Claude Code 用 npm create astro@latest 初始化了项目,然后装了 @astrojs/rss 和 @astrojs/sitemap。到这一步没什么问题,标准操作。
但它做了一件我没要求的事:创建了一个 React 集成。我在 prompt 里明确说了”不用任何 UI 框架”,但它可能觉得”反正加上也不碍事”。我让它删掉了。
教训:即使 prompt 写得很明确,还是要检查它有没有”多做”。这和思维篇第 1 篇讲的一样——AI 有时候会按自己的理解”优化”你的需求。
$ claude "设计 content collection 的 schema:
字段:title, module(枚举 m1-basics/m2-thinking/m3-practice/m4-advanced),
order(数字), description, duration, level, publishedAt, draft
在 src/content.config.ts 里配置"
这步很顺利,一次过。Schema 设计这种结构化的任务是 Claude Code 的强项——规则明确,没有模糊空间。
创建完之后我发现 Astro 的 content collection 默认把 Markdown 文件放在 src/content/ 里,但我想放在项目根目录的 content/ 下面。这个调整花了两轮对话才搞定,因为涉及修改 content.config.ts 里的 loader 配置。
第一轮 Claude Code 给了一个用 file() loader 的方案,实际运行报错。第二轮我把报错信息贴给它,它改用了 glob() loader,这次成功了。
// 最终方案
const lessons = defineCollection({
loader: glob({ pattern: '**/*.md', base: './content' }),
schema: z.object({ /* ... */ }),
});
时间消耗:约 25 分钟,其中 10 分钟在排查 loader 的问题。
这是最花时间的阶段,一共开了 12 次对话。
我先让它创建三个布局:BaseLayout(全局)、LessonLayout(教程页)、PageLayout(静态页)。
这里犯了一个错误:我在第 4 次对话里把三个布局一口气都描述了。结果 Claude Code 产出了三个布局文件,但它们之间的嵌套关系搞混了——LessonLayout 没有正确继承 BaseLayout 的 head 标签。
怎么修的:没有在那次对话里继续修,而是开了新对话,一次只处理一个布局。先把 BaseLayout 彻底搞对(对话 5),再基于它写 LessonLayout(对话 6)。这正是小步快跑的实际应用。
首页是我和 Claude Code 协作最纠结的部分。
对话 7:我先描述了我想要的大致结构——hero 区、数据统计、课程卡片、理念介绍、最新文章、底部 CTA。Claude Code 一次性生成了整个页面,大约 200 行 Astro 代码。
问题来了:代码能跑,但设计太”模板”了。 看起来就像从某个 landing page 模板复制过来的——完美的对称布局、标准的 CTA 按钮、刻板的分区。能用,但没有任何辨识度。
对话 8-9:我花了两次对话调整设计细节。把颜色方案从蓝灰色改成暖色调(米白底 + 砖红强调色),调整字体组合,重写了文案。这些事情不能交给 AI——设计品味和文案调性是需要人来把控的。
对话 10:加了终端组件。我让 Claude Code 写一个仿终端的展示组件,放在 hero 区右侧。这个它做得很好,CSS 动画、语法高亮色都不用我多说。技术性强、创意性弱的任务,是它的舒适区。
教程页需要一个侧边栏导航,显示当前模块的所有文章。这个需求说起来简单,实际做的时候碰到两个问题:
路由设计:我想用 /m1/01-what-is-claude-code 这种短路径,但 Astro 的 content collection 默认 slug 是 m1-basics/01-what-is-claude-code。需要手动做路径映射。
分页组件:上一篇/下一篇的逻辑需要知道当前模块的所有文章顺序。Claude Code 第一版的排序用的是字母序而不是 order 字段,导致第 10 篇排在第 2 篇前面。
这两个问题各花了一次对话解决。不难,但如果不是分步做、每步验证,这种小问题会叠加起来变得很难排查。
CSS 是我和 Claude Code 合作效率最低的环节。不是因为它写不好 CSS——它写的 CSS 语法上完全没问题——而是因为视觉效果只有你自己看了才知道对不对。
典型的流程是:
比如调整卡片悬浮效果那次,我描述”鼠标悬浮时卡片微微上浮,顶部出现一条强调色的线”。Claude Code 写了代码,效果是对的,但线太粗了、动画太快了。我又说”线从 3px 改成 2px,过渡时间从 0.2s 改成 0.3s”。来回调了 4 轮。
后来我学到的方法:CSS 微调这种事,直接在浏览器 DevTools 里试好数值,然后告诉 Claude Code 具体参数。不要让它猜你想要什么效果——它猜不准。
让 Claude Code 写了一个 SEOHead 组件,包含 Open Graph、Twitter Card 和 JSON-LD 结构化数据。这类有明确规范的任务它做得非常好——schema.org 的格式、meta 标签的属性,它比我记得清楚。
唯一改了一次:它在 JSON-LD 里把 publisher 写成了个人(Person),但对于一个教程站应该用 Organization。小问题,一次对话修复。
这两个功能基本是标准实现,Claude Code 一次搞定。Astro 的官方集成已经很成熟了,没有踩坑的空间。
移动端适配又花了 5 次对话。最大的问题是导航——桌面端的水平导航在移动端要变成汉堡菜单。Claude Code 写了一个纯 CSS + JS 的方案,功能正确但动画生硬。我又花了 2 次对话调整过渡效果。
侧边栏在移动端的处理也费了一些功夫。最终方案是移动端把侧边栏从固定定位改成正常文档流,放在文章上面。
完成整个项目花了大约 3 天,对话轮次分布:
| 阶段 | 对话次数 | 占比 | 一次成功率 |
|---|---|---|---|
| 项目初始化 | 3 | 8% | 67% |
| 页面开发 | 12 | 32% | 50% |
| 样式打磨 | 10 | 27% | 30% |
| 内容和 SEO | 8 | 22% | 75% |
| 修复和调整 | 4 | 11% | - |
| 合计 | 37 | 100% | 约 50% |
几个数字值得注意:
回头看这个过程,有几件事我会做不同:
先画线框再写代码——首页设计浪费了太多时间在”来回调”上。如果先用 Figma 或者纸笔画好大致布局,再让 Claude Code 实现,效率会高很多。
CSS 微调不要用对话——直接在 DevTools 里调好数值,然后告诉它改成什么。用自然语言描述视觉效果,效率极低。
不要在一次对话里塞太多文件——第 4 次对话(三个布局一起做)就是反面教材。文件之间有依赖关系时,必须分开处理。
CLAUDE.md 应该第一天就写——我到第二天才补上。如果一开始就写好项目约定(色彩方案、命名规范、目录结构),很多返工都可以避免。
每周更新 Claude Code 实战技巧、工具对比、行业动态。回复「模板」获取 CLAUDE.md 模板合集。