使用 Claude Code 的 greenfield 工作流搭建结构、脚本和第一个可运行的垂直切片,让你能每周运行、测试并逐步改进。

从空仓库开始看起来充满自由,但往往会变成混乱的动力:大量生成文件、半工作的构建、没有明确的下一个改动位置。Claude Code 的 greenfield 工作流的目的是避免这种第一周的混乱。
一些常见的失败会反复出现:
早期决定很难撤销,因为所有东西都叠加在它们之上。混乱的结构不断被强化。手动构建演变成十种不同的设置。如果你不尽早锁定一个简单的 dev 命令,你就无法判断是改动把应用弄坏了,还是只是把运行环境弄坏了。
当本文提到“可运行的应用”时,意思很具体:一个命令启动项目,打印可预测的输出,并在缺少某些内容时明显失败。你应该能够删除本地安装、克隆仓库、运行该命令并看到相同的结果。
“垂直切片”是最小的端到端功能,用来证明你的应用是真的。不是 UI 模拟,也不是单独的数据表。它是穿过整个系统的一条细线,比如带表单的页面、一个保存数据的 API 端点、一次数据库写入和读取,以及页面上可见的一个结果。
如果你可以用一个命令运行应用并交付一个垂直切片,你就有了可以逐步迭代的基础,而不需要猜测。
明确的第一个切片能让仓库保持整洁、提示保持聚焦。此时该决定你想端到端演示什么,而不是你希望完整产品成为什么样子。
选择最小的用户故事来证明应用在整个路径上可工作。一个好的切片触及 UI、数据和一个真实动作。例子:"作为用户,我可以添加一个任务并在刷新后看到它出现在列表中。" 很小,但它强制你处理路由、验证、存储和一个基本屏幕。
第一周只选一个目标平台并坚持它。如果你从 web 开始,就只做 web。不要“以防万一”加上移动界面。即便将来计划使用像 Koder.ai 这样的平台,你如果把第一个切片保持在一条赛道上(React web,或 Go API,或 Flutter),会得到更好的结果。
用简单明了的语言定义“第 1 周完成”的标准:
然后写下三个非目标来保护范围。例如:不做认证、不开主题系统、不加后台任务。
一旦这些决定被写下来,你的生成提示可以很严格:只生成支持该切片的内容,其余全部留作 TODO。
在你要求 Claude 生成任何内容之前,先锁定少量默认设置。它们看起来很小,但能防止后来“全部重命名”的烂摊子。
首先,决定应用的形态。如果你确实需要浏览器 UI 和后端,就从两部分清晰开始(frontend + API)并准备一个共享的契约位置(API 类型或简单的 schema)。如果应用可以是单个服务器渲染的 web 应用,就保持单代码库,这样本地开发更简单。
接着,就配置规则达成一致。使用本地 env 文件,不纳入 git,并提交一个模板(例如 .env.example)包含安全占位符和简短注释。这能让入职更容易并降低泄露秘密的风险。
选定默认的开发端口并保持稳定。端口会出现在脚本、文档和错误信息中,以后改动很麻烦。命名也一样:文件夹、服务和包应遵循一种约定。稳定性比“完美”更重要。
一个简单的起始决策集合:
.env,提交 .env.example例子:你选择 web 端口 3000,api 端口 8080。你的 env 模板包含 API_URL=http://localhost:8080 和 DATABASE_URL=...。当 Claude 之后生成脚本和文档时,一切都会对齐,而不是各自漂移。
首先要求一个可运行的骨架,而不是“整个应用”。在还没有放置功能的位置之前请求功能,是导致混乱输出的最快途径。
明确结构。要求一个带简短注释的文件夹布局,说明每个位置放什么、不该放什么。这会让决策提前出来,而不是随着文件散落。
一种让其保持自律的简单方法是在提示中设规则:
这里有一个可复用并可调整的提示:
You are working in an empty repo. Create a minimal runnable skeleton.
Constraints:
- Keep it small: no real features yet.
- Propose a clear folder structure and add brief comments in each folder’s README.
- Add scripts for: setup, dev, test, build. They must work on a fresh machine.
- Tell me exactly how to run it, and what output I should see.
- After generating, stop and wait for my “ran it” confirmation.
Output:
1) File tree
2) Key files (only)
3) Run instructions
然后保持循环紧凑。不要一次性请求五项修改。生成一个小改动,运行它,粘贴确切的错误(或成功),然后请求最小修复。那种生成-运行-调整的节奏能让项目可预测,并且减少结构漂移的可能。
从一个承诺开始:任何人都能克隆仓库并通过一条命令看到可运行内容。这会在你请求 AI 添加真实功能之前给你一个稳定的基础。
创建仓库并趁一切还清晰时写一个简短的 README。保持实用:先决条件、那条 dev 命令,以及如何运行测试(即使测试现在是空的)。
接下来,选择与你之前决定的应用形态相符的顶层布局。
如果你要构建多个可部署单元(例如 frontend + API),工作区布局会有帮助:
/
apps/
packages/
scripts/
docs/
README.md
如果你只做单一应用,保持结构简单,避免不必要的层次,直到需要为止。
现在添加最小的防护措施以保持代码一致。选择一个格式化工具和一个 linter,接受其默认设置,并添加各自的单一配置文件。目标是清晰的 diff,而不是第一天就定下完美规则。
通过一条总是从 repo 根能运行的命令让开发体验可预测。这里有一个简单的形状:
{
"scripts": {
"dev": "echo \"start dev server here\"",
"build": "echo \"build here\"",
"test": "echo \"tests here\"",
"lint": "echo \"lint here\""
}
}
在你生成其他任何东西之前,先运行那个 dev 命令,确认它干净退出(或启动占位服务器),然后只提交包含脚手架的第一次 commit。如果队友(或未来的你)能从头重现设置,你就可以开始构建第一个切片。
好的 greenfield 结构做两件事:帮你快速找到代码,并且给 Claude 更少的空间每次请求都发明新模式。目标不是完美,而是稳定。
如果你在单一应用内工作(或在 apps/<name>/ 文件夹内),一个简单的内部布局通常能很好地维持:
src/ 应用代码(features、shared、入口点)config/ 非秘密配置tests/ 更高层次的测试,读起来像用户行为scripts/ 辅助脚本(开发设置、数据库重置、发布任务)docs/ 简短笔记和你会实际维护的清单在 src/ 内,根据变更模式把 feature 代码和共享代码分开。feature 代码经常变,应放得靠近;共享代码应尽量平淡可复用。
一个实用规则:把 UI 屏幕、处理器和 feature 特定逻辑放在 src/features/<featureName>/...。把日志、API 客户端、设计系统组件和通用工具放在 src/shared/...。如果某个辅助工具仅对一个 feature 有意义,就把它放在那个 feature 里,即便看起来可复用;当你有第二个真实使用时再移动它。
文件夹名应描述用途,而不是技术。features 和 shared 在技术栈变化时仍有意义。避免使用 misc 或 new 这类名称。
保持 docs/ 小而有用。一个良好的起点是 docs/checklists.md,写几行:如何运行、如何测试、如何添加新 feature 文件夹,以及什么算“完成”。
当任何人都能运行相同命令并得到相同结果时,仓库才显得真实。脚本是护栏:它们减少猜测、保持变更小,并让问题变得醒目。
从一组小而朴素的命令开始并保持它们无聊。如果新人加入(或你两周后回来),不应需要特殊标志或隐藏步骤。
这里有一个可以适配任何技术栈的基线:
{
"scripts": {
"dev": "node ./scripts/dev.js",
"build": "node ./scripts/build.js",
"test": "node ./scripts/test.js",
"test:quick": "node ./scripts/test.js --quick",
"test:full": "node ./scripts/test.js --full",
"format": "node ./scripts/format.js",
"lint": "node ./scripts/lint.js",
"smoke": "node ./scripts/smoke.js"
}
}
让 dev 脚本成为开心路径。它应该启动应用、打印运行地址,并保持日志可读。如果服务器无法启动,应快速失败并给出清晰信息(缺少 env 变量、端口被占用、无法连接数据库)。
构建脚本应始终产生干净的输出目录。先删除旧的输出,然后产出新工件。这样可避免因遗留文件导致的奇怪 bug。
测试应把快速检查与慢速检查分开。快速测试在每次变更时运行(单元测试、类型检查)。完整测试包含集成检查,并在合并前运行。
用一个命令保持风格一致。简单规则是:format 修复东西,lint 抱怨东西。
最后,添加一个 smoke 检查以在你开始调试前验证基本要素:
build 后构建输出存在你的第一个垂直切片应证明应用端到端可工作,而不是仅证明 UI 看起来漂亮。那意味着一个小功能触及屏幕、逻辑和某种存储,即便存储是临时的。
挑选一个乏味但有用的功能,比如“添加笔记”或“创建任务”。保持足够小以在一个时段内完成,但足够完整以能点击查看真实状态变化。
一个好的切片包含四部分:一个路由或屏幕、一个表单、一次保存动作和一次显示。例子:一个“新建任务”页面,包含标题输入、一个调用单个函数的保存按钮,以及显示已保存任务的列表。
先用占位存储快速推进。内存数组、本地 JSON 文件或简单的存根接口都可以。关键是建立一个以后能替换的边界。如果今天的代码调用 taskRepository.save(task),将来切换到真实数据库就是小改动而不是重写。
保持 UI 朴素。跳过设计系统争论、空状态和动画。
你可以在两分钟内做的验收检查:
在你有可运行骨架和一个垂直切片后,目标转为:让故障明显并让修复迅速。这正是许多 greenfield 启动失败的地方,不是因为功能难,而是小改动开始引发意外。
为每次添加切片设定一个小的稳定门槛:
具体例子:你的第一个切片允许用户创建一个“Project”并在列表中看到它。添加一个测试:启动服务器,调用 create 端点,然后获取列表并检查新项出现。如果失败,应有明显的报错,例如“Create Project endpoint returned 500”,而不是一堆输出。
对于错误处理,坚持一小套一致的响应。验证错误返回简短信息(“Name is required”)和字段名。意外错误返回“出了点问题,请重试”。详细信息留给日志。
日志最有用时能回答:哪个请求、哪个用户(或匿名)、什么失败、出在哪儿。在开发中包含请求 id 和耗时,但默认避免打印令牌、密码、API key 或完整 payload。
添加一个小的健康检查。在 web 上可以是 /health 返回 ok;在移动端可以是一个“Connected”状态,在无法访问后端时变成“Offline”。它是你在开始调试错误前的快速信号。
浪费 greenfield 启动的最快方式是让模型生成整个应用,然后你晚点才运行。大规模生成隐藏了小错误:缺失依赖、错误的导入路径、脚本假设你有某些工具。把每次输出当作你应在几分钟内能运行的东西。
另一个陷阱是在有功能之前设计完美架构。争论文件夹名字看起来很有建树感,但没有真实切片你无法判断什么笨拙。一个支持一条工作路径的简单结构胜过未测试的巧妙结构。
命令漂移也很常见。AI 加入新的启动方式,你又加另一个测试方式,慢慢地没人知道哪条才是“标准”命令。如果有人克隆仓库问“如何运行?”,你已经在付利息。
导致最多返工的错误:
一个简单例子:你生成了一个“完整”应用(登录、主题、计费),但第一次运行失败因为缺少密钥且没有 .env.example。于是你花了一小时修复设置,而不是学习功能是否有用。
保持诚实:一条可运行命令、一个小功能、一个 env 模板,然后再扩展。
在你再添加“一个功能”之前,确认项目第二天(或别人)能轻松接手。速度本身不是目标,可预测性才是。
若有任何项不通过,现在就修复。在仓库还小的时候收紧脚本和命名代价很低。
只有能重复时,greenfield 启动才有价值。第一个垂直切片端到端运行后,把好的部分冻结到一个小模板里:相同的文件夹模式、相同的脚本名、相同的 UI/API/数据接线方式。
把你的第一个切片当作参考实现。当你开始切片 #2 时,复制形态而不是代码。如果切片 #1 有路由、处理器、数据访问层和基本测试,切片 #2 应遵循相同路径。
保持计划轻量。为接下来的 2-3 个切片写一页笔记就足够:每个切片目标和用户动作(一句话)、所需数据、“完成”检查以及需要尽早测试的风险。
然后养成维护习惯。每周一次做简短清理:收紧脚本、在 README 中更新任何新的设置步骤,并刷新 env 示例文件,以保持入门简单。
如果你偏好以聊天为首的构建循环,Koder.ai (koder.ai) 是一个可以考虑的选项,它支持规划模式、快照和回滚,并能在你想把项目带走时导出源码。
目标是一个不需思考就能运行的工作流:规划 2-3 个切片,构建一个切片,稳定,重复。