如何检测npm包是否需发布并仅执行必要发布(多项目CI场景)
解决多包发布时已发布版本中断流程的问题
我太懂你的痛点了——在单一代码库批量发布多个包时,只要有一个包版本没更新就触发失败,导致后续所有包都发不出去,完全打乱了CI流程的节奏。下面给你几个实用的解决方案,核心都是先检测版本是否已在npm仓库存在,再决定是否执行发布:
方案一:用npm原生命令做前置检测(最轻量化)
你可以直接修改package.json里的发布脚本,给每个包的发布命令加上版本检测逻辑,只有版本不存在时才执行发布:
"publish-package1": "npm view package1@$(node -p \"require('./dist/package1/package.json').version\") || npm publish ./dist/package1", "publish-package2": "npm view package2@$(node -p \"require('./dist/package2/package.json').version\") || npm publish ./dist/package2", "publish-all": "npm run publish-package1 && npm run publish-package2"
这里的逻辑拆解:
node -p "require('./dist/package1/package.json').version":读取打包后包文件里的版本号npm view package1@[版本号]:检查这个版本是否已在npm仓库存在。如果版本已存在,这条命令会返回成功(退出码0),||后面的发布命令就不会执行;如果版本不存在,命令失败(退出码非0),就会触发执行发布
方案二:用monorepo工具简化流程(适合多包场景)
如果你的代码库包数量较多,手动写检测逻辑太繁琐,可以用lerna或nx这类专门的monorepo管理工具,它们原生支持跳过已发布版本:
- 用Lerna的话,配置好
lerna.json后,执行lerna publish --skip-existing,它会自动遍历所有包,只发布版本有更新的包 - 用NX的话,配合它的版本管理功能,执行
nx run-many --target=publish --only-changed,也能实现自动跳过已发布包的效果
方案三:写个简单Node脚本统一处理(自定义性强)
如果不想引入额外工具,也可以写个小脚本批量处理所有包,灵活性更高:
// publish-check.js const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); // 定义需要发布的包列表 const packages = ['package1', 'package2']; packages.forEach(pkg => { const pkgJsonPath = path.join(__dirname, 'dist', pkg, 'package.json'); const pkgInfo = require(pkgJsonPath); const { name, version } = pkgInfo; try { // 检测版本是否已发布 execSync(`npm view ${name}@${version}`); console.log(`✅ ${name}@${version} 已发布,跳过`); } catch (err) { // 版本不存在,执行发布 console.log(`📦 开始发布 ${name}@${version}`); execSync(`npm publish ${path.join(__dirname, 'dist', pkg)}`, { stdio: 'inherit' }); console.log(`🎉 ${name}@${version} 发布成功`); } });
然后在package.json里新增脚本:
"publish-all": "node publish-check.js"
执行npm run publish-all就会自动批量检测并发布需要更新的包了
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

