jsPDF 版本发布全流程指南:从 GitHub Release 到 npm 自动发布的标准化操作手册
【免费下载链接】jsPDFClient-side JavaScript PDF generation for everyone.项目地址: https://gitcode.com/gh_mirrors/js/jsPDF
本文以 jsPDF 官方仓库的 RELEASE.md 为骨架,系统讲解维护者在发布新版本时执行的完整操作链路:创建 GitHub Release 草稿、同步 bower.json 版本号、通过npm version打 Tag、推送分支,以及最终由 GitHub Actions 在 Release 发布时自动触发npm publish。读者在阅读后可完整掌握 jsPDF(乃至同类 npm 包)的可复现发布流程,并理解版本号在源码、构建产物与文档之间的传递机制。
发布流程总览
jsPDF 的发布流程是一个"手动打 Tag + CI 自动发布"的混合模式:版本号的更新与 Tag 的创建由维护者在本地完成,而 npm 包的实际发布由 GitHub Actions 在 Release 正式发布时自动执行。整条链路如下:
- 在 GitHub 上新建一个draft release(草稿 Release);
- 撰写并完善本次 Release 的版本说明(Release Notes);
- 更新 bower.json 中的版本号(仓库注释标注为
@TODO: Automate?,即该步骤尚未自动化); - 本地执行
npm version 2.x.y,同步更新 package.json 并生成 Git Tag; git push origin v2.x.y推送版本 Tag;git push origin master推送主分支代码;- 在 GitHub 上将草稿 Release 正式发布,此时 GitHub Actions 监听到
release: published事件,自动执行npm publish。
这一设计的优势在于:发布动作(Publish)由 CI 承担,避免维护者在本地环境配置 npm 登录凭据,同时保证发布包一定来自最新构建产物。
步骤一:创建 GitHub Draft Release
发布的第一步是在 GitHub 仓库的 Releases 页面点击Draft a new release,创建草稿。草稿不会对外可见,维护者可以在此从容撰写说明。
编写 Release Notes 时,建议覆盖以下信息:
- 版本号与标题:与后续
npm version使用的版本号保持一致; - 新增特性(Features):列出本次新增的 API 与模块,例如新支持的图片格式、新的
hotfixes选项等; - 破坏性变更(Breaking Changes):明确提示使用者需要调整的调用方式;
- Bug 修复(Fixes):列出修复的问题及其对应 issue/PR 编号;
- 升级指引:说明从上一版本迁移的关键差异。
草稿创建后先不要点击 Publish,而是继续完成本地版本号更新与代码推送,最后再回来发布草稿——这正是该流程将第 1、2 步与第 7 步拆开的原因。
步骤二:同步 bower.json 版本号
jsPDF 仓库同时维护 package.json 与 bower.json 两份元数据。bower 生态虽然已逐渐淡出主流,但仓库仍保留了对它的兼容,因此发布前需要手动把 bower.json 中的version字段更新为目标版本:
{ "name": "jspdf", "version": "4.2.1", "description": "PDF Document creation from JavaScript", "main": [ "dist/jspdf.umd.js", "dist/jspdf.umd.min.js", "dist/jspdf.es.js", "dist/jspdf.es.min.js", "dist/jspdf.node.js", "dist/jspdf.node.min.js" ], "moduleType": ["amd", "globals", "node", "es6"] }需要特别说明的是:
- 该步骤在 RELEASE.md 中被明确标注为
@TODO: Automate?,即官方承认它尚未自动化,需要发布者手工同步; - 目前仓库中 package.json 与 bower.json 的版本号均为
4.2.1,两者保持一致是发布的前提; - 之所以不能完全省略该文件,是因为 bower 客户端在安装依赖时会读取此处的
version与main字段来定位构建产物(bower.json 中main字段列出的正是dist/目录下的 UMD、ESM、Node 三类打包文件)。
步骤三:本地执行 npm version 更新版本号
在仓库根目录执行:
npm version 2.x.y其中2.x.y替换为实际版本号(遵循语义化版本 SemVer)。npm version会自动完成三件事:
- 将 package.json 的
version字段更新为指定版本; - 生成对应的 Git Tag(默认格式为
v2.x.y); - 触发 package.json 中定义的
version生命周期脚本。
version 脚本:发布前的自动化构建与文档生成
jsPDF 在 package.json 中为version脚本注入了发布前的关键动作:
"version": "yarpm run build && yarpm run generate-docs && git add -A dist docs"其执行顺序为:
yarpm run build:调用 rollup.config.js 重新构建所有分发产物,产出dist/目录下的jspdf.umd.js、jspdf.es.js、jspdf.node.js及对应的.min.js压缩版本;yarpm run generate-docs:先由pregenerate-docs脚本(deletedocs.js)清理旧文档,再调用 JSDoc 根据 jsdoc.json 配置(源目录为src/,输出到docs/)重新生成 API 文档;git add -A dist docs:将重新构建的产物与文档自动暂存,纳入本次版本提交。
这意味着每次发版,dist/构建产物与docs/文档都会与源码版本严格对应,避免出现"源码已更新但产物滞后"的版本漂移问题。
版本号在构建产物中的注入机制
版本号并非硬编码在源码中。在 src/jspdf.js 中,静态版本字段以占位符形式存在:
jsPDF.version = "0.0.0";真正的版本号由 rollup.config.js 中的replaceVersion()插件在构建时注入:
function replaceVersion() { return replace({ delimiters: ["", ""], "0.0.0": pkg.version }); }即:构建时从 package.json 读取pkg.version,将源码中的"0.0.0"占位符替换为真实版本号。因此,只要npm version更新了 package.json,重新构建后的dist/产物就会携带正确的jsPDF.version。同理,rollup.config.js 中的licenseBanner()会读取 src/license.js 模板,把versionID(版本号)、builtOn(构建时间)与commitID(当前 Git 短哈希)写入每个产物的头部版权注释,方便排查线上问题的来源。
步骤四:推送 Tag 与主分支
版本号更新、构建与文档生成完成后,依次推送两个引用:
git push origin v2.x.y # 推送版本 Tag git push origin master # 推送主分支(含版本提交、dist 产物与 docs)两个推送缺一不可:
- Tag 推送:
v2.x.y是 GitHub Release 的关联锚点,草稿 Release 需要指定目标 Tag; - master 推送:确保主分支包含版本号更新提交、最新构建产物与文档,保证仓库主干与发布版本一致。
步骤五:发布 Release,触发 npm 自动发布
回到 GitHub 上之前创建的草稿 Release,将其正式发布(Publish release)。此时 GitHub Actions 工作流 .github/workflows/npm-publish.yml 会被事件自动触发:
name: Node.js Package on: release: types: [published] jobs: publish-npm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v6 with: node-version: 20 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm publish env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}该工作流的执行逻辑:
- 触发条件:仅当 Release 状态变为
published(发布)时运行,draft(草稿)与prerelease状态不会触发; - 环境准备:检出代码、安装 Node.js 20、配置 npm 官方 registry 地址;
- 依赖安装:
npm ci依据 package-lock.json 安装锁定版本的依赖,保证发布环境可复现; - 发布动作:
npm publish使用仓库 Secrets 中的NPM_TOKEN进行 npm 身份认证并上传包。由于 package.json 的files字段仅包含dist、types/index.d.ts、README.md、LICENSE,npm 包内不会携带 src、test、examples 等目录,实现精简发布。
注意:
npm publish并不会重新构建,它直接发布当前仓库(即最新 master)中已构建好的dist/产物。这正是"步骤三中必须先跑 build"的原因——保证发布出去的包与源码版本完全匹配。
发布前的前置质量保障
正式发版前,维护者还应确保 CI 全绿。jsPDF 的持续集成工作流 .github/workflows/continuous-integration.yml 覆盖四类检查:
| 检查项 | 内容 | 对应命令 |
|---|---|---|
| Browser tests | ChromeHeadless 下的全量单元测试(Karma) | npm run test-ci |
| Node.js tests | Node 20/22 双版本下的测试(Jasmine) | npm run test-node |
| Typings tests | TypeScript 4.0 与 latest 下的类型声明校验 | npm run test-typings |
| Lint | Prettier 格式一致性检查 | npm run lint |
在 package.json 中,test脚本被定义为pretest(先构建)加test-node与test-ci的组合:
"pretest": "yarpm run build", "test": "yarpm run test-node && yarpm run test-ci"本地开发时,也可使用npm run test-local一次性串行执行单元测试、Node 测试以及 AMD、ESM、Globals、TypeScript、WebWorker 五种部署形态的测试(分别对应 test/deployment 下的 karma 配置)。参考 PDF 基线文件位于 test/reference,例如blank.pdf、textfield.pdf等,用于像素级回归比对。
发布流程中的关键约定与注意事项
- 版本号一致性:
bower.json、package.json、Git Tag、GitHub Release 四处的版本号必须一致,任何一处遗漏都会导致依赖解析或产物版本错乱; - Tag 格式:Git Tag 使用
v前缀(如v4.2.1),与npm version的默认行为一致; - 发布是幂等动作的终点:草稿阶段可以反复修改说明,但一旦 Publish,
npm publish会立即执行且 npm 不允许覆盖已发布的同版本号,因此发布前务必确认版本号正确; - 无需在本地配置 npm 凭据:认证完全由 CI 中的
NPM_TOKENSecret 承担,维护者本地只需要 Git 权限; - 版本号占位符机制:若在源码中搜索不到"真实版本号",是因为 src/jspdf.js 中的
"0.0.0"会在构建时被 rollup.config.js 的replaceVersion()替换为 package.json 的version字段。
小结
jsPDF 的发布流程是一条"本地打 Tag、CI 发版"的标准化流水线:维护者只需在本地完成bower.json同步、npm version更新版本号与构建产物、推送 Tag 与 master,随后在 GitHub 上发布草稿 Release,剩下的npm publish由 .github/workflows/npm-publish.yml 自动完成。理解这一流程,不仅可以帮助贡献者参与 jsPDF 的发版协作,也能为其他 npm 开源项目的发布自动化设计提供可直接借鉴的范本。
【免费下载链接】jsPDFClient-side JavaScript PDF generation for everyone.项目地址: https://gitcode.com/gh_mirrors/js/jsPDF
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考