Skip to content

🧐 什么是 Monorepo?

Monorepo (Monolithic Repository),中文常称为**“单体仓库”**。

用最通俗的话说:把所有的鸡蛋(项目)都放在同一个篮子(Git 仓库)里管理。

  • 以前 (Polyrepo / Multi-repo):
    • 你有一个后台项目 admin-repo
    • 你有一个用户端项目 h5-repo
    • 你有一个组件库项目 ui-lib-repo
    • 现状:这里有 3 个独立的 Git 仓库。
  • 现在 (Monorepo):
    • 你有一个大仓库 my-company-repo
    • 文件夹 apps/admin 是后台。
    • 文件夹 apps/h5 是用户端。
    • 文件夹 packages/ui-lib 是组件库。
    • 现状:所有代码都在这 1 个 Git 仓库里。

💡 为什么要用 Monorepo?解决了什么痛点?

想象一下,你现在的公司有 3 个前端项目,它们都用了同一个 Button 组件。

❌ 传统模式 (Polyrepo) 的噩梦:

  1. 你发现 Button 组件有个 Bug。
  2. 你去 ui-lib 仓库修好它,发布版本 v1.0.1 到 npm。
  3. 你去 admin 仓库,运行 npm update,测试,提交代码。
  4. 你去 h5 仓库,运行 npm update,测试,提交代码。
  5. 痛点:流程繁琐,版本不同步(有的项目忘了升),本地调试困难(你需要 npm link,这玩意儿经常出问题)。

✅ Monorepo 模式的爽点:

  1. 你在 packages/ui-lib 里修好 Button
  2. 因为所有项目都在一起,apps/adminapps/h5瞬间就感知到了变化(直接引用本地文件路径,甚至不需要发 npm 包)。
  3. 你运行一次测试命令,确保所有受影响的项目都通过。
  4. 一个 Commit 提交所有更改。
  5. 优势代码共享极致简单,版本管理统一,原子化提交。

🏗️ 标准的 Monorepo 目录结构

一个现代前端 Monorepo 通常长这样:

Plaintext

my-monorepo/
├── package.json          # 根配置
├── pnpm-workspace.yaml   # pnpm 的工作区配置(告诉它哪些是子项目)
├── turbo.json            # Turborepo 构建缓存配置

├── apps/                 # 🚀 应用程序目录 (业务代码)
│   ├── web/              # Next.js 官网
│   ├── admin/            # React + Vite 后台管理
│   └── docs/             # 文档站点

└── packages/             # 📦 共享库目录 (基建代码)
    ├── ui/               # 共享 UI 组件库 (Button, Input)
    ├── utils/            # 共享工具函数 (formatDate, currency)
    ├── tsconfig/         # 共享 TS 配置 (所有项目统一标准)
    └── eslint-config/    # 共享 Lint 配置

🛠️ 怎么实现?(工具链选择)

Monorepo 不是靠手动复制粘贴实现的,它需要工具支持。目前业界最主流的方案是:

pnpm + Turborepo

  1. pnpm (包管理):
    • 它是 Monorepo 的基石。它的 Workspaces (工作区) 功能,允许你在根目录下 npm install 一次,它就会帮你在所有子项目里把依赖装好,并把 packages/ui 自动软链接(Symlink)到 apps/web 里。
  2. Turborepo (构建工具):
    • 由 Vercel 开发。它的核心作用是**“快”**。
    • 缓存机制:如果你在 apps/web 里改了一行代码,Turborepo 知道 apps/admin 没变,构建时会直接复用缓存,跳过 admin 的构建。
    • 并行执行:它可以同时跑所有项目的 Lint、Test 和 Build。

⚠️ 架构师的“避坑”指南

Monorepo 虽然好,但也不是没有代价的:

  1. 仓库体积大: 随着时间推移,.git 会变得巨大。
    • 解法:使用 Git LFS 管理大文件,或者只 clone 最近的 commit (shallow clone)。
  2. 权限控制难: 以前不同团队只能看自己的仓库,现在大家都在一个仓库里,对于极其注重保密的公司可能是问题。
    • 解法:通常通过 Code Owner 机制来控制谁能合并哪个文件夹的代码。
  3. CI/CD 变慢: 既然代码都在一起,难道改一行代码就要把所有项目重新部署一遍吗?
    • 解法:必须配合 TurborepoNx 这样的工具,实现“按需构建”(Affected Build)。只构建和部署受影响的应用。