在前端团队协作开发中,私有 npm 包几乎是标配:我们经常会将通用组件库、工具函数库、业务基础 SDK 发布到 公司内部 npm 私服(如 Verdaccio、Nexus、Artifactory),供团队内部统一使用。
如果每次都手动 npm login、npm publish,不仅繁琐,还容易出错。在实际项目中,团队中就有人踩过“忘记切换 registry、误发到 npm 官方仓库”的坑。
因此,本文结合实际经验,分享一个完整的 npm 私服包自动化发布流程(GitLab 实战),从本地开发同步代码,到打 Git 标签,再到自动化构建和发布,最后给出完整的 Shell 脚本与最佳实践总结。
一、背景与痛点
在没有自动化脚本之前,我的发布流程大概是这样的:
- 手动拉取代码,确认与远程一致;
- 修改
package.json版本号; - 切换 registry 到公司内部私服;
- 登录 npm,输入账号密码;
- 手动执行
npm run build; npm publish发布;- 手动切换回官方 registry。
问题很多:
- 容易忘记更新代码,导致发布的包版本和远程分支不一致;
- 容易忘记切换 registry,甚至误发到公共 npm;
- 登录麻烦,尤其在 CI/CD 流程里;
- 没有打 tag,版本追踪不清晰。
于是我们设计了一套 自动化脚本 + GitLab 流程,来彻底规范团队的 npm 发布操作。
二、整体实现流程
自动化流程新增了 代码同步 和 Git 标签管理,整体步骤如下:
- 同步代码:拉取远程
master分支并更新到最新。 - 切换 registry:使用
nrm use切换到公司私服。 - 身份认证:通过
.npmrc或 token 自动认证。 - 版本管理:自动更新
package.json版本。 - Git 标签:根据版本号自动打 Git tag 并推送。
- 打包 & 发布:执行
npm run build && npm publish。 - 还原 registry:切换回淘宝镜像源,保证开发环境正常。
流程图如下:
[代码同步] → [切换私服] → [登录认证] → [版本更新] → [打 tag] → [npm run build] → [npm publish] → [切换淘宝镜像]
三、Shell 脚本实现
下面给出最终的完整脚本,可以直接保存为 publish.sh。
#!/bin/bash
# === 配置项 ===
PRIVATE_REGISTRY="your-npm-private" # nrm 配置的私服名称
TAOBAO_REGISTRY="https://registry.npmmirror.com" # nrm 配置的淘宝镜像
PACKAGE_NAME=$(node -p "require('./package.json').name")
PACKAGE_VERSION=$(node -p "require('./package.json').version")
NPM_TOKEN=${NPM_TOKEN:-""} # 从环境变量读取 npm token
# === 函数定义 ===
# 1. 同步远程 master 分支
sync_code() {
echo ">>> 拉取远程 master 分支最新代码..."
git checkout master || exit 1
git pull origin master || exit 1
}
# 2. 切换 registry
set_registry() {
echo ">>> 使用 nrm 切换到私服: $PRIVATE_REGISTRY"
nrm use $PRIVATE_REGISTRY
if [ -n "$NPM_TOKEN" ]; then
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
echo ">>> 已配置 npm token"
else
echo ">>> 未检测到 NPM_TOKEN,请确认是否需要手动 npm login"
fi
}
# 3. 更新版本号
update_version() {
echo "当前版本:$PACKAGE_VERSION"
read -p "请输入新的版本号 (留空则自动 patch): " NEW_VERSION
if [ -z "$NEW_VERSION" ]; then
npm version patch --no-git-tag-version
NEW_VERSION=$(node -p "require('./package.json').version")
echo ">>> 自动更新 patch 版本为 $NEW_VERSION"
else
npm version $NEW_VERSION --no-git-tag-version
echo ">>> 手动设置版本为 $NEW_VERSION"
fi
}
# 4. 打 Git Tag 并推送
git_tag() {
echo ">>> 打 Git 标签 v$NEW_VERSION 并推送到远程..."
git add package.json
git commit -m "chore: release $PACKAGE_NAME@$NEW_VERSION"
git tag -a "v$NEW_VERSION" -m "release $PACKAGE_NAME@$NEW_VERSION"
git push origin master --tags
}
# 5. 打包 & 发布
publish_package() {
echo ">>> 执行构建..."
npm run build || exit 1
echo ">>> 发布 $PACKAGE_NAME@$NEW_VERSION 到私服 $PRIVATE_REGISTRY"
npm publish --registry $(nrm current)
if [ $? -eq 0 ]; then
echo ">>> 发布成功!"
else
echo ">>> 发布失败,请检查日志"
exit 1
fi
}
# 6. 切回淘宝镜像
reset_registry() {
echo ">>> 切回淘宝镜像 $TAOBAO_REGISTRY"
nrm use $TAOBAO_REGISTRY
}
# === 主流程 ===
main() {
sync_code
set_registry
update_version
git_tag
publish_package
reset_registry
}
main "$@"
执行步骤:
chmod +x publish.sh
./publish.sh
这样一条命令就能完成 同步代码 → 打 tag → 构建 → 发布 → 切换回淘宝镜像 全流程。
四、GitLab CI 集成
在公司内部,我们最终把这套脚本接入了 GitLab CI,让团队只需要打 tag 即可自动触发发布。
.gitlab-ci.yml 示例
stages:
- publish
publish_npm:
stage: publish
image: node:18
script:
- npm ci
- chmod +x ./publish.sh
- ./publish.sh
only:
- tags
variables:
NPM_TOKEN: $NPM_TOKEN
这样一来:
- 开发者只需
git push origin v1.0.0; - GitLab Runner 会自动执行
publish.sh; - 保证团队每次发布一致、可追溯。
五、最佳实践总结
经过几次迭代,我们总结了一些 最佳实践:
- 本地发布必须保证代码与远程 master 一致:避免发布未合并代码。
- 使用 Git Tag 管理版本:CI/CD 触发基于 tag,确保可回溯。
- 打包与发布一体化:统一
npm run build && npm publish。 - 避免误发公共 npm:通过
nrm use固定私服,减少误操作。 - 发布完成后切换回淘宝镜像:保证日常开发依赖安装更快。
- token 管理走 CI/CD Secrets:不要写死在代码里。
- 团队协作统一脚本:避免不同开发者用不同发布方式。
六、结语
从最开始的“手动发布 → 人肉切换 registry → 误发公共 npm”,到现在的一键脚本 + GitLab CI 自动化,我们团队的 npm 包管理终于稳定高效。
技术的价值不仅在于“能用”,更在于“好用、稳用”。
如果你们团队也在使用私服 npm 包,强烈建议落地这套流程。只需小改几行配置,就能适配不同公司内部的私服环境。
文章评论