Skip to main content

发布 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:命令行可执行文件
  • filesnpm 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 # 删整个包

八、最佳实践

  1. CI 自动化发包:用 semantic-releaserelease-it,根据 commit 自动 bump 版本
  2. 不要把 token 提交到代码仓库:用环境变量 NPM_TOKEN
  3. 私有包加 .npmrc + private: true:防误发
  4. prerelease 走 beta tag:不污染 latest
  5. monorepo 用 pnpm -r publish:批量发包

九、备注

更详细的 package.json 字段说明见 包管理.npmrc 配置见 .npmrc 配置文件