Monorepo 最佳实践:从工具到组件依赖全搞定
Monorepo(单一代码仓库)听起来高大上,其实就是把所有项目代码塞到一个 Git 仓库里统一管。但怎么实现?用啥工具?组件怎么构建?依赖咋处理?别急,这篇博客会一步步解答这些问题,给你一个简单又好用的最佳实践方案。
什么是 Monorepo,我了解它的实现和工具吗?
简单说,Monorepo 就像一个大超市,所有代码(前端、后端、组件库)都在一个仓库里。好处是共享方便、管理统一,但得靠工具撑起来。
实现 Monorepo 的核心问题:
- 代码组织:怎么分文件夹不乱?
- 构建速度:改一行别全重编译。
- 依赖管理:版本别冲突。
- 团队协作:多人改代码不出岔子。
工具组合:
- pnpm Workspaces:管依赖,快又省空间。
- Turborepo:管构建,聪明到只编译改动部分。
- TypeScript:代码安全,像给仓库加锁。
- ESLint/Prettier:统一规范,像超市的整理员。
例子:一个 Monorepo 可能长这样:
bash
monorepo/
├── apps/
│ ├── web/ # Next.js 应用
│ └── docs/ # 文档站点
├── packages/
│ ├── ui/ # 组件库
│ └── utils/ # 工具函数
├── pnpm-workspace.yaml
├── turbo.json
└── package.json
组件库在 Monorepo 里怎么构建?能单个更新吗?
假设 packages/ui/
是组件库,里面有 Button.tsx
和 Input.tsx
,给 apps/web/
用。组件怎么"生产"出来?改一个能不能只更新它?
构建过程:
-
定义构建脚本 :在
ui/package.json
加:json"scripts": { "build": "tsc --outDir dist" }
- TypeScript 编译成 JavaScript,输出到
dist/
。
- TypeScript 编译成 JavaScript,输出到
-
用 Turborepo 管理 :
turbo.json
定义:json{ "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] } } }
- 跑
turbo run build
,自动构建所有项目。
- 跑
单个组件更新:
- 可以!Turborepo 自带增量构建 和缓存 :
- 改了
Button.tsx
,跑turbo run build --filter=ui
。 - Turborepo 对比文件,只重新编译
Button.tsx
,Input.tsx
不动。
- 改了
- 缓存存在
.turbo/
,下次构建直接跳过没变的部分。
给应用用:
web/package.json
加"ui": "workspace:*"
,用 pnpm 链接本地最新ui
。
组件间相互依赖咋处理?
开发时,组件常互相依赖,比如 Card
用 Button
,甚至可能循环依赖。咋不卡壳?
单向依赖:
-
链接 :在
card/package.json
加:json"dependencies": { "button": "workspace:*" }
- pnpm 保证用本地
button
。
- pnpm 保证用本地
-
构建顺序 :Turborepo 的
dependsOn
确保button
先建好。
循环依赖:
- 同包 (都在
packages/ui/
):-
TypeScript 支持直接引用:
tsx// Button.tsx import { Card } from './Card'; // Card.tsx import { Button } from './Button';
-
跑
tsc
一起编译,没问题。
-
- 不同包 (
packages/button/
和packages/card/
):- 尽量打破循环:抽公共逻辑到
packages/utils/
。 - 实在不行,合并到一个包,或靠 Turborepo 尝试按顺序构建(但不保证完美)。
- 尽量打破循环:抽公共逻辑到
开发时更新:
- 改了
Button
,跑turbo run dev
,热更新让Card
立刻用上。
最佳实践:5 个实用建议
综合上面,Monorepo 的最佳实践是:
-
选对工具:
- 小团队用 Turborepo + pnpm Workspaces,简单高效。
- 大项目试 Nx 或 Bazel,功能更强。
-
结构清晰:
apps/
放应用,packages/
放共享代码。- 加
README.md
说明白。
-
依赖管理:
- 用
workspace:*
链接本地包,保持一致。
- 用
-
快速构建:
- Turborepo 的增量构建和缓存是核心。
- 用
--filter
缩小范围,但默认也够聪明。
-
自动化协作:
- 加 ESLint、Prettier、Husky 规范代码。
- 用 CI/CD(像 GitHub Actions)跑测试。
总结
Monorepo 能让代码管理更简单,但得靠工具和实践撑起来。Turborepo + pnpm 是轻量又好用的组合,组件构建靠增量更新提速,依赖问题靠链接和顺序解决。
有问题欢迎留言 Monorepo Demo!