在前端工程日益复杂的今天,代码组织方式正在成为影响团队协作效率的关键因素。无论是组件库、多业务应用、工具库还是微前端项目,使用 Monorepo(单仓库多包管理) 都正在成为越来越多团队的选择。而 Lerna 作为最成熟的 JavaScript Monorepo 管理工具之一,也成为前端团队最常用的工具链组件。
本文将带你系统了解:
- 什么是 Monorepo
- 为什么要使用 Monorepo
- 前端团队使用 Lerna 的最佳方式
- 如何从 0 到 1 搭建一个可运行的 Monorepo 项目
1. 什么是 Monorepo?
Monorepo(单一代码仓库) 是一种代码管理方式,它强调:
“多个项目、多个模块放在同一个 Git 仓库中管理。”
也就是说:
过去你可能有多个 repo,例如:
- web-app
- admin
- shared-utils
- cli
在 Monorepo 下,这些代码都集中到一个仓库,并放在 packages 或 apps 目录中。
Monorepo vs Multirepo
| 类型 | 特点 |
|---|---|
| Monorepo | 一个仓库管理所有项目和模块 |
| Multirepo | 每个项目一个仓库,单独维护 |
谁在使用 Monorepo?
- Babel、React、Angular、Ember、Jest 都在使用
- Google 内部甚至有一个 超过 2 亿行代码的 Monorepo
- Facebook、Twitter、Airbnb 均采用 Monorepo 架构
这说明:Monorepo 适合大型项目,且已被巨头验证。
2. Monorepo 的优势与局限
优势(为什么越来越多人用)
① 所有代码可见,协作效率提升
不同项目间的变动可以即时同步,无需等待依赖发布。
② 依赖统一管理,避免多项目版本不一致问题
③ 代码重用自然、简单
内部包依赖使用软链即可,无需频繁发 npm 包。
④ 测试、构建、发布流程可统一
CI/CD 一套流程覆盖所有包。
⑤ 性能优化更容易
公共依赖只需安装一次(特别是在 Lerna hoist 之后)。
缺点(需要提前考虑)
① 仓库规模变大后,Git 性能会下降:
- commit 变慢
- blame、log 变慢
- clone/fetch 也更慢
② 项目间互相引用过多会导致耦合加深
③ 权限管理困难
所有成员都能看到整个仓库。
④ tag 语义变弱
在一个 repo 内,某个 tag 对另一个模块可能毫无意义。
3. 为什么前端团队特别需要 Monorepo?
前端多项目、多包、多组件库开发非常常见:
- 多个 web 应用共享一个 utils 库
- 组件库与 demo 项目、文档项目放一起
- 微前端下多个子应用共享代码
- 工具 CLI + preset + plugin 的组合结构
这些场景用 Multirepo 会非常麻烦,而 Monorepo 天然适配。
4. Lerna:前端 Monorepo 的核心工具
Lerna 是基于 Git + npm 的 Monorepo 管理工具,它最早为了解决 Babel 的多包管理问题。
Lerna 能做什么?
| 功能 | 描述 |
|---|---|
| 依赖安装提升(Hoist) | 将多个包的公共依赖提升到根目录 |
| 软链包之间的依赖关系 | 本地包互相直接联动,无需发布 |
| 自动版本管理 | 自动生成版本号、changelog、tag |
| 批量执行命令 | 一次执行所有子包的同名 script |
| 自动发布 | npm publish 自动化处理所有包 |
简而言之: Lerna 让 Monorepo 成为可用、可维护、可扩展的工程体系。
5. Lerna 项目结构示例
my-lerna-repo
│── package.json
│── lerna.json
└── packages
│── package-1
│ └── package.json
└── package-2
└── package.json
所有子项目统一放在 packages/ 下。
6. 使用 Lerna 搭建一个 Monorepo(实战示范)
以下示例包含:
- 一个 React 前端应用
- 一个 Express 后端服务
- 支持共享依赖
- 支持统一启动 / 测试
步骤 1:初始化 Monorepo
mkdir my-lerna-project
cd my-lerna-project
lerna init --yes
生成:
my-lerna-project
├── lerna.json
├── package.json
└── packages
步骤 2:在 packages 中创建子项目
创建 React Web 应用
cd packages
npm init react-app my-web-app
创建 Express 后端服务
npm init express-app my-backend
步骤 3:清理各项目 node_modules
lerna clean
步骤 4:依赖提升(Hoist)
lerna bootstrap --hoist
此步让所有项目共享依赖,减少重复安装。
步骤 5:统一执行 script
修改子项目 package.json:
"test": "echo tests running in my-web-app"
"test": "echo test running in my-backend"
然后修改根目录 package.json:
"scripts": {
"start": "lerna run start",
"test": "lerna run test"
}
运行:
npm run test
会自动执行所有子项目 test。
步骤 6:统一版本管理
提交代码:
git add .
git commit -m "first commit"
执行版本管理:
lerna version
Lerna 会自动:
- 检测变更包
- 升级版本
- 生成 changelog
- 打 tag
- push 到远端
7. 什么时候应该使用 Monorepo + Lerna?
适合的场景:
✔ 多项目共享组件或工具库
✔ 前端多工程(admin、web、mobile…)需要统一管理
✔ 微前端架构
✔ 一个 CLI 工具包含多个插件
✔ 多个 npm 包需要联动开发
不适合的场景:
✘ 项目完全独立,各自不同的发布流程
✘ 团队规模小,没有复杂的模块共享
✘ 项目包含大量大文件(视频、模型等)
8. 总结
Lerna 为前端团队带来了一个非常高效且成熟的 Monorepo 方案,它的优势包括:
- 高效的依赖共享
- 易于管理的多包联动开发
- 自带版本与发布流程
- 更统一的工程化标准
无论是企业级前端架构还是个人项目,只要涉及 多包管理、多项目协作、依赖共享,Lerna 都是一个值得使用的工具。
文章评论