【直播切片工作台】第3章:Monorepo 工程结构

简介: 本章详解Monorepo工程结构:pnpm workspace统一管理React前端,Go后端自治(go.mod),根package.json串联命令。目录严格分层——`cmd`/`internal`/`docker`/`docs`边界清晰,前后端路径与职责对仗,支持全栈并行开发。(239字)

第3章:Monorepo 工程结构

本章从仓库物理布局出发,讲清 pnpm workspace 如何同时管理 Go 后端与 React 前端、根 package.json 承担什么职责、以及 cmd / internal / docker / docs 的边界约定。理解目录约定后,任何新成员都能凭文件路径推断职责归属。

流程

仓库根目录只有六个条目:backend/frontend/docs/LICENSE、根 package.jsonpnpm-workspace.yaml。pnpm 把 frontend(还有未来可能的其他 JS 包)纳入统一 workspace 管理;Go 后端自带 go.mod,与 pnpm 互不干涉——两者通过根 package.json 的 scripts 串成一条命令链(例如一键安装、一键构建)。

后端内部遵循 Go 社区标准布局:cmd/ 放可执行入口(webserver 主服务、envinit 初始化工具、test 试验场),internal/ 放全部私有代码(编译器强制禁止外部导入,天然模块边界),docker/ 放镜像与编排,migrations/ 放 SQL 参考脚本,backend/docs/ 放 swaggo 生成的 Swagger 产物。前端的 src/ 按 pages / services / utils / components / layouts / routes / context / hooks 分层,与后端的 handler / service 命名形成心智对仗。

输入是「一个人维护全栈」的现实,输出是一套前端一条 pnpm 命令、后端一条 go 命令即可各自开发测试的并行工作流:

flowchart TD
    R[仓库根] --> B[backend: go.mod 自治]
    R --> F[frontend: pnpm workspace 包]
    R --> P[根 package.json: 串联脚本]
    B --> C1[cmd/webserver · cmd/envinit]
    B --> C2[internal/ 12 个领域包]
    F --> C3[src/pages 业务页面]
    F --> C4[src/services API 层]

实现

几个值得注意的工程细节:

  • .github/workflows/ci.yml 在根目录而非 backend,说明 CI 视角是整个 monorepo(第 50 章)。
  • .husky/pre-commit + lint-staged 提交前只对暂存文件跑 lint/format,前端代码质量门禁前移。
  • backend/internal/config/config.yaml 被 gitignore,仓库提供 config.yaml.example:本地密钥永不入库,示例文件与新配置项同步维护是仓库纪律(README 明确要求)。
  • .cursor/rules/toast-notify.mdc:为 AI 辅助编码准备的规则文件,约束前端提示组件的使用方式——工具链配置也是工程的一部分。
  • cmd/test/main.go 充当临时实验入口,避免污染正式命令;正式入口保持极薄(webserver 的 main 只有装配逻辑,见第 5 章)。

前端的路径别名 ~/ 指向 src/vite.config.mts + tsconfig.json 双处配置),所以 import 全是 ~/services/http 风格,杜绝 ../../ 相对路径漂移。

📌 设计决策

  • pnpm workspace 而非把前端塞进根 package.json:版本与依赖隔离清晰,未来可加 e2e 包、shared-types 包。
  • backend 与 frontend 完全不共享构建产物:前后端仅通过 OpenAPI 契约(Swagger 页面)耦合,是典型的契约优先协作。
  • internal/ 而非 pkg/(顶层):所有代码都是应用私有,没有对外开源 SDK 的诉求。

代码示例

workspace 定义极简,只圈定 JS 侧:

# pnpm-workspace.yaml
packages:
  - frontend

根 package.json 把两侧常用动作收敛为脚本入口(节选示意):

{
   
  "name": "live-mixer",
  "private": true,
  "scripts": {
   
    "dev": "pnpm --filter base-ui dev",
    "build": "pnpm --filter base-ui build",
    "test": "pnpm --filter base-ui test"
  },
  "devDependencies": {
   
    "husky": "^9.0.0",
    "lint-staged": "^15.5.1"
  }
}

小结

  • 仓库 = Go 自治模块 + pnpm workspace 前端 + 根级 CI/Husky 门禁。
  • cmd/ 薄入口、internal/ 强边界、配置示例文件同步是三条硬纪律。
  • 前后端仅通过 OpenAPI 契约协作,目录结构对仗便于全栈切换。

思考题

  1. 若要抽出前后端共享的 TypeScript 类型(按 Swagger 生成),workspace 结构应如何扩展?
  2. cmd/test 这种试验入口长期存在会有什么风险?更好的替代是什么?

项目信息

  • GitHub仓库:github.com/Chyona/live-mixer
  • 项目案例:gogoshine.com
相关文章
人工智能 缓存 前端开发
12432 70
人工智能 自然语言处理 安全
1316 0
Web App开发 人工智能 API
1537 2
人工智能 JavaScript 开发工具
4907 0
人工智能 Java BI
1631 1
人工智能 JavaScript 测试技术
2572 2
开发工具 Swift git
2000 6
人工智能 JavaScript 测试技术
1239 4

热门文章

最新文章