Appearance
发布指南
组件库通过 release 分支发布到 npm 官方源,全程一条命令:
bash
npm run release # 唯一日常命令:默认递增 patch;上次中断则自动续发发布模型
dev(日常开发分支,见开发流程指南)
│ 功能稳定后 git merge --no-ff dev 合并
▼
master(集成与发布分支 = EdgeOne 文档生产分支)
│
│ npm run release [patch|minor|major]
▼
release(发布分支)
│ 自动:切/建 release → 合入 master 最新提交
│ 自动:package.json 版本号 +1 → commit "chore(release): vX.Y.Z" → 附注 tag vX.Y.Z
│ 自动:typecheck → build → pack 预览 → 人工确认 → npm publish(官方源)
│ 自动:push release + tag → master 快进合回 → push master → 官方源验证
▼
npm registry.npmjs.org 上的 vX.Y.Z(不可变)- tag 与 npm 版本一一对应:
vX.Y.Z指向 release 分支上的版本提交,合回 master 后 master 也包含该提交,可随时追溯"哪个提交 = 哪个 npm 版本"。 - 发布只发生在 release 分支:日常开发在 dev,master 只接受 dev 合并与版本提交,保持随时可发布(详见开发流程)。
版本号规则(semver + 0.x 约定)
| 提交类型 | 版本动作 | 说明 |
|---|---|---|
feat | minor | 新组件、新 prop / 事件 / 插槽、新增可选 peer 依赖 |
fix / perf | patch | 缺陷修复、性能优化 |
feat! / fix! / 正文含 BREAKING CHANGE | 1.0 前 = minor(CHANGELOG 标 ⚠);1.0 后 = major | 破坏性变更 |
docs / chore / refactor / style / test / build / ci | 不发版 | 文档、重构、工程化 |
- 同批多笔提交取最高级别;
- 手动版本优先:package.json 已是 ≥ 计算值的版本(如里程碑跳号
0.3.0)时自动化跳过; - 0.x 语义:
^0.1.x只匹配 patch,minor 即破坏性——与 npm 消费行为一致,规则天然对齐。
推送前自动管理(pre-push 钩子)
版本递增级别不再依赖人工判断——npm install 时自动安装 pre-push 钩子(scripts/install-hooks.mjs,零额外依赖):
- 推送时自动分析自上个版本 tag 以来的全部提交(conventional commits);
- 无
feat/fix/perf→ 静默放行; - 有待发版改动 → 自动
npm version(package.json + lock)→ 生成 / 更新CHANGELOG.md段落(文档站「版本发布」页自动展示)→ 提交chore(release): vX.Y.Z→ 打附注 tag → 拦截本次推送并提示重推,确保版本提交与 tag 一并上传; - 重推时钩子复核无新增待发版改动,直接放行。
配套约定:
npm run version:check随时干查版本计划,零副作用;npm run release自动识别"版本已就绪"(v<当前版本>tag 已存在且包含于 HEAD),跳过递增直接构建发布;-- minor/-- x.y.z强制指定仍可用(手动优先);- tag 是版本事实源头:每个 npm 版本都有对应 tag;tag 不一定都发 npm(连续多次推送可能产生多个 tag,发布时取最新);
- CHANGELOG.md 随版本提交自动生成(分组为 ⚠ 破坏性 / ✨ 新增 / 🐛 修复 / 📦 其他),文档站「版本发布」页实时展示;
- 钩子不会覆盖他人写入的 pre-push 钩子(识别非本仓库生成的钩子时提示手动合并)。
一次性准备
1. npm 账号与登录
npm 官网(www.npmjs.com)国内可能 403,但 registry API 与官网网页是两条通道,CLI 发布不受影响。账号注册需要网页一次(手机或代理),之后全程终端:
bash
npm login --registry=https://registry.npmjs.org/ --auth-type=legacy
# 终端直接输入用户名 / 密码 / OTP(2FA),不打开浏览器
npm whoami --registry=https://registry.npmjs.org/ # 验证登录态登录成功后 ~/.npmrc 会写入(与镜像配置共存,互不影响):
//registry.npmjs.org/:_authToken=npm_xxxxxxxxxxxx⚠️ token 只存于
~/.npmrc,绝不提交进仓库。本仓库不使用项目级.npmrc配 registry,发布通过脚本内--registry参数精确指向官方源。
2. 镜像源与官方源共存
本机 registry=https://registry.npmmirror.com/ 是只读同步镜像:
| 动作 | 用哪个源 |
|---|---|
日常 npm install | npmmirror(快) |
npm login / npm publish / npm view | 官方源(脚本已内置) |
3. 必须:满足 npm 发布 2FA 策略(2026-09 现状)
npm 已强制所有发布走双因素认证。未启用 2FA 的账号发布时会收到:
npm error code E403
npm error 403 403 Forbidden - PUT https://registry.npmjs.org/<pkg> -
Two-factor authentication or granular access token with bypass 2fa enabled
is required to publish packages.当前政策要点:
- TOTP 验证器(扫码 6 位码)已被 npm 废弃:
npm profile enable-2fa会报E404 Adding a new TOTP 2FA is no longer supported,CLI 无法再绑定; - 网站上只能添加安全密钥 / passkey(Windows Hello 指纹或 PIN、手机 passkey 均可);
- 推荐发布凭据:granular access token(创建时勾选 Bypass 2FA)——发布免 OTP、免交互;
- 官网
www.npmjs.com用真实浏览器可正常访问(curl/脚本被 Cloudflare 拦是机器人检测,不代表浏览器打不开)。
操作步骤(浏览器完成,一次性):
- 浏览器登录 npmjs.com → 账号设置 → Two-Factor Authentication (
npmjs.com/settings/<用户名>/tfa)→ 添加 Security key / Passkey(Windows Hello 指纹/PIN 或手机); (敏感操作需要 2FA 挑战,passkey 配好后网站内交互即可通过) - Access Tokens → Generate New Token → Granular Access Token,按下方字段表填写;
- 复制 token(
npm_开头,仅创建后显示一次,之后只显示前 4 后 4 位),替换~/.npmrc中的旧行(只保留一行,避免新旧并存冲突)://registry.npmjs.org/:_authToken=npm_<granular_token>
New Granular Access Token 页面填写方案
| 页面字段 | 建议值 | 说明 |
|---|---|---|
| Token name | vue3-ep-biz-lib-publish-local | 见下方命名建议 |
| Description(可选) | 本机 npm run release 发布用 | 便于日后核对用途 |
| Bypass 2FA | ✅ 必须勾选 | 解除发布 403 的关键开关。若复选框不可见/置灰 → 先完成第 1 步 passkey 再回来创建(创建 token 属敏感操作,可能要求先过 2FA 挑战)。2026-08 起该设置不覆盖账号身份/治理类操作,只影响发布,正是所需 |
| Allowed IP Ranges | 留空 | 家庭/办公宽带 IP 常变动,配置后可能把自己锁在门外;仅公司有固定出口 IP 时考虑(CIDR 格式,可多条) |
| Packages and scopes → Select Packages | All packages | 首次发布时本包尚不存在,"Only select packages and scopes" 里选不到(按包选择要求包已存在,上限 50 个包/scope) |
| → Permissions | Read and write | 发布必须有写权限(No access / Read-only 都发不了) |
| Organizations | No access | 个人包无关;组织授权只管组织设置,不代表能发组织的包 |
| Expiration | 90 天 | token 无法续期只能重建,太短维护烦、太长泄露窗口大;也可 Custom 自定义(至少 1 天后) |
Token name 命名建议:官方无成文字符/长度规则,实践约定——只用小写字母、数字、连字符 (避免中文、空格、特殊字符,CLI 输出与 npm token list 里最稳),命名带包名 + 用途 + 使用位置 (<包名>-publish-<位置>),将来 token 列表一眼认出、精准吊销。同一账号可建多个 token 靠名字区分 (本机 / CI / 临时),例如日后 CI 用 vue3-ep-biz-lib-publish-ci。
生成后立即复制(仅此一次显示),按第 3 步写入 ~/.npmrc。
发布成功后的收敛建议(最小权限原则,可选):包发布出来后,再建第二个 token—— Select Packages → Only select packages and scopes → 选中 vue3-ep-biz-lib(此时已存在)→ Read and write + Bypass 2FA,替换日常使用,并把 All packages 权限的旧 token Revoke 掉。
安全提醒:token 等同发布密码——只放 ~/.npmrc,不进 git、不贴聊天工具、不写进脚本/配置文件; 怀疑泄露立即官网 Revoke;npm token list 可随时核对在用凭据。
然后发布(免 OTP,一条命令):
bash
npm run release- 新版 npm 的 granular token 已支持
whoami,凭据预检直接通过;旧版本不支持时脚本会 自动识别~/.npmrc中的 token 并放行(--skip-auth保留为强制跳过); - 老账号若已绑定 TOTP,仍可
npm run release -- --otp=123456显式携带(granular token 方案用不到); - 发布中断不需要清理重来:重跑同一命令即自动续发;
- ⏳ 时间线:2027-01 起带 bypass-2FA 的 token 将失去直接发布能力,届时迁移官方推荐的 trusted publishing(OIDC 免 token)/ staged publishing(暂存 + 维护者 2FA 批准)。
统一发布命令
| 命令 | 说明 |
|---|---|
npm run release | 完整发布:版本已由推送前自动化就绪则直接用该版本,否则默认递增 patch |
npm run release -- minor / -- major | 强制递增次版本 / 主版本(手动优先于自动化) |
npm run release -- 0.2.0 | 发布显式版本号 |
npm run release -- --dry | 干跑:构建 + 打包预览 + 发布预演,无任何 git/npm 副作用 |
npm run release -- --yes | 跳过人工确认(仅 CI 建议) |
npm run release -- --skip-merge-back | 发布后不把 release 合回 master |
npm run release -- --otp=123456 | 显式携带 npm 2FA 验证码(npm 强制发布走 2FA) |
npm run release -- --resume | 强制续发(默认已自动识别中断现场,通常无需传) |
npm run release -- --skip-auth | 强制跳过凭据预检(granular token 已自动识别,通常无需传) |
npm run version:check | 干查下次推送将产生的版本计划(解析提交类型,零副作用) |
脚本自动执行的 8 步:
- 前置校验:工作树干净、官方源连通、已登录、目标版本未被占用(npm 版本发布后不可变);
- 分支:在 master 上自动切换 / 新建 release(
--ff-only合入 master 最新提交); - 版本:写入 package.json → 提交
chore(release): vX.Y.Z→ 打附注 tag(版本已由推送前自动化就绪时自动跳过); - 构建:
typecheck→build,产物永远来自当前源码(杜绝旧 dist 发布); - 预览:
npm pack --dry-run列出完整包内容; - 确认并发布:人工确认(y/N)后
npm publish至官方源; - 同步:推送 release 分支 + tag,master 快进合回并推送;
- 验证:
npm view确认官方源上版本存在。
安全设计:所有 git 写操作(commit/tag/push)都发生在人工确认之后。确认前取消会自动还原 package.json 与分支状态,不留任何痕迹。
智能续发(无需任何参数):release 分支上若存在 v<当前版本> 的 tag(上次发布中断的现场),npm run release 自动进入续发——跳过分支切换、版本递增与提交;若该版本其实已发布成功(仅推送/合回未完成),则直接补完剩余步骤。日常发布永远只有一条命令。
首次发布前的人工检查
检查包内容
bash
npm run release -- --dry # 或直接 npm pack --dry-run确认 tarball 只包含 dist/ + README.md + LICENSE + package.json(files: ["dist"] 白名单已排除 docs / 截图 / 源码)。
本地安装验证(tgz 消费测试)
bash
npm pack # 生成 vue3-ep-biz-lib-x.y.z.tgz
# 在一个全新的 vite + vue3 + element-plus 工程里:
npm i ../vue3-ep-biz-lib/vue3-ep-biz-lib-x.y.z.tgzts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' // EP 基础样式(本库依赖其 css 变量)
import 'vue3-ep-biz-lib/dist/style.css' // 本库组件样式(必引)
import Vue3EpBizLib from 'vue3-ep-biz-lib'跑通「全局注册 + 按需导入 + 样式」后再正式发布。
注意事项
网络与源
- npmmirror 只读:直接
npm publish(走镜像源)会 403,必须带官方源参数——脚本已内置; - 官网 403 ≠ 不能发布:
registry.npmjs.orgAPI 实测可直连(npm ping验证),CLI 全流程可用; - 镜像同步延迟:发布后约 10 分钟内,镜像源
npm i可能 404,属正常;可到 https://npmmirror.com/sync/vue3-ep-biz-lib 手动触发同步;验证发布是否成功请查官方源。
版本纪律
- npm 版本不可变:某版本号发布后永久占用,无法覆盖;发错了用
npm deprecate vue3-ep-biz-lib@x.y.z "说明"标记弃用,或发新版本; - 0.x 语义:
^0.1.0只匹配 patch(0.1.x),minor 即视为破坏性变更——推送前自动化按提交类型递增(见版本号规则),需要跳号时先手动npm version x.y.z提交再推送; - 发布前 master 必须干净:脚本会拒绝脏工作树,避免"npm 上的版本在 git 里追溯不到"。
发布失败处理
| 阶段 | 现象 | 处理 |
|---|---|---|
| 登录/网络 | ENEEDAUTH / 超时 | 按"一次性准备"重新 npm login(官方源 + legacy) |
| 绑定 2FA 报 E404(TOTP no longer supported) | npm 已废弃 TOTP 绑定 | 浏览器上官网加安全密钥/passkey,并创建勾选 Bypass 2FA 的 granular token(见"一次性准备"第 3 节) |
| 发布 403(Two-factor authentication) | 账号未启用 2FA 或 OTP 未携带/已过期 | 未启用先 npm profile enable-2fa auth-and-writes(官方源);已启用则 npm run release -- --resume --otp=<新验证码> 续发,版本提交与 tag 不会重复 |
| 确认前取消 | 手动选 N | 脚本已自动还原版本与分支,无需处理 |
| 发布失败,tag 未推送 | publish 报错 | 删本地现场后重试:git tag -d vX.Y.Z && git reset --hard HEAD^,修复后重跑 npm run release |
| 发布失败,tag 已推送 | publish 报错但 tag 已上远端 | 版本号已被 git 占用,只能 npm run release -- <更高版本>;弃用错误 tag:git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z |
| 发布成功但包有问题 | 代码缺陷 | 发新版本 + npm deprecate 旧版本;72 小时内可尝试 npm unpublish(严格限制) |
| 发布成功但验证 404 | registry 读副本传播延迟(发布实际已成功) | 稍等重跑 npm run release(自动识别已发布,仅补验证)或手动 npm view;脚本已内置 5 次自动重试 |
消费方须知(写进你的业务项目 README)
ts
import 'element-plus/dist/index.css' // EP 样式(peer 依赖不打包)
import 'vue3-ep-biz-lib/dist/style.css' // 本库样式包声明了 sideEffects: ["dist/*.css"],JS 侧可被 tree-shaking;UMD 产物为 .umd.cjs("type": "module" 包内 CJS 必须 .cjs 后缀)。
手动等价流程(脚本不可用时)
bash
git status # 必须干净
git checkout master && git merge --no-ff dev # 先合入 dev 的待发布内容
git checkout release && git merge --ff-only master
npm version patch -m "chore(release): v%s" && git tag -a "v$(node -p "require('./package.json').version")" -m "release"
npm run typecheck && npm run build
npm pack --dry-run
npm publish --registry=https://registry.npmjs.org/
git push origin release --follow-tags
git checkout master && git merge --ff-only release && git push origin master
npm view vue3-ep-biz-lib versions --registry=https://registry.npmjs.org/