发布 npm 包
公司一般会搭建私有 npm 仓库(基于 nexus / verdaccio / cnpm),用途:
- 内部服务器存储自研包(安全)
- 组件库(登录权限组件、...)
- 工具 hooks(useStore、useArrayState、...)
- 缓存第三方包,加速下载
- 对 npm 包配置权限管理
一、切换 npm 源
nrm已经基本被淘汰,现在直接用包管理器的 config 命令更轻量。
pnpm(推荐)
# 查看当前源
pnpm config get registry
# 切换源
pnpm config set registry https://registry.npmmirror.com
# 切换到公司私有源
pnpm config set registry https://npm.example.com
npm / yarn
# npm
npm config set registry https://registry.npmmirror.com
# yarn
yarn config set registry https://registry.npmmirror.com
临时切换(只对当前命令生效)
npm --registry https://registry.npmmirror.com i <pkg>
项目级配置(推荐)
.npmrc:
registry=https://registry.npmmirror.com
# 公司私有包走自己的源
@my-company:registry=https://npm.example.com
这样团队共享一份 npm 配置,clone 下来就能用。
二、登录
第一次发布需要先登录:
# 私有源第一次登录
npm adduser --registry https://npm.example.com
# 后续
npm login --registry https://npm.example.com
npm whoami # 查看当前登录用户
npm logout # 退出登录
最佳实践:用 CI 的 NPM_TOKEN 环境变量发包,不要把 token 提交到 git。
三、创建包
mkdir my-pkg && cd my-pkg
npm init
package.json:
{
"name": "my-pkg",
"version": "1.0.0",
"description": "工具描述",
"author": "lucas",
"license": "MIT",
"main": "./lib/index.js",
"module": "./lib/index.mjs",
"types": "./lib/index.d.ts",
"bin": {
"my-pkg": "./bin/index.js"
},
"files": ["lib", "bin"],
"scripts": {
"build": "tsc"
},
"keywords": []
}
关键字段:
main:CJS 入口module:ESM 入口(webpack/rollup 优先用)types:TypeScript 类型入口bin:命令行可执行文件files:npm publish时包含的白名单private: true:永远不要给内部包发到公网
四、本地调试
# 在包目录下
npm link
# 在使用方项目里
npm link my-pkg
# 调试完解除
npm unlink my-pkg
或者用 pnpm 的 workspace,monorepo 场景下直接 import 即可。
五、版本管理
遵循 SemVer major.minor.patch:
major:破坏性变更minor:新增功能(向后兼容)patch:bugfix
npm version 自动改 package.json + 打 tag:
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.0 -> 1.1.0
npm version major # 1.0.0 -> 2.0.0
# 预发版
npm version prepatch --preid=beta # 1.0.1-beta.0
npm version prerelease # 1.0.1-beta.1
六、发布
# 确认登录
npm whoami
# 构建产物
pnpm build
# 发布(私有包加 --registry)
npm publish --registry https://npm.example.com
# 打 tag
npm publish --tag beta
发布后用新包名安装验证:
pnpm add -D my-pkg
七、删除 / 弃用
⚠️ npm 现在对 unpublish 有限制:
- 发布超过 72 小时的包不能 unpublish(需要联系 npm support)
- 推荐用
npm deprecate标记弃用,而不是直接删
# 弃用一个版本(提示用户升级)
npm deprecate my-pkg@1.0.0 "请升级到 1.0.1,已修复 xxx"
# 弃用整个包
npm deprecate my-pkg "已停止维护,请迁移到 new-pkg"
72 小时内删除:
npm unpublish my-pkg@1.0.0
npm unpublish my-pkg --force # 删整个包
八、最佳实践
- CI 自动化发包:用
semantic-release或release-it,根据 commit 自动 bump 版本 - 不要把 token 提交到代码仓库:用环境变量
NPM_TOKEN - 私有包加
.npmrc+private: true:防误发 - prerelease 走 beta tag:不污染 latest
- monorepo 用
pnpm -r publish:批量发包
九、备注
更详细的 package.json 字段说明见 包管理,.npmrc 配置见 .npmrc 配置文件。