1、项目中遇到的问题
最近在开发小程序的UI库,组件拆分力度比较细,都是一个个的单独的package包, 模块的复用性和灵活性达到最大化,实操的过程当中,会遇到如下问题:node
一、维护成本较高,任何的基层 repo 版本变动,将会引起一系列上层封装版本变更git
二、版本发布npm包,代码不够规范,不少都不是发布mastergithub
三、一个包一个repo,每次须要找到对应的仓库npm
四、changelog 梳理异常折腾,有些基本上都没有changelogjson
基于上面的问题,有没有一种能解决咱们问题的技术呢?bootstrap
2、Monorepo 项目管理
Monorepo 的全称是 monolithic repository,即单体式仓库,与之对应的是 Multirepo(multiple repository),这里的“单”和“多”是指每一个仓库中所管理的模块数量。小程序
Multirepo 是比较传统的作法,即每个 package 都单独用一个仓库来进行管理。例如:Rollup, ...,上面遇到问题的也是采用的这种方式。babel
Monorep 是把全部相关的 package 都放在一个仓库里进行管理,每一个 package 独立发布。例如:React, Angular, Babel, Jest, Umijs, Vue ...app
Multirepo和Monorep优劣势对好比下:工具
3、Monorepo 管理工具Lerna
Lerna 是一个管理多个 npm 模块的工具,是 Babel 本身用来维护本身的 Monorepo 并开源出的一个项目。优化维护多包的工做流,解决多个包互相依赖,且发布须要手动维护多个包的问题。
Lerna 如今已经被不少著名的项目组织使用,如:Babel, React, Vue, Angular, Ember, Meteor, Jest 。
一、lerna模式
在初始化一个项目以前咱们必需要清楚,lerna 对管理 monoRepo 有两种模式
- Fixed/Locked mode (default)
- Independent mode
Fixed/Locked 模式
: 官方默认推荐模式,当前 babel 的项目管理模式,在该模式下全部的 packages 都会遵循一个版本号,该版本号维护在 lerna.json
的 version 字段中,当须要版本发布时 lerna publish
时,若是一个模块和上一次 release 相比有过变动的话,会自动发布一个新版本。
这种模式的问题在于:当有一个 major 变动的时候,全部 packages 都会都会有一个新的 major 版本。
维护团队认为:版本是一种很是 cheap 的东西,因此没必要纠结。
Independent 模式
: 在该模式下全部 packages 新版本的生成将会由开发者决定,lerna.json
的 version 字段也会随之失效。这种模式的弊端很是明显,开发者必需要很是清晰该发什么版本,事实上在多人协做项目上很难作到这一点。
二、如何使用lerna
a、全局安装lerna
npm i -g lerna
b、初始化项目
mkdir lerna-repo && cd $_ npx lerna init
初始目录以下,接着进行开发
c、创建 packages 的依赖关系
lerna bootstrap
这个命令会安装好全部 packages 的依赖,以及创建好 packages 相互依赖的软链接
正式流程为:
- 安装全部 package 的外部依赖.
- 对存在相互依赖的 package 建立软链接.
- 在全部已经 bootstrapped 的 package 中执行 npm run prepublish.
- 在全部已经 bootstrapped 的 package 中执行 npm run prepare.
固然咱们使用 --hoist 来把每一个 package 下的依赖包都提高到工程根目录,来下降安装以及管理的成本。
lerna bootstrap --hoist
若是之前安装了依赖,发生改动,能够先清理一下安装的依赖便可:
lerna clean
d、发布版本
lerna publish
正式流程为:
- 执行 lerna updated 来肯定哪些包须要被发布.
- 若有必要会升级 lerna.json 的 version 字段。
- 对全部须要 update 的 package 进行版本的更新,并写入他们的 package.json.
- 对全部须要 update 的 package 进行依赖申明 specified with a
caret (^)
. - 建立一个 git commit 和 tag
- 把包发布至 npm
4、生成changelog
因为本项目后期须要对外,使用基于PR来生成changelog的lerna-changelog,项目建议使用cz-lerna-changelog 。
一、安装lerna-changelog
npm install lerna-changelog --save-dev
二、修改 lerna.josn
须要新增相关 lerna-changelog 所须要的配置,此处参考babel配置
"changelog": { "repo": "binglingwy/lerna-test-new", "cacheDir": ".changelog", "labels": { "PR: Breaking Change :boom:": ":boom: Breaking Change", "PR: New Feature :rocket:": ":rocket: New Feature", "PR: Bug Fix :bug:": ":bug: Bug Fix", "PR: Docs :memo:": ":memo: Documentation", "PR: Internal :house:": ":house: Internal", "PR: Performance :running_woman:": ":running_woman: Performance" } },
注意:labels 的 key 必须在 github 的仓库内定义好
三、设置令牌
export GITHUB_AUTH="..."
GITHUB_AUTH 的 token 字段能够在github 申请 token 得到。
四、建立个PR
a、拉一个新的分支
b、修改代码并提交,提交记录记得关联issues,例如:
git commit -a -m "module-base: bug fixed, Close #1"
c、推送代码,并在github上建立PR
注意:在建立 pr 时必定要选择对应的 label ,label需提早在github建好,跟lerna.josn一致
d、合并pr到主干,切换到本地master,生成changelog
node_modules/.bin/lerna-changelog
e、一旦 publish 后咱们即可以建立 release note,效果以下
固然也能够在生成文件CHANGELOG.md,在lerna.json中添加conventionalCommits配置:
"command": { "publish": { "allowBranch": "master", "conventionalCommits": true } }
配置后,当咱们执行lerna publish
后会在项目根目录以及每一个packages
包下,生成CHANGELOG.md
。
注意: 只有符合约定的commit
提交才能正确生成CHANGELOG.md
文件。
参考文章
Lerna 官网:https://github.com/lerna/lerna/blob/master/README.md
lerna-changelog:https://github.com/lerna/lerna-changelog
手摸手教你玩转 Lerna: http://www.uedlinker.com/2018/08/17/lerna-trainning/