Socket.IO 发版流程详解:从 RELEASING 文档看 socket.io 的版本发布、npm Trusted Publishing 与客户端 Bundle 同步

发布时间:2026/9/5 23:22:04
Socket.IO 发版流程详解:从 RELEASING 文档看 socket.io 的版本发布、npm Trusted Publishing 与客户端 Bundle 同步 Socket.IO 发版流程详解从 RELEASING 文档看 socket.io 的版本发布、npm Trusted Publishing 与客户端 Bundle 同步【免费下载链接】socket.ioBidirectional and low-latency communication for every platform项目地址: https://gitcode.com/gh_mirrors/so/socket.io本文围绕 packages/socket.io/RELEASING.md 中定义的 6 步发版流程展开结合 monorepo 的 workspaces 结构、client-dist/ 静态资源的服务机制以及 .github/workflows/publish.yml 中的 CI 配置完整解析 socket.io 是如何通过 Git tag 触发 GitHub Actions并借助 npm trusted publishing 安全发布到 npm 的。读完后你将掌握一套可复用的 monorepo 版本发布方案手动同步版本号与 changelog、用 tag 约定驱动 CI 自动发布、以及服务端包如何内嵌客户端浏览器 bundle。一、发版流程总览6 步完成一次发布packages/socket.io是 Socket.IO 的 Node.js 服务端主包当前版本为 4.8.3见 packages/socket.io/package.json同时它也是 monorepo 中唯一“打包分发”的包npm 包内不仅包含服务端编译产物还内嵌了客户端浏览器 bundle。packages/socket.io/RELEASING.md 定义的发布流程共 6 步更新package.json中的版本号用conventional-changelog -p angular更新CHANGELOG.md把 client 项目产出的 bundle 拷贝到client-dist/提交package.json、CHANGELOG.md、client-dist/三处变更创建 tagsocket.iox.y.z并推送由 CI workflow 自动发布到 npm在 GitHub 仓库创建 Release 页面。前 4 步是维护者手动完成的内容准备第 5、6 步分别对应自动化发布与面向用户的公告。整个流程没有任何“手动执行npm publish”的环节——发布权完全交给 CI这也是后文重点解释的部分。1. 版本号与 CHANGELOG 的更新package.json的version字段是发布的唯一事实来源。以当前仓库为例packages/socket.io/package.json 与 packages/socket.io-client/package.json 的版本均为4.8.3——服务端包与客户端包保持锁步lockstep版本这是第 3 步“拷贝 bundle”能够成立的前提socket.io服务端内嵌的客户端 bundle 必须来自同一版本的socket.io-client。changelog 通过conventional-changelog -p angular生成即基于conventional commits规范并使用angular 预设feat/fix/perf 等类型映射到 Major/Minor/Patch。生成结果写入 packages/socket.io/CHANGELOG.md其顶部是一张版本与发布日期的索引表例如| Version | Release date | |----------------------------------|---------------| | 4.8.3 (2025-12-23) | December 2025 | | 4.8.2 (2025-12-22) | December 2025 | | 4.8.1 (2024-10-25) | October 2024 |这意味着日常开发中提交的 commit message 规范feat:、fix:等直接决定了 changelog 的内容与版本号应升哪个层级。2. 与客户端包的对应关系socket.io发布前必须同步socket.io-client的构建产物这一步的细节见下节。值得注意的是 monorepo 的完整工作区清单根 package.json 声明了 11 个 workspaceengine.io、engine.io-client、socket.io-parser、socket.io-adapter等但 RELEASING.md 只覆盖socket.io这一个包。从源码结构看其余包的发布依赖同一个 tag 触发机制tag 命名包名版本如socket.io-clientx.y.zpackages/socket.io-client/RELEASING.md 额外要求更新support/package.esm.json中的版本号、执行npm run compile与npm run build、提交dist/产物最后还需把 bundle 同步到独立的 CDN 仓库供cdn.socket.io使用。二、client-dist/服务端包为什么内嵌客户端 bundleRELEASING.md 第 3 步“Copy the bundles from the client project toclient-dist/”看似简单却揭示了 socket.io 的一个核心设计服务端默认帮浏览器分发客户端 JS因此socket.ionpm 包必须携带预构建的客户端 bundle。当前仓库的 packages/socket.io/client-dist/ 目录包含 4 个 bundle外加 source mapsocket.io.js/socket.io.min.jsUMD 格式可直接用script标签引入全局变量名为iosocket.io.esm.min.jsES Module 版本socket.io.msgpack.min.js带 MessagePack 序列化支持的压缩版。1. serveClientbundle 的实际消费路径服务端通过serveClient选项决定是否为客户端分发这些静态文件。从 packages/socket.io/lib/index.ts 可以看到实现细节构造函数中this.serveClient(false ! opts.serveClient)index.ts#L325——默认开启只有显式传serveClient: false才关闭开启时静态文件路由指向path.join(__dirname, ../client-dist/, filename)index.ts#L577也就是包内client-dist/目录若serveClient为 false则不注册静态文件处理器测试用例见 packages/socket.io/test/server-attachment.ts#L154new Server(srv, { serveClient: false })。这正是 RELEASING.md 第 3 步存在的原因每次发版前必须把socket.io-client新构建的 bundle 拷贝进client-dist/否则用户npm install socket.io后服务端通过/socket.io/socket.io.js等路径分发的将仍是旧版本客户端。而 packages/socket.io/package.json 的files字段确认了client-dist/会随 npm 包一起发布files: [ dist/, client-dist/, wrapper.mjs, !**/*.tsbuildinfo ]2. 客户端 bundle 从哪里来socket.io-client的build脚本见 packages/socket.io-client/package.json#L59用 Rollup 串行执行三个配置产出上述文件rollup -c support/rollup.config.umd.js \ rollup -c support/rollup.config.esm.js \ rollup -c support/rollup.config.umd.msgpack.js以 packages/socket.io-client/support/rollup.config.umd.js 为例它定义了两个输出devBundle输入./build/esm-debug/browser-entrypoint.js输出./dist/socket.io.jsUMD全局名io带 sourcemapprodBundle输入./build/esm/browser-entrypoint.js输出./dist/socket.io.min.js经 Terser 压缩。两个 bundle 都会写入版本 banner其中的版本号直接读取../package.json的version字段const version require(../package.json).version; const banner /*! * Socket.IO v${version} * ... */;这解释了为什么客户端发版packages/socket.io-client/RELEASING.md必须先更新两个package.json主包 support/package.esm.json再执行npm run build——bundle 内嵌的版本号、files声明的dist/目录packages/socket.io-client/package.json#L13-L16都以版本同步为前提。3. ESM 互操作wrapper.mjssocket.io是 CommonJS 包type: commonjs但对 ESM 导入提供了 packages/socket.io/wrapper.mjs 作为垫片import io from ./dist/index.js; export const {Server, Namespace, Socket} io;package.json的exports字段将import条件指向./wrapper.mjs、require指向./dist/index.jspackages/socket.io/package.json#L28-L33。该 wrapper 同样在files声明中是发布产物的一部分。三、tag 约定与 CI 自动发布RELEASING.md 第 5 步是整套流程的自动化核心Create the tagsocket.iox.y.zand push it to the GitHub repository. The workflow.github/workflows/publish.ymlwill safely publish the package to npm using trusted publishing.tag 采用包名版本格式例如socket.io4.8.3推送后触发 .github/workflows/publish.yml。该 workflow 的关键配置如下on: push: tags: # expected format: packageversion (example: socket.io1.2.3) - *** jobs: publish: runs-on: ubuntu-latest permissions: contents: read id-token: write # 生成 OIDC token用于 npm trusted publishing steps: - name: Checkout repository uses: actions/checkoutv6 - name: Use Node.js 26 uses: actions/setup-nodev6 with: node-version: 26 registry-url: https://registry.npmjs.org cache: npm - name: Install dependencies run: npm ci - name: Compile each package run: npm run compile --workspaces --if-present - name: Publish package run: npm stage publish --workspace${GITHUB_REF_NAME%*} --access public逐行解析触发条件***任何形如xxxyyy的 tag 都会触发一个 workflow 文件服务 monorepo 中所有包tag 中的前的部分就是目标包名permissions: id-token: write这是 npm trusted publishingOIDC的必要权限使 Actions 能向 npm 换取临时身份全程无需在仓库中保存NPM_TOKENcontents: read说明发布流程只需要读代码最小权限npm run compile --workspaces --if-present在 monorepo 根目录对每个声明了compile脚本的 workspace 执行编译。对socket.io而言packages/socket.io/package.json#L47 定义compile: rimraf ./dist tsc对socket.io-client则是清理build/后做 CJS ESM 双份 tsc 编译并执行postcompile.shpackages/socket.io-client/package.json#L54。之所以要编译是因为dist/产物不入库——CI 从源码现场构建保证发布的字节码与 tag 指向的提交完全一致npm stage publish --workspace${GITHUB_REF_NAME%*} --access public${GITHUB_REF_NAME%*}是 bash 参数展开剥去 tag 名及之后的部分即从socket.io4.8.3提取出socket.io作为--workspace参数只发布这一个包。前缀npm stage publish表明这里使用的是npm staged publishing工作流文件头部注释也引用了 npm 的 trusted publishing 与 staged publishing 官方文档包先被发布到暂存区只有当该版本的所有产物tarball、元数据等都就位后才会对外可见避免了传统npm publish可能出现的“半成品版本”注意该步骤没有指定版本号——npm 以 tag 触发时包内package.json的version字段为准。这就是 RELEASING.md 第 1 步先改package.json再打 tag与第 5 步 tag 名必须一致的原因如果socket.io4.8.3这个 tag 指向的提交里package.json仍写着4.8.2发布结果会是一个版本名与 tag 不符的包因此“版本号更新 → 提交 → 打 tag”的顺序不可颠倒。适用前提与限制该流程依赖仓库是 monoreponpm workspaces--workspaces --if-present是根级命令单包仓库需要相应简化trusted publishing 要求预先在 npm 控制台为 GitHub 仓库配置 publisher仓库、workflow 文件、环境绑定本仓库中看不到这部分配置它在 npm 侧因此文中“会自动发布”的结论以 RELEASING.md 的官方说明为准CI 使用 Node.js 26 执行发布而包自身的engines声明如 packages/socket.io/package.json#L81-L83 的node 10.2.0面向的是最终用户两者不冲突但含义不同。四、第 4 步提交的三个文件及其一致性第 4 步要求提交package.json、CHANGELOG.md、client-dist/三个路径的变更三者构成一个自洽的版本快照提交内容作用一致性要求package.jsonnpm 元数据name、version、files、exports、dependenciesversion必须与将创建的 tag 中版本一致CHANGELOG.md面向用户的变更说明由 conventional-changelog 生成新版本的 changelog 小节如# 4.8.3 (2025-12-23)需与version对应client-dist/服务端分发的客户端 bundle必须来自同版本的socket.io-client构建产物bundle banner 中的版本号应一致三者任一不同步都会产生问题package.json与 tag 不一致会导致发布版本错位CHANGELOG.md缺更新则 Release 说明不完整client-dist/落后则出现“服务端 4.8.3 分发 4.8.2 客户端 bundle”的版本漂移且由于serveClient默认开启packages/socket.io/lib/index.ts#L325这种漂移会静默影响所有依赖服务端分发客户端的项目。五、第 6 步创建 GitHub Release流程的最后一步是在仓库的 Releases 页面手动创建 Release向用户公告新版本及其变更内容。这一步不触发任何自动化纯粹是发布流程的“面向人”的收尾它与第 5 步的 tag 天然关联——Release 通常锚定在socket.iox.y.z这个 tag 上正文内容一般直接取自本次更新生成的CHANGELOG.md小节。至此一次完整发版的闭环是规范提交conventional commits→ 手动升版本、生成 changelog、同步 client bundle → 提交三文件 → 打包名版本tag → CI 编译 npm stage publish经 trusted publishing 发布 → 创建 Release 公告。整个过程发布密钥零落地OIDC 换取临时身份、发布内容可追溯到具体 tag 指向的提交是典型的 monorepo 安全发布范式。六、可复用的发版要点清单结合本文对 packages/socket.io/RELEASING.md 与配套 CI/源码的分析可提炼出通用要点tag 命名即路由包名版本格式让单个 publish workflow 服务所有包${GITHUB_REF_NAME%*}提取包名避免为每个包维护独立 workflow产物不入库、CI 现编译dist/、build/均不在提交范围files字段只约束 tarball 内容prepack/CI 中的compile脚本保证发布的产物来自 tag 指向的确切提交如 packages/socket.io/package.json#L53 的prepack: npm run compile多文件版本同步点主包有“package.json 内嵌 bundle”两个同步点对应第 3 步客户端包另有support/package.esm.json这个 ESM 子包的版本副本遗漏任一都会造成包内版本不一致changelog 自动化conventional-changelog -p angular将 commit 规范转化为发布说明维护者无需手写安全发布trusted publishing staged publishing 组合CI 仅持id-token: write权限即可完成npm stage publish仓库无需持久化任何 npm 凭据。若需进一步了解各环节的实现可重点阅读发版文档 packages/socket.io/RELEASING.md 与 packages/socket.io-client/RELEASING.md、发布工作流 .github/workflows/publish.yml、服务端静态分发逻辑 packages/socket.io/lib/index.tsserveClient相关段落约 L325、L541-L577、客户端 bundle 构建 packages/socket.io-client/support/rollup.config.umd.js以及 ESM 互操作垫片 packages/socket.io/wrapper.mjs。【免费下载链接】socket.ioBidirectional and low-latency communication for every platform项目地址: https://gitcode.com/gh_mirrors/so/socket.io创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考