平常的项目由于依赖包不多基本都是一个依赖使用一个仓库,但如果开发较为大型的项目,或者项目组件抽出的比较细,这种场景下一个依赖使用一个仓库就加大了管理难度。Monorepo就是解决这样场景而产生的,像是BabelVue3React都是使用这样的管理方式。

Monorepo优劣势

优势

1、方便代码管理

依赖数据一旦多起来时,众多的项目仓库会使得修改关联功能需要在几个仓库间切换。

依赖分散,管理上需要更多的精力,如果缺乏持续性管理,可能导致功能模块定义偏差。或是各个项目内容易存在过多功能相同的代码,也不方便提取复用。

如果文档整理不全,有可能出现交接时导致仓库遗失的情况。

2、分支构建统一

由于模块数众多,各个模块的版本管理与模块分支对应也会越来越复杂。

由于模块数众多,可能因为某个小模块的代码修改而未被注意到,导致不容易检测。

3、方便复用与测试

所有依赖同在一个仓库,方便复用、修改、测试。

劣势

1、不利于权限管理

由于所有代码都放在同一个仓库,不利于做权限管理,对于项目不熟悉的人容易修改到其他地方代码。

2、仓库体积大

由于所有代码同放一个仓库,可能有时候修改一个小功能需要拉下完整的仓库。

如果是引入临时开发者或是新人,不利于快速上手项目。

Lerna、Yarn与Monorepo关系

文章标题提到YarnLerna这是比较主流的Monorepo仓库管理工具。

YarnFacebook为了解决NPM使用中诸多问题而创立的包管理工具,其中自带了workspaces功能,可以通过配置根目录的package.json来实现Monorepo仓库管理。但是Yarn只解决了包管理的问题,对于包内的依赖、发版依然麻烦,此时就需要另一个工具Lerna

Lerna就是Babel项目在包管理时发现处理依赖等诸多不便,因此产生的管理工具。

Monorepo应用

安装

安装lernayarn

npm i -g lerna yarn

初始化项目

进入目录,执行初始化命令

lerna init

lerna init --independent // 创建independent模式的项目

执行后在项目下会多出package.jsonlerna.json文件和packages目录。

packages目录就是存放多个项目的目录,在配置文件中可以修改。

package.json可以添加一些配置,

"private": true, // 私有,主工程不会被发布
"workspaces": [ // 声明子package项目路径,yarn会读取使用
    "packages/*"
]

lerna.json可以配置一些参数:

  • version: 版本号
  • npmClient: 使用指定的包管理器,值为yarnnpm。默认为npm
  • command.publish.ignoreChanges: 值为数组,配置忽略变更的文件或目录
  • command.publish.message: 自定义发布新版的提交信息,参看@lerna/version (翻译版@lerna/version
  • command.publish.registry: 配置发布的自定义仓库地址
  • command.bootstrap.ignore: 值为数组,lerna bootstrap命令忽略的包
  • command.bootstrap.npmClientArgs: 值为数组,lerna bootstrap命令时,会将此变量值传递给npm install
  • command.bootstrap.scope: 值为数组,lerna bootstrap命令针对哪些包执行
  • packages: 值为数组,所有子包的路径

依赖管理

安装依赖

只要在项目主目录下执行

yarn install

yarn会自动读取workspace配置,就能自动安装、处理、软链接各个子包的依赖,统一放在根目录下。

也可以使用lerna的安装命令

lerna bootstrap

但可能不如yarn的包管理机制好用,可以看这篇文章《Lerna的依赖管理及hoisting浅析》

增删依赖

主项目添加依赖

yarn add -W -D [packageName]

删除公共依赖

yarn remove -W -D [packageName]

给所有子项目增删依赖

yarn workspaces add [packageName]
yarn workspaces remove [packageName]

给某个项目增删依赖

yarn workspace [packageNameA] add [packageNameB] // packageNameA是指定安装依赖的包名,packageNameB是公共的包名或者项目内的包名
yarn workspace [packageName] remove [packageName]

当项目依赖凌乱的时候,可以使用命令清理依赖

lerna clean

其余还有一些命令

// 如果 package.json 中设置了 "private": true 的不会展示

lerna ls // 列出仓库中包信息
lerna changed // 查看项目变动
lerna exec // 执行命令
yarn workspaces info // 查看项目内信息

构建发布

使用lerna run命令构建项目

lerna run build // 会执行子包中build命令构建

lerna同时提供了快速版本发布功能

lerna version

执行后会自动识别修改的包,然后修改版本号。如果当前代码有未提交的修改记录则禁止更新。

使用带--conventional-commits参数命令,可以支持Git的提交记录来自动更新版本号

lerna version --conventional-commits

详细的参数文档可以看@lerna/version或者@lerna/version翻译

之后可以用lerna publish发布新包

lerna publish from-git // 显式发布在当前提交中标记的包

详细的参数文档可以看@lerna/publish或者@lerna/publish翻译

03-05 16:33