monorepo
monorepo
什么是 monorepo 和 multirepo
monorepo 有啥优缺点
基于 lerna 实践 monorepo
构建
- bazel
- Rollup react
- Gulp babel
- MakeFile
Lerna
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.
常用 lerna 命令
只介绍一些常用命令。详细命令请查看 lerna 的 readme 文档
lerna init
初始化 monorepo 项目,会新建
lerna.json
//默认是固定模式。{"packages":["packages/*"],"version":"0.0.0"}注意:如果想要使用独立模式。
lerna init --independent
。则生成的lerna.json
中的version
字段为independent
而不是0.0.0
lerna version
固定模式。会更新根目录 changelog,并且 publishconfig
独立模式
只有当前 packge 改变 changelog 才会改变。不会影响其他 package
发布工作区中自上次发布有更改的 package。包的版本可以自定义,也可以根据一些条件自动生成。这里我只介绍根据 commit 提交信息自动生成 package 版本,其它可以点击链接查看详情
lerna version --conventional-commits
按照常规提交规范自动生成 package version。
fix
类型提交转换为PATCH
发行版。feat
类型提交转换为MINOR
发行版。BREAKING CHANGE
无论类型如何,提交中的提交都应转换为MAJOR
发行版。提示:不管是独立还是固定模式,某个包变化。其它 package 依赖该包在发布的时候都会更新 version。只是两个模式不同的是 major 的变化是否统一
注意:在 commir 的 footer 中以
BREAKING CHANGE:
开头就是重大更新一般 package 的格式是 major.minor.patch 组成。例子:1.0.0
默认模式:固定模式下 Fixed/Locked mode (default)
- 某个 package 有重大更新,工作区所有 package 都会增加一个 major 版本
- 根目录 changelog 会改变
- lerna.json 中 version 的 messge 的
S%
版本会随着 version 变化。
独立模式
根目录 changelog 不会改变
lerna.json 中 version 的 messge 的
S%
版本不会由 version 代替。任然是s%
。(参考:lerna version -m)建议独立模式使用
lerna version --conventional-commits -m "chore(release): publish 版本号"
//lerna.json{"command": {"version": {//lerna version只能在master分支中使用"allowBranch": ["master"],//同lerna version -m "chore(release): publish %s"。默认lerna version生成的commit是没有遵循conventional commit规范的。使用这个可以指定发布的commitmsg"message": "chore(release): publish %s",//检测更改的软件包时,忽略与glob匹配的文件中的更改"ignoreChanges": ["*.md","*.txt"//一些测试文件、和发布无关的文件。。。]}}}配合 yarn workspace 之后,一般使用
yarn install
代替lerna bootstrap
// lerna.json{"npmClient":"yarn","useWorkspaces":true}//根目录 package.json{"workspaces": ["packages/*"],}在工作区中运行任意命令,使用
--
传递参数运行工作区中某个 script 脚本(只针对具有这个 script 脚本的包执行),使用
--
传递参数lerna import path --preserve-commit
将当前已有的库添加到工作区里面。会保留 commit 信息(包括原始提交人和作者)。不使用
--preserve-commit
则会导致提交人更改为当前 import 的人。如果是 scope package(@xxx/some-package),则需要在
package
的package.json
指定publishConfig.access
字段//package的package.json文件{"publishConfig": {//指定范围包的访问权限 不设置public,就付钱升级npm账号吧。"access": "public",//指定发布的目录 可以配合.npmignore"directory": ""}}需提前
npm login
,使用npm whoami
判断是否登录成功。没问题使用lerna publish from-package
发布包
Yarn workspace
yarn config list
中没有设置 workspaces-experimental 则使用以下命令开启
yarn config set workspaces-experimental true
使用 yarn workspace 主要是可以将各个 package 相同的包提升到根目录中。避免每个 package 都 install 一个包。
使用工作区之后,package 没有自己的 yarn.lock 文件。所有 packages 共用根目录的 yarn.lock 文件
常用命令
当第一次安装 package 提示找不到 package。可以试着写死版本
工作区
给某个 package 添加包
将
react
和react-dom
作为devDependencies
加到packages/awesome-package/package.json
中yarn workspace awesome-package add react react-dom --dev
注意:第一次(some-package 还未发布到 npm 上)使用 lerna add some-package --scope=packaget
删除某个 package 的某个包
从
packages/web-project/package.json
中移除some-package
yarn workspace web-project remove some-package --save
给所有 package 添加某个包
yarn workspace add some-package
使用
lerna add package
,一次只能添加一个
4. 给所有 package 删除某个包yarn workspace remove some-package
根目录
根目录添加包
yarn add -W some-packeages
根目录删除包
yarn remove -S some-package
lerna 配合 yarn workspace
扩展
常见问题
发布测试包 command
lerna version --conventional-prerelease --conventional-commits --no-changelog -m "chore(release): 发布测试版本"
a
lerna publish from-package
为什么 lerna.json 设置了
command.version.message
为chore(release): %s
无效只有在固定模式才会替换%s
如何自定义 changelog