 使用changeset管理monorepo项目
使用changeset管理monorepo项目
  # 前言
monorepo(将多个项目放在同一个仓库管理)是当前大热的一个多包管理方案,但是想要用好monorepo,就需要解决依赖关系的处理以及包的构建和发布问题。下文就来介绍一下如何优雅的解决这些问题
# pnpm
强烈安利在monorepo方案中使用pnpm作为包管理器,pnpm有着天然的对monorepo的支持
- 内置workspace,有着良好的依赖关系管理,让你无需处处npm link
- 独特的依赖管理机制(将所有依赖的依赖都打平放置在.pnpm文件夹内),解决了让人诟病的幽灵依赖问题
- 特有的filter机制,让你在轻松筛选你想处理的子包
# changeset
下面介绍一下主角,changeset是一个版本管理,发布,以及changelog文件管理的工具,它可以筛选出你想发布的子包然后为这些包进行版本升级,生成changelog,以及发布新版本。
他的工作流程也很简单
- 首先筛选出想更新的包
- 然后选择更新版本号
- 接着写入更新摘要,此时会生成一个临时changelog文件
- 执行更新命令,会消耗这个临时文件生成最终的changelog,并且更新版本
- 然后执行发布命令,就完成了一个包的更新发布
由于Monorepo方案的特殊性,我们没办法直接通过commit来生成changelog,所以此时changeset这种更新方式就显得尤其有用,虽然他看上去会比较繁琐。
下面通过一个例子来真实感受一下
首先通过pnpm创建一个monorepo工程并创建几个子包
pnpm-changsets-monorepo-example
├── LICENSE
├── package.json
├── packages
|  ├── a
|  |  ├── CHANGELOG.md
|  |  ├── index.ts
|  |  └── package.json
|  ├── b
|  |  ├── CHANGELOG.md
|  |  ├── index.ts
|  |  └── package.json
|  └── c
|     ├── CHANGELOG.md
|     ├── index.ts
|     └── package.json
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
几个子包的依赖关系如下: c包独立,a包是b包的依赖
这里再提一点pnpm的强大之处,例如此时我们a包和b包有更新,需要发版。此时因为a包和b包之间存在依赖关系,正常来说我们需要等待a包构建发布完毕再去发布b包。
而pnpm其实早已帮我们处理好了这一切,当我们同时构建这两个包的时候,pnpm内部会自行检测依赖关系,并且先执行被依赖的包的构建最后再执行主包的构建。
回归正题,此时我们有三个包,如果想要更新c包,并且为他生成他自己的changelog。
首先安装一下changeset
pnpm i @changesets/cli
然后执行初始化命令
changeset init
执行后你就会看到在根目录生成了.changeset文件夹,里面有changeset的配置
{
  "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
  "changelog": "@changesets/cli/changelog",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "public",
  "baseBranch": "master", //这里修改成你的主分支名
  "updateInternalDependencies": "patch",
  "ignore": []
}
2
3
4
5
6
7
8
9
10
11
12
开始更新,先执行
changeset 或者 npx changeset
执行次命令后控制台就会罗列出package下的所有子包,按空格选择你想要更新的包,然后按回车确定
这时候控制台会展示需要更新的版本号,是大版本还是小补丁,一共三个选择,对应了语义化版本号管理的三个值。
但是这里不是罗列出来让你选了,而是你要一个一个去确认,不是你想跟新的位数直接输入n跳过就行了。
当版本号确定后就会出现让你输入摘要,这个摘要就是最后写入changelog的内容
输入完摘要就会生成一个临时的md文件。
这个时候执行以下命令消耗掉这个临时文件
changeset version
这样就可以看到版本号更新了,以及changelog也生成了。
发布版本
changeset publish
以上就是一个完整的使用过程了