Monorepo项目必看:用@changesets/cli管理多包版本号的5个实战技巧
如果你正在使用Monorepo架构管理多个npm包,那么版本号管理可能是你最头疼的问题之一。手动更新每个包的版本号不仅耗时,还容易出错。想象一下,当你需要同时发布core、layout和plugins三个包的更新时,手动操作不仅繁琐,还可能导致版本号不一致的问题。这正是@changesets/cli工具的用武之地——它能够自动化这一过程,确保版本管理的准确性和一致性。
@changesets/cli是一个专为Monorepo设计的版本管理工具,它通过"变更集"(changeset)的概念来记录和跟踪每个包的修改,然后智能地决定如何更新版本号。无论是简单的补丁更新,还是重大的破坏性变更,@changesets/cli都能帮你轻松应对。本文将分享5个实战技巧,帮助你在实际项目中更高效地使用这一工具。
1. 快速搭建@changesets/cli基础工作流
在开始使用@changesets/cli之前,我们需要先进行基础配置。这个配置过程非常简单,但有几个关键点需要注意。
首先,在你的Monorepo项目根目录下安装@changesets/cli。推荐使用pnpm作为包管理器:
pnpm add -W -D @changesets/cli安装完成后,初始化changeset配置:
npx changeset init这个命令会在项目根目录下生成一个.changeset文件夹,其中包含一个config.json文件。这个配置文件决定了@changesets/cli的行为方式。让我们来看一个典型的配置示例:
{ "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [], "linked": [], "access": "restricted", "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": ["docs", "example"] }配置项说明:
changelog: 指定如何生成变更日志commit: 是否自动提交版本变更access: 包发布时的访问权限baseBranch: 项目的主分支名称updateInternalDependencies: 内部依赖更新的策略ignore: 不需要版本更新的包
提示:如果你的项目中有一些文档或示例代码不需要发布,记得将它们添加到
ignore列表中。
完成配置后,你可以在package.json中添加一些便捷的命令:
{ "scripts": { "changeset": "changeset", "version-packages": "changeset version", "publish-packages": "changeset publish" } }这样,你就完成了@changesets/cli的基础配置,可以开始使用它来管理你的Monorepo项目了。
2. 高效管理变更集的3个技巧
变更集是@changesets/cli的核心概念,它记录了每个包的具体变更内容。掌握变更集的管理技巧可以显著提高工作效率。
2.1 交互式创建变更集
创建变更集的最简单方式是运行:
pnpm changeset这会启动一个交互式命令行界面,引导你完成以下步骤:
- 选择需要版本更新的包(使用空格键多选)
- 为每个选中的包选择版本更新类型(patch/minor/major)
- 输入变更描述(这些内容会出现在CHANGELOG.md中)
这个过程中有几个实用技巧:
- 批量选择包:如果多个包需要相同的版本更新类型,可以一次性选择它们
- 变更描述:尽量清晰描述变更内容,这对后续的版本追踪非常有帮助
- 语义化版本:准确选择patch/minor/major,遵循semver规范
2.2 变更集文件的结构
每次创建变更集后,.changeset目录下会生成一个类似cool-bananas-march.md的文件,内容如下:
--- "package-a": minor "package-b": patch --- 这是一个功能更新,添加了新的API接口并修复了几个小问题。文件内容分为两部分:
- YAML格式的前言,声明哪些包需要更新以及更新类型
- Markdown格式的变更描述
注意:变更集文件名是随机生成的,不需要手动修改。重要的是文件内容。
2.3 批量处理变更集
在大型项目中,可能会积累多个变更集文件。@changesets/cli可以智能地处理这种情况:
pnpm version-packages这个命令会:
- 读取所有变更集文件
- 计算每个包需要的版本更新
- 更新package.json中的版本号
- 生成或更新CHANGELOG.md文件
- 删除已处理的变更集文件
版本更新策略:
- 如果多个变更集对同一个包有不同级别的更新,会选择最高级别的更新
- 相互依赖的包会自动保持版本兼容性
3. 预发布模式的实战应用
预发布模式是@changesets/cli的一个强大功能,特别适合需要频繁发布测试版本的项目。
3.1 进入预发布模式
要开始预发布周期,运行:
pnpm exec changeset pre enter next这里的"next"是预发布标识符,也可以是"alpha"、"beta"等。执行后,会在.changeset目录下生成一个pre.json文件:
{ "mode": "pre", "tag": "next", "initialVersions": { "package-a": "1.0.0", "package-b": "1.2.3" }, "changesets": [] }3.2 预发布期间的版本管理
在预发布模式下,版本号的更新方式会发生变化。例如:
- 初始版本:1.0.0
- 第一次预发布:1.0.1-next.0
- 第二次预发布:1.0.1-next.1
- 以此类推...
这种模式非常适合以下场景:
- 持续集成/持续交付(CI/CD)流程
- 内部测试版本发布
- 功能预览版发布
3.3 退出预发布模式
当预发布测试完成后,可以退出预发布模式:
pnpm exec changeset pre exit然后运行版本更新命令:
pnpm version-packages这将把所有包的版本号从预发布版本(如1.0.1-next.0)转换为正式版本(如1.0.1)。
4. 高级配置技巧
@changesets/cli提供了多种高级配置选项,可以满足复杂项目的需求。
4.1 链接包版本
如果你希望某些包始终保持相同的版本号,可以在config.json中使用linked配置:
{ "linked": [["package-a", "package-b"]] }这样,当package-a或package-b中任何一个需要版本更新时,另一个也会同步更新。
4.2 固定包版本
对于高度耦合的包,可以使用fixed配置将它们锁定在完全相同的版本:
{ "fixed": [["package-c", "package-d"]] }与linked不同,fixed会确保这些包始终具有完全相同的版本号。
4.3 自定义变更日志生成
你可以替换默认的变更日志生成器。例如,使用@changesets/changelog-git:
{ "changelog": ["@changesets/changelog-git", {"repo": "your-org/your-repo"}] }或者创建自己的生成器:
{ "changelog": "./scripts/my-changelog-generator.js" }5. 与CI/CD流程集成
将@changesets/cli集成到CI/CD流程中可以自动化版本管理和发布过程。
5.1 基本集成方案
一个典型的GitHub Actions工作流可能如下:
name: Release on: push: branches: - main jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: pnpm/action-setup@v2 - run: pnpm install - run: pnpm build - run: pnpm version-packages - run: pnpm publish-packages env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}5.2 自动化变更检测
你可以配置CI只在检测到变更时运行发布流程:
- name: Check for changes id: changes run: | git fetch if [ -n "$(git diff --name-only origin/main...HEAD .changeset)" ]; then echo "::set-output name=has_changes::true" fi - name: Publish if: steps.changes.outputs.has_changes == 'true' run: pnpm publish-packages5.3 版本发布策略
对于大型团队,可以考虑以下策略:
- 开发人员创建变更集并提交PR
- CI检查变更集是否存在
- 合并到主分支后自动发布新版本
- 使用Git标签标记每个发布版本
@changesets/cli的灵活性让它能够适应各种不同的工作流程和团队规范。