跳到正文

发版

这一页记录本主题的发版流程。仓库是 npm 包,同时也是一个可部署的文档站,两件事在 发布时都要顾及。

版本号怎么加

遵循 语义化版本。对一个主题来说,判断标准是 用户要不要改自己的配置:

变更版本位例子
破坏性变更:选项改名/删除、默认值变化导致渲染不同、不再支持的 Node 版本majorsidebarDepth 语义反转
新增能力且向后兼容:新选项、新组件、新插件键、新导出minor新增 WAuthor 组件与 author 选项
只修行为、不动接口:bug 修复、样式微调、文档修正patch修一次词数统计

1.5.0 是一次 minor:新增了 progressBar、codeBlockLanguage、numbered、 drawerTrapFocus 四个选项(都有默认值,默认行为向后兼容),同时修掉了一批只在 嵌套 locale 或多语言下才暴露的 bug。修 bug 本身是 patch,但同一次发布里带了新增 能力,所以取 minor 里较高的那个数字。

主题在 1.x 阶段对「新增可选能力」非常宽松:新增选项一律给默认值,author 缺省为 null、页脚不渲染作者区块 —— 这类改动不构成破坏,走 minor。

发布前的最低验证

四层测试都要绿,缺一层就可能把「构建成功但页面没人链接」这种问题发出去。

npm ci
npm run lint          # 0 error(4 条 v-html warning 是既有基线)
npm test              # 纯函数单测(当前 19)
npm run test:build    # 构建 fixture 站点并断言产物(当前 24)
npm run test:browser  # 需要先 npx playwright install chromium(当前 20)

再确认文档站能构建:

npm run docs:build    # 产物在 docs/.vuepress/dist

CI(.cnb.yml 的 verify-theme)会在构建之前依次跑 lint、单测、集成测试,所以 本地跑不过的提交在 CI 上也不会过。

打包产物要实测

「仓库能构建」不等于「打出来的包能装进别人的站点」。打 tarball 并装进一个全新消费者 站点,是发版前唯一能覆盖 files 字段、exports 映射与 peerDependencies 的检查。

npm pack                                  # 生成 vuepress-theme-github-<version>.tgz

然后在仓库之外建一个最小站点验证它:

mkdir /tmp/consumer && cd /tmp/consumer
npm init -y
npm install vuepress@2.0.0-rc.31 @vuepress/bundler-vite \
  /path/to/vuepress-theme-github-<version>.tgz
mkdir -p docs/.vuepress && cd docs/.vuepress
// docs/.vuepress/config.js
import { viteBundler } from '@vuepress/bundler-vite'
import { defineUserConfig } from 'vuepress'
import { githubTheme } from 'vuepress-theme-github'

export default defineUserConfig({
  bundler: viteBundler(),
  title: 'Consumer',
  theme: githubTheme({ navbar: [{ text: '首页', link: '/' }] }),
})
cd ../.. && npx vuepress build docs

断言这些,任何一项不对就说明包本身有问题:

  • 构建成功,渲染出页面
  • 构建日志里的 error / warn / not defined 为 0 条
  • 导航栏、侧边栏、页内目录、首页 Hero 都渲染出来

npm pack 只打 package.json 的 files 字段列出的内容,加上 package.json / README.md / LICENSE。lib/ 是 npm run build 的产物、被 .gitignore 忽略,但 prepublishOnly 会在发布前重新构建它 —— 手工打 tarball 时记得先跑一次 npm run build, 否则打出来的是空壳。

files 漏列 = 包装不上

v1.2.0 发过这个错:postinstall 会跑 scripts/ensure-rolldown-binding.mjs,但 files 里没有 scripts/,于是每个消费者 npm install 都在 postinstall 阶段失败:

Cannot find module '.../vuepress-theme-github/scripts/ensure-rolldown-binding.mjs'

仓库里永远测不出来,因为仓库里那个文件一直都在 —— 只有把 tarball 装进一个全新 目录才会暴露。这就是「仓库能构建」不等于「包能用」的典型形态。

规则:任何会被 postinstall(消费者安装时)执行的脚本,都必须在 files 里。scripts/test.mjs 里有一条单测专门盯这条,改动 files 时会立刻报错。

发版提交该改什么

  1. package.json 的 version 提到目标版本。

    package-lock.json 里的版本也要跟着对齐。lockfile 与 package.json 版本不一致, 会让依赖 lockfile 同步校验的宿主(如 EdgeOne Makers)直接失败。

  2. CHANGELOG.md 记录本次变更。用 ## [x.y.z] - YYYY-MM-DD 的格式,四类小节按需 选:新增 / 变更 / 修复 / 删除。

  3. 如果有新的公开选项或组件,同步 docs/guide/configuration.md 与 docs/components/。

打标签与发行

标签名带 v 前缀(v1.2.0),指向 main 上的发布提交。发行说明直接复用 CHANGELOG 里对应那一节的正文。

tag:      v1.2.0
name:     vuepress-theme-GitHub v1.2.0
target:   main
状态:     正式发布(草稿与预发布都取消勾选),设为 Latest

发布到 npm

npm login
npm publish           # publishConfig.access 已设为 public

prepublishOnly 会在发布前跑 clean + build,所以不需要手工准备 lib/。

发布后

  • 确认 tag 对应的提交就是 main 上的发布提交(合并产生的提交容易错位)。
  • 若 README 顶部有版本徽章,检查它是否指向新版本。
  • 部署文档站的宿主会读 package.json 的 engines,发版时改过 engines 就要顺手确认 宿主的 Node 版本还能满足。

相关

  • 测试 —— 四层测试分别拦什么
  • 部署 —— 静态托管的构建命令与常见失败
  • 开发文档 —— 主题内部构造