跳到正文
码上手 coding.chengyu.dev

选技术栈并搭骨架:第一次提交

为书单项目选定 Astro、Tailwind 和 Cloudflare Workers,让 Claude Code 初始化项目、写好 CLAUDE.md、完成第一次 git 提交并推到 GitHub。

约 30 分钟 进阶 Claude CodeAstroCloudflareGit 核实于 2026-10-25

学完这一课,你能

  • 能说清这套技术栈每一层为什么这样选
  • 能让 Claude Code 初始化 Astro + Tailwind + Cloudflare 项目并验证能构建
  • 能写出精简有效的项目 CLAUDE.md,把技术栈和红线固定下来
  • 能在提交前检查没有密钥进入仓库,并把代码推到 GitHub

有了规格,下一步是让项目「立起来」:能启动、能构建、有版本管理、代码在远端有备份。这一步看起来平淡,却决定了后面五课的质量。骨架搭歪了,后面每次让智能体改东西,都会在歪的地基上继续歪。

这一课有两个目标:选对栈并把选择固定下来,完成第一次提交。

为什么选这套栈

选技术栈的标准不是「最先进」,而是对一个人维护的小项目最省心。书单项目的需求很朴素:几个页面、一张表、一个调用 AI 的接口。

层 选择 理由
页面 Astro 默认输出很少的 JavaScript,内容型页面很快;组件用 .astro 文件,智能体写起来不容易出错
样式 Tailwind CSS 样式写在标签旁边,智能体改一个组件不会牵连全局;设计令牌用 CSS 变量,下一课细讲
运行环境 Cloudflare Workers(含静态资源) 页面和接口放在同一个 Worker 里,一次部署,没有单独的服务器要管
数据库 D1 Cloudflare 托管的 SQLite,免费额度对个人项目足够,用法就是 SQL
AI Workers AI 在同一个平台里直接调用模型,不需要另外申请密钥
代码托管与部署 GitHub + GitHub Actions 推送即部署,第 6 课配置

一个值得单独说的变化是 Workers 与 Pages。早几年部署前端框架到 Cloudflare,大家默认用 Pages。现在 Cloudflare 的框架指南和 Astro 官方部署文档都以 Workers 为准:Workers 可以同时托管静态资源和服务端代码,配置统一写在 wrangler 配置文件里。Astro 的 Cloudflare 适配器在 v13 起已经移除了对 Pages 的支持。所以如果你在网上看到「创建 Pages 项目、连接 Git 仓库」的老教程,不要照着做,以官方当前文档为准。

另一个变化是配置文件格式。Cloudflare 现在推荐新项目使用 wrangler.jsonc(带注释的 JSON),而不是早年的 wrangler.toml。部分较新的功能只在 JSON 格式的配置里提供。

让 Claude Code 搭骨架

骨架搭建是典型的「步骤明确、结果可检查」的任务,很适合交给智能体。但要注意两点:

  • 把栈和版本说死。否则它可能顺手选 Next.js,或者用旧的 Pages 配置。
  • 让它自己验证。构建通过才算完成,别接受「已创建」这种自述。

整个过程的命令,其实只有这几条(智能体会替你执行,你要能看懂):

# 1. 创建 Astro 项目(交互式,选「空项目/minimal」模板,不要选带示例的)
npm create astro@latest my-shelf

# 2. 添加 Cloudflare 适配器:安装依赖并更新 astro.config.mjs,同时生成 wrangler.jsonc
npx astro add cloudflare

# 3. 添加 Tailwind:安装官方 Vite 插件,并创建 src/styles/global.css
npx astro add tailwind

# 4. 把 wrangler 装成开发依赖,保证团队和 CI 用同一个版本
npm install -D wrangler@latest

如果你是在已有 SPEC.md 的目录里操作,npm create astro@latest 可以用 . 作为目标目录。执行前让智能体先确认目录里只有 SPEC.md。

适配器装好后,wrangler.jsonc 大致是这个形状(以官方文档为参照,实际字段以生成的为准):

{
  "name": "my-shelf",
  "main": "@astrojs/cloudflare/entrypoints/server",
  "compatibility_date": "2026-10-25",
  "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
  "assets": {
    "binding": "ASSETS",
    "directory": "./dist"
  },
  "observability": { "enabled": true }
}

几个字段的含义:

  • main 是 Worker 的入口,由适配器提供;
  • assets 告诉 Wrangler 把构建产物 dist 目录当静态资源上传;
  • compatibility_date 决定运行时行为的版本,填你创建项目当天的日期,之后不要随手改;
  • observability 打开 Workers 日志,第 6 课查日志时会用到。

模板自带的 .gitignore 内容以实际生成的为准,不一定覆盖 Cloudflare 相关的本地文件。创建后让智能体确认它至少包含这些:

node_modules/
dist/
.astro/
.wrangler/
.dev.vars*
.env*

.dev.vars 是 Wrangler 约定的本地密钥文件,后面存放管理令牌。它必须在第一次提交之前就被忽略。

写项目的 CLAUDE.md

CLAUDE.md 是 Claude Code 每个会话开头都会读的项目说明。官方的建议是:只写「删掉就会让它犯错」的内容,越短越好。在项目里运行 /init 可以生成一份草稿,再手工收紧。(写法细节见 CLAUDE.md 与记忆。)

书单项目的 CLAUDE.md 可以这样写:

# 个人书单(my-shelf)

规格见 @SPEC.md。需求变化时先改 SPEC.md,再改代码。

## 技术栈(不要替换)
Astro 7(on-demand 渲染)+ Tailwind CSS 4 + Cloudflare Workers(含静态资源)
+ D1(绑定名 DB)+ Workers AI(绑定名 AI)。配置文件用 wrangler.jsonc,不用 Pages。

## 常用命令
- `npm run dev`:本地开发
- `npm run build`:构建,改完代码必须跑通
- `npx wrangler types`:改完 wrangler.jsonc 后重新生成类型
- 数据库迁移:`npx wrangler d1 migrations apply my-shelf-db --local`

## 红线
- 绝不读取、打印或提交 `.dev.vars`、`.env*`;密钥只通过 `wrangler secret` 或环境变量
- 绝不对 `--remote` 的数据库执行写操作,也不执行 `wrangler deploy`,除非我明确要求
- SQL 一律使用 `bind()` 参数绑定,禁止字符串拼接
- 不要用 `set:html` 渲染用户输入
- 不新增 SPEC.md 里「不做什么」列出的功能

这份文件只有二十来行,但每一行都在防一种具体的失误。你会发现它和 .gitignore 是配套的:一个管智能体的行为,一个管仓库里有什么。

CLAUDE.md 只是「提示」,不是强制。如果某条红线你一刻也不想它越过,比如读取 .dev.vars,还要在 .claude/settings.json 里加一条 Read 拒绝规则,让权限系统来拦(见 权限与安全):

{
  "permissions": {
    "deny": ["Read(./.dev.vars)", "Read(./.env)"]
  }
}

第一次提交:先看再提交

提交之前,让智能体做两件事:npm run build 验证骨架能构建,git status 和 git diff --stat 列出将要提交的文件。你要亲眼看一遍这份清单,重点找三类东西:密钥文件、node_modules、dist。这一步在第 6 课也会有,只是那时会交给 CI。

claude — ~/projects/my-shelf
$ git init && git add -A && git status --short
A .gitignore
A CLAUDE.md
A SPEC.md
A astro.config.mjs
A package.json
A package-lock.json
A src/pages/index.astro
A src/styles/global.css
A wrangler.jsonc
# 清单里没有 .dev.vars、.env、node_modules、dist,可以提交
$ git commit -m "chore: 初始化 Astro + Tailwind + Cloudflare 骨架"
$ gh repo create my-shelf --private --source=. --push
# 私有仓库创建成功并推送;公开前先想清楚仓库里有没有不该公开的内容

gh repo create 的三个参数分别是:--private 选择私有仓库,--source=. 以当前目录为来源,--push 把已有提交推上去。这条命令会在你的 GitHub 账号下创建仓库,属于外部写入,建议你自己确认后在终端执行,或者在智能体询问时明确点头。

之后的约定也提前说好:每课在一个分支上做,合并前看 diff。直接往 main 推没有硬性禁止,但从现在起养成习惯,第 6 课配置自动部署后,推到 main 就意味着上线。

常见坑

  • 智能体换了栈。症状是出现 next.config.js 或 functions/ 目录。原因通常是 CLAUDE.md 没写栈,或者写得太含糊。
  • 照着旧教程配了 Pages。症状是出现 _routes.json 之类的文件,或者适配器版本过旧。让智能体对照上面列的官方页面重做。
  • compatibility_date 被改来改去。它影响运行时行为,应该是一次性设定,除非你有意升级。
  • 构建能过,运行时才报错。骨架阶段只能证明「编译通过」,数据库和 AI 要到第 4 课才会真正被用到。
搭建书单项目骨架 Claude Code

读取 SPEC.md,在当前目录搭建项目骨架。技术栈固定为:Astro(最新稳定版)+ Tailwind CSS(用 npx astro add tailwind)+ Cloudflare Workers(用 npx astro add cloudflare),配置文件使用 wrangler.jsonc,不要使用 Cloudflare Pages。

步骤:

  1. 目录里只有 SPEC.md 时,用 npm create astro@latest . 的最小模板初始化;创建过程中不要选择示例内容;
  2. 添加 Cloudflare 适配器和 Tailwind,并安装 wrangler 作为开发依赖;
  3. 打开 wrangler.jsonc,把 name 改为 my-shelf,确认 main、assets、observability 与 Astro 官方 Cloudflare 部署文档一致,compatibility_date 使用今天的日期;
  4. 确保 .gitignore 包含 node_modules、dist、.astro、.wrangler、.dev.vars*、.env*;
  5. 在 package.json 里加一个 "types": "wrangler types" 脚本;
  6. 生成 CLAUDE.md:技术栈、常用命令、红线(不碰密钥文件、不对远程数据库写入、不自行部署、SQL 只用参数绑定),控制在 30 行内;
  7. 运行 npm run build,把结果贴给我。

完成后不要提交。运行 git status,列出所有将被提交的文件,并逐项说明为什么需要它,等我确认后再提交。

小测

下面哪个说法最准确地描述了 Cloudflare 上部署 Astro 的当前推荐做法?

小测

为什么 `.dev.vars` 要在第一次 git 提交之前就加入 .gitignore?

动手任务

动手清单

0/5

下一课:做界面。骨架已经有了,我们先用假数据把页面做出来,后端留到第 4 课。

参考来源

工具更新很快,若与官方文档不一致,以官方为准。

学完了吗?

标记完成会记录在本机浏览器,计入你的学习进度和连续天数。

Esc

输入关键词开始搜索,例如「CLAUDE.md」「MCP」「部署」