一、背景概述
前端目前基于Monorepo
架构的npm包开发很普遍,在开发完毕后,我们需要对包进行版本号升级,并且部署,这些操作如果是手动来操作的话,很麻烦,而且容易出错。
例如有这样的场景:
-apps
-packages-core-layout-plugins
我们在发版的时候,需要手动去更改core
、layout
、plugins
三个插件包的版本号。
并且如果要查看每个包的变更迭代的话,需要单独查看子包的git log
进行查看,但是有时git log
的记录不代表版本真正的迭代变更,最常见的是子包的一个特性开发,会分成多个commit
去提交。
以上场景我们可以使用changeset
来解决,查看:官网地址。
二、正常模式
1、安装 changesets
进入Monorepo
项目根目录,执行下列命令:
# 安装 changesets
pnpm add -W -D @changesets/cli
2、初始化项目
# 初始化 changesets 文件夹
npx changeset init
#pnpm exec changeset init //pnpm的话执行pnpm exec,效果一致
执行完初始化命令后,会在工程的根目录下生成 .changeset
目录,其中的 config.json
作为默认的 changeset
的配置文件。
config.json
代码如下:
{"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json","changelog": "@changesets/cli/changelog","commit": false,"fixed": [],"linked": [],"access": "restricted","baseBranch": "personal-wjb","updateInternalDependencies": "patch","ignore": ["docs", "micro-app", "umi3", "umi4"]
}
配置说明:
-
changelog
:changelog 生成方式 -
commit
: 不要让changeset
在publish
的时候帮我们做git add
-
linked
: 配置哪些包要共享版本 -
access
: 公私有安全设定,内网建议 restricted ,开源使用 public -
baseBranch
: 项目主分支 -
updateInternalDependencies
: 确保某包依赖的包发生 upgrade,该包也要发生 version upgrade 的衡量单位(量级) -
ignore
: 不需要变动 version 的包 -
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH
: 在每次 version 变动时一定无理由 patch 抬升依赖他的那些包的版本,防止陷入 major 优先的未更新问题
更多配置说明,请查看【changeset官网】
3、配置package.json
"changeset": "changeset",
"packages-version": "changeset version",
"publish:only": "changeset publish --registry=指定仓地址"
4、提交变更集
执行pnpm changeset
,进入交互式变更集设置命令行:
这里需要注意的是,版本的选择一共有三种类型,分别是 patch
、minor
和 major
,严格遵循 semver 规范。
可以简单按照下图这么理解:
5、升级版本号
当我们开发完成一个特性需求之后,我们的.changeset
目录下可能会缓存了很多的变更记录,这时候我们要准备发版,就需要进行升级版本号操作,升级完后,.changeset
目录中缓存的所有UNIQUE_ID.md
文件会被清空。
执行pnpm packages-version
,由于上面【步骤4】选择了补丁版本(patch),所以只会升级第三位版本号,变成1.0.1
。
{- "version": "1.0.0",+ "version": "1.0.1",
}
然后如果有些包不需要升级版本号的话,可以通过设置/changeset/config.json
中的ignore
属性进行过滤。或者直接设置待过滤包的package.json
,添加private:true
设置。
命令执行完成后,会在每个需要升级的包目录下,自动生成CHANGELOG.md
文件,会记录当前包的所有的变更。
6、部署
执行pnpm publish:only
,会自动部署到指定的npm仓。之后就可以正常使用。
设置子包中的
package.json
中的publishConfig.registry=npm仓
,可以指定部署目标仓地址。
三、预发布模式
1、进入预发布模式
pnpm exec changeset pre enter <preid>
preid
为预发布版本标记,例如 alpha
、beta
等,默认值为 next
。
我们执行pnpm exec changeset pre enter next
,执行成功后会在.changeset
中新增pre.json
文件。
//pre.json
{"mode": "pre","tag": "next","initialVersions": {"micro-app": "1.0.0","@my-package/components": "1.0.17","@my-package/hooks": "1.0.5","@my-package/utils": "1.0.3"},"changesets": []
}
2、开发
进入预发布模式后,我们可以进行正常的代码开发,和变更集提交。
我们这里添加了两个变更集,如图:
<!-- fluffy-seahorses-watch.md -->
---
"@my-package/components": patch
"@my-package/utils": patch
---修改路由
<!-- breezy-maps-listen.md -->
---
"@my-package/hooks": patch
"@my-package/utils": patch
---修改路由配置-2
3、升级版本号
执行:changeset version
,由于是在【预发布模式】,更新的版本号会加上<preid>
标记。
例如:
预发布模式下,后续的版本号升级都会更新末尾的索引号。按照这个逻辑,下次@my-package/components
更新的版本号就是1.0.18-nest.1
,
如图:
更新版本号后,pre.json
中的内容也会更新:
//pre.json
{"mode": "pre","tag": "next","initialVersions": {"micro-app": "1.0.0","@my-package/components": "1.0.18-next.1","@my-package/hooks": "1.0.5","@my-package/utils": "1.0.3"},"changesets": ["breezy-maps-listen","fluffy-seahorses-watch","tender-cars-taste"]
}
changesets
:中记录了变更集文件文件的文件名ID。
***注意:*为了使项目能够通过变更集进行跟踪,它需要一个最小的 package.json
,其中至少包含name
, private
和version
。否则这里升级版本号会报错。如图:
4、退出预发布模式
执行:pnpm exec changeset pre exit
命令,提示如下:
可以看到执行成功后,控制台打印出提示:再次changeset version
后,就会切换到正常的版本号。
5、切换到正常版本号
执行命令pnpm exec changeset version
,执行成功后系统会做以下操作:
- 删除
pre.json
和.changeset
目录下的所有变更集文件。 - 将所有子包的版本号切换成正式版本号,例如:
1.0.18-nest.1
->1.0.18
之后我们就可以正常进行提交代码提交,并执行changeset publish
部署。