@changesets/cli是什么?哪些情况下需要使用?怎么使用

一、@changesets/cli 是什么

一句话 :它是一个专门为 Monorepo(多包仓库) 设计的版本管理与发布工具

它的核心工作流程是:

复制代码
开发者写代码 → 声明"我要发布什么包、升什么级别" → 生成一个 .md 计划文件
                                                        ↓
                                   所有 PR 合并后,统一消费这些计划文件
                                                        ↓
                                    自动改版本号、写 CHANGELOG、发布到 npm

它本质上解决了 Monorepo 场景下的两个核心痛点:

痛点 Changesets 的解法
多人同时改同一个包,版本号在 Git 中冲突 不直接改版本号,而是生成独立的 .md 计划文件,文件名随机,永远不会冲突
包之间有依赖,升级一个包需要同步更新依赖它的包 updateInternalDependencies 配置,自动级联更新

在当前工程中,它作为 devDependencies 安装在根目录:

bash 复制代码
// 根 package.json
"devDependencies": {
  "@changesets/cli": "^2.31.1"
}
bash 复制代码
"scripts": {
  "changeset": "changeset",           // → pnpm changeset
  "version:pkgs": "changeset version", // → pnpm version:pkgs
  "publish:pkgs": "changeset publish"  // → pnpm publish:pkgs
}

二、哪些情况下需要使用

✅ 必须使用的情况

bash 复制代码
你同时满足以下 3 个条件 → 必须用版本管理工具(Changesets 是首选之一):
  ✅ 多个 npm 包在同一个仓库里(Monorepo)
  ✅ 包之间有相互依赖关系
  ✅ 需要发布到 npm 仓库(公共或私有)

❌ 不需要的情况

场景 为什么不需要
单包仓库 直接改 package.json 版本号 + npm publish 就够,不需要 Changesets 的复杂度
应用项目(非库) 应用不需要发布到 npm,只需要部署到服务器
不发布到 npm 如果只是内部使用 workspace:* 协议引用,不需要版本管理
个人项目、单人维护 没有多人协作带来的版本号冲突问题

当前工程为什么需要

对照这个工程:

bash 复制代码
✅ Monorepo:20+ 个包在 packages/ 下
✅ 相互依赖:business → composables → core,形成依赖链
✅ 发布到 npm:发布到阿里云私有仓库(packages.aliyun.com)
✅ 多人协作:团队开发

三、怎么使用

3.1 初始化(一次性)

bash 复制代码
pnpm add -D @changesets/cli
pnpm changeset init

这会生成 .changeset/ 目录,包含 config.jsonREADME.md

当前工程的 config.json:

bash 复制代码
{
  "changelog": "@changesets/cli/changelog",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "restricted",
  "baseBranch": "master",
  "updateInternalDependencies": "patch",
  "ignore": ["test1", "test2", "example-page", "pc-demo", "pc-template", "@bht-next/docs"]
}

3.2 逐一解释每一个配置项:

bash 复制代码
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json"

含义:JSON Schema 的声明,告诉编辑器(VS Code)这个 JSON 文件的结构规范,从而提供自动补全和字段校验。

实际效果:你在编辑 config.json 时,编辑器会提示哪些字段是合法的、值的类型是什么,写错了会标红。纯粹是开发体验优化,不影响运行时行为。

bash 复制代码
"changelog": "@changesets/cli/changelog"

含义 :指定 CHANGELOG 的生成模板。值是一个 npm 包的路径,Changesets 会 require() 这个包来格式化 CHANGELOG。

默认值@changesets/cli/changelog(内置的默认模板)

实际效果 :执行 changeset version 时,生成的 CHANGELOG 是这样的格式:

bash 复制代码
# @bht-next/business
2.0.0
Major Changes
该次提交日志
Patch Changes
本次提交日志
1.0.6
Patch Changes
分页参数修改

可以自定义 :如果你想要不同的 CHANGELOG 格式,可以指向自定义包,比如 @changesets/changelog-github(带 GitHub 链接的格式):

bash 复制代码
"changelog": "@changesets/changelog-github"
bash 复制代码
## 2.0.0
Major Changes
study (#123)    ← 自动带 PR 链接
bash 复制代码
"commit": false

含义changeset version 执行后,是否自动执行 git commit

false (当前设置):只修改文件,不自动提交。你需要手动 git add + git commit。这是推荐做法,因为你可以检查版本变更是否正确后再提交。

true:自动提交。适合 CI/CD 全自动流程。

bash 复制代码
"fixed": []

含义固定版本组 。数组中的包被强制绑定,它们的版本号永远保持一致。当其中任何一个包需要升级时,组内所有包一起升级到同一个版本号。

当前为空 :意味着这个工程中每个包独立管理自己的版本号,@bht-next/core 可以是 1.0.27@bht-next/business 可以是 2.0.0,互不影响。

使用场景示例 :假设 @bht-next/business@bht-next/ui 总是需要一起发布,版本号必须一致:

bash 复制代码
"fixed": [["@bht-next/business", "@bht-next/ui"]]

效果:如果 business 需要从 2.0.0 升到 2.1.0,ui 就算没改代码,也会被迫1.5.0 升到 2.1.0(取组内最高版本号)。

bash 复制代码
"linked": []

含义关联版本组 。和 fixed 类似,但更宽松 ------组内包版本号不需要完全相同,只需在同一个 major 版本内即可。当组内某个包需要跨 major 升级时,其他包也一起升级 major。

当前为空:不做关联。

fixed 的区别

fixed linked
版本号一致性 必须完全相同 可以不同,但 major 版本同步
升级触发 任意包的任意级别变更都触发全组升级 只有 major 升级时触发全组
举例 business@2.1.0, ui@2.1.0 business@2.1.0, ui@2.0.5(同 major 即可)
bash 复制代码
"access": "restricted"

含义:包的发布访问级别。

  • "restricted":私有包,只有授权用户才能安装(当前设置)
  • "public":公开包,任何人都能安装

所以实际发布时,business 包是 public 的,其他包是 restricted 的。

注意 :这个值只是默认值 。如果某个包的 package.json 中单独设置了 publishConfig.access,会覆盖这个默认值。比如当前工程中 @bht-next/businesspackage.json

bash 复制代码
"publishConfig": {
  "access": "public"  // ← 覆盖了 config.json 的 "restricted"
}

3.3 日常开发(每个开发者)

只做一件事:pnpm changeset

bash 复制代码
# 修改完代码后
pnpm changeset

🔄 Step 1/3 --- 选择要发布的包

? Which packages would you like to include?

◯ @bht-next/auth-keycloak

◉ @bht-next/business ← 空格勾选/取消

◯ @bht-next/composables

...

🔄 Step 2/3 --- 选择版本变更级别

? What kind of change is this for @bht-next/business?

major ← 不兼容的 API 修改(BREAKING CHANGE)

❯ minor ← 向下兼容的新功能

patch ← 向下兼容的 bug 修复

🔄 Step 3/3 --- 输入变更描述

? Please enter a summary for this change:

  • 新增批量导入组件

  • 支持 xlsx 解析

✔ Changeset added! → .changeset/tall-tigers-sing.md

bash 复制代码
---
"@bht-next/business": minor
---
新增批量导入组件
支持 xlsx 解析

把这个文件提交到 Git

bash 复制代码
git add .changeset/tall-tigers-sing.md
git commit -m "feat(business): 新增批量导入组件"

3.4 发布阶段(在 master 分支上统一执行)

bash 复制代码
# Step 1: 消费所有计划文件,更新版本号
pnpm changeset version

这一步自动完成:

  • 读取所有 .changeset/*.md,合并同一包的多个变更
  • 修改 package.jsonversion 字段
  • 更新 CHANGELOG.md
  • 删除已消费的 .md 文件
bash 复制代码
# Step 2: 提交版本变更
git add . && git commit -m "chore: release"
Step 3: 发布到 npm
pnpm changeset publish

这一步自动完成:

  • 检测哪些包的本地版本 > npm 仓库版本
  • 触发 prepublishOnly 钩子 → 自动执行 tsup 构建
  • 发布到 npm 仓库

核心口诀

开发者只管 changeset(声明意图),发布者统一 version + publish(执行发布)。 记住这个分工,就不会用错。

相关推荐
天远Date Lab1 小时前
零信任架构实战:基于天远行驶证核查构建自动化车队准入网关
运维·人工智能·架构·自动化
不会就选b2 小时前
Linux之网络基础(二)
linux·运维·网络
莫浅子3 小时前
Day 4:USB 2.0 时序与带宽预算
linux·运维·网络
ly76893 小时前
Linux 从入门到实践:系统架构、常用命令、服务管理与故障排查详解
linux·运维·系统架构
2401_868534783 小时前
在企业环境中快速安装配置 FreeBSD Unix 服务器操作系
linux·网络协议
小雪崩3 小时前
嵌入式学习 day27:标准IO
linux·c语言·学习
Arnold.Shen3 小时前
Dell Storage SC - 如何发送SupportAssist,并启用安全控制台
linux·安全
青瓦梦滋3 小时前
IP/MAC帧/ARP协议
运维·服务器·网络·网络协议·tcp/ip
wunaiqiezixin3 小时前
MIT 6.S081 xv6 源码精读(Scheduling):sched、scheduler
linux·unix·os·xv6·mit6.s081