前言
monorepo
是什么?
正常情况下,我们一个前端项目只会有一个package.json
,比如做一个设备管理系统,这个项目只负责实现设备管理系统相关的功能。
但是如果我们需要做公司内部公共库的项目,比如我的公司是comp
,
- 我需要一个
comp-ui
项目,存放公司内部封装的常用组件 - 我需要一个
comp-util
项目,存放公司内部常用的公共方法 - 我需要一个
comp-icon
项目,存放公司内部画的图标库。 - 我需要一个
comp-docs
项目,存放该公共库的使用示例文档。 - .....
这些项目可能会互相依赖,比如comp-ui
要依赖comp-util
、comp-icon
、comp-router
,comp-docs
需要依赖comp-ui
。
如果每个项目都单独创建一个git
仓库管理,那么当comp-util
做了修改,就必须先打包升版发布,然后comp-ui
、comp-docs
需要分别更新各自项目的依赖,十分的麻烦。
monorepo
就是为了解决这个痛点,将所有的comp-xx
项目放在一个仓库管理。
lerna
则是解决monorepo
项目管理的便捷性,当其中一个子项目更新了之后,不需要更新仓库中其他项目对该子项目的依赖,而是会自动生效!
当项目发版的时候,lerna
会对本次有修改的子项目一起升版,并且在git
提交使用tag
标记,以便于我们以后查看每个版本的代码,如下图所示:

当然,可能有的同学还是会想说,这么麻烦干嘛?我不这么分项目,所有东西放在一个项目里不就得了!
其实完全也可以这么做,无非就是如果其他项目只想用到公共方法comp-util
,就不得不把全部依赖引入!
为什么选择lerna
lerna
最初是Babel团队
内部使用管理monorepo
项目,之后开源供社区使用,团队强大,并且许多大型的项目也是使用lerna
做管理,比如React
和Jest
,
lerna
近期升级到8
版本,进一步降低了用户的上手成本,简化了项目管理。
总的来说lerna
是一个强大的工具,适用于管理大型JavaScript项目中的多个包,通过其提供的命令和功能,能够简化多包存储库的管理和操作,提高开发效率和代码质量。
开始使用
1. 全局安装
markdown
npm install -g lerna,yarn
lerna
与yarn
有着非常好的适配性,所以lerna
项目十分推荐使用yarn
作为包管理工具。
2. 进入一个空文件夹,执行初始化项目命令
csharp
lerna init
项目初始化完成,并且依赖node_modules
已经安装好了!
可以看到项目的初始结构! 由于默认使用的是
npm
安装依赖,我们可以将package-lock.json
删除,执行
yarn install
将包管理工具切换为yarn
,得到如下结构的项目。

打开package.json
文件查看,内容如下:
json
{
"name": "root",
// 根项目是私有的,并不需要打包发布,仅作为多个子项目包的管理
"private": true,
// 子项目是在packages文件夹下,因为目前一个子项目都没有,所以也没有packages文件夹
"workspaces": [
"packages/*"
],
"dependencies": {},
"devDependencies": {
"lerna": "^8.1.2"
}
}
3. 新增模块
monorepo
的项目,推荐使用作用域包的命名方式,也就是@组织名/包名
,这样不容易和别人的包名重复,并且一目了然。
接下来我们新增一个@comp/ui
子项目,看看
sql
lerna create @comp/ui

可以看到默认创建的子项目是入口是lib/ui.js
,是一个js
项目,如果想要开发一个vue
或者react
组件库,可以自行修改项目为对应的结构。
这里,我再增加一个子项目@comp/util
,最终的结构如下:

值得一提的是,如果我们的包最终不是发布到npm,而是公司内部的仓库中,可以修改package.json
的publishConfig.registry
的地址为公司内部地址。
4. 子模块增加依赖
如果需要为子模块增加依赖,比如@comp/util
需要用到axios
依赖,执行
sql
yarn workspace @comp/util add axios
安装完成后,我们发现在packages/util
下面,并没有node_modules
文件夹,axios
的依赖是安装到了根项目的node_modules
下,这样,所有的子项目,依赖就可以共用。
5. 全局依赖
如果你拿到一个lerna
管理的项目,安装依赖的时候只需要在根目录执行
markdown
yarn install
lerna
就会自动安装全部子项目的依赖,十分方便。
6. 发布版本
首先需要将本地所有的更改都提交到git仓库。
其次执行npm login
登录。
最后执行lerna publish
,根据提示操作即可。
lerna
会提供给我们选择哪种版本类型的升级。

最后就可以在自己的仓库看到对应版本的tag,并且可以在npm上看到自己发布的包了,之后继续迭代我们的项目即可。