项目架构
了解这套模板的文件结构,知道你的代码应该放在哪里
顶层目录是干什么的
这套模板是一个 monorepo(单一代码仓库,一个 git 仓库里放了多个项目)。打开项目根目录,你会看到:
01mvp/
├── products/
│ ├── 01mvp/
│ │ ├── apps/web/ # 01MVP Web 站点
│ │ └── packages/ # 01MVP 产品内复用能力
│ └── onesay/
│ ├── apps/web/ # OneSay Web 站点
│ ├── apps/desktop/ # OneSay 桌面端
│ ├── apps/mobile/ # OneSay 移动端
│ └── packages/ # OneSay 产品内复用能力
├── packages/ # 跨产品共享包
│ ├── ui/ # Web UI 原语
│ ├── email/ # 邮件 provider 和模板
│ ├── logger/ # 结构化日志
│ ├── config/ # 共享 env schema
│ └── ... # 其他跨产品能力
├── tools/ # 开发工具和脚本简单理解:products/<product>/apps = 具体端,products/<product>/packages = 该产品内部复用能力,根目录 packages = 多个产品都能复用的通用零件。
为什么用 products 结构
如果你持续做 Web coding,很快就不会只有一个 app。你可能会同时维护产品官网、后台、移动端、桌面端、实验项目、模板项目和若干内部工具。把它们拆成很多 GitHub 仓库,看起来边界清楚,但通用能力会不断复制:UI 原语、登录、配置、日志、邮件、存储、AI workflow、Agent Skills、代码规范和部署经验都会散落在不同仓库里。
这套结构把所有项目放在一个长期维护的 monorepo 里:
products/<product>承载一个具体产品,产品内可以继续拆apps/*和packages/*。- 根目录
packages/*只放跨产品通用能力,保持产品无关。 - 根目录
.agents、Skills、工具链和规范由整个仓库共享。 - 每个产品有自己的 config、API、DB、auth 和前端入口,默认不会影响其它产品。
这样你可以在一个仓库里持续积累自己的工程系统:新产品复用成熟能力,老产品保留隔离边界,AI 编码工具也能读到同一套规则和上下文。
我的代码应该放在哪?
| 你的情况 | 放这里 |
|---|---|
| 页面路由 | products/01mvp/apps/web/src/routes/ |
| 页面级组合组件 | products/01mvp/apps/web/src/pages/ |
| 业务功能组件 | products/01mvp/apps/web/src/features/ |
| 只在 web 应用使用的工具逻辑 | products/01mvp/apps/web/src/lib/ 或 products/01mvp/apps/web/src/server/ |
| 这个功能只属于 01MVP,但多个 01MVP app/package 会用 | products/01mvp/packages/ 下对应的包里 |
| 这个功能多个产品都要用 | 根目录 packages/ 下对应的包里 |
| 纯 shadcn/ui 组件(按钮、弹窗等) | 用命令加到 packages/ui/,不要手改 |
shadcn/ui 是什么? 一个预制 UI 组件库,提供了按钮、输入框、对话框等 80+ 种零件。通过命令
vpx shadcn@latest add <组件名>来添加。
包(Package)是怎么工作的
每个 packages/ 或 products/<product>/packages/ 下的文件夹是一个独立的包(package)。关键规则:
- 每个包有自己的
package.json - 用
workspace:*引用内部包 — 意思是"就用本仓库的版本,别去网上下载" - 入口文件是
src/index.ts— 包对外提供的功能从这里导出 - 产品包可以引用同产品包和根共享包 — 比如
@01mvp/api可以引用@01mvp/db、@01mvp/auth和@repo/email - 根共享包不要引用产品包 —
@repo/email、@repo/ui、@repo/logger这类包必须保持产品无关
Product Package 和 Global Package 怎么分
| 放置位置 | 适合内容 | 例子 |
|---|---|---|
products/01mvp/packages/* | 只属于 01MVP,但会被 01MVP 多个端或模块复用 | api、auth、db、config、payment |
products/onesay/packages/* | 只属于 OneSay,但会被 OneSay 多个端或模块复用 | api、auth、db、config、client |
packages/* | 多个产品都可复用,不能带产品业务假设 | email、ui、logger、storage、config |
以 email 为例:发信 provider、模板渲染、发送结果类型放在 packages/email;某个产品要发什么邮件、邮件发给谁、使用什么默认发件人,放在产品自己的 api、auth 或 config 包里。
UI 组件三层结构
packages/ui/ ← 第一层:shadcn 原装组件
↓ 只通过命令添加,不要手动改
products/01mvp/apps/web/src/features/ ← 第二层:业务功能组件
↓ 登录、导航、反馈等可复用页面能力
products/01mvp/apps/web/src/pages/ ← 第三层:页面级组合一句话:通用 UI 原语留在 packages/ui,业务模块放 features,页面拼装放 pages 或具体 route。
关键规则速查
记住这几条,能避免大部分结构性错误。
- ✅ 改网站功能 → 去
products/01mvp/apps/web/src/ - ✅ 改产品内共用逻辑 → 去
products/01mvp/packages/ - ✅ 改跨产品共用逻辑 → 去根目录
packages/ - ✅ 改 API → 优先改
products/01mvp/packages/api/src/routers,Hono 特殊路由放products/01mvp/apps/web/src/server - ✅ 改数据库结构 → 改
products/01mvp/packages/db/src/schema,在products/01mvp下跑vpr db:generate和vpr db:migrate - ✅ 加共享环境变量 → 改
packages/config;加产品默认值或覆盖 → 改products/01mvp/packages/config - ❌ 不要手动改
packages/ui/里的组件 - ❌ 不要把单网站代码放到
packages/里 - ❌ 不要把密钥密码写到
packages/里
下一步
这篇文档有问题?