npm发布流程和常见问题

最近项目中需要发布 NPM 包。 之前其实发过好多次,但是中间间隔的时间太长了,导致现在记忆有点模糊了。 正好借助这次的 NPM 发布,整理一下相关的内容,更新到博客里面,方便后面作为参考。

发布流程概览

  1. 切换到官方 npm 源
  2. 准备代码和 package.json 文件
  3. 处理忽略文件
  4. 注册 npm 账号并登录
  5. 发布到 npm
  6. 验证安装
  7. 常见问题解决

详细发布步骤

1. 切换到官方 npm 源

在发布 npm 包之前,必须确保使用的是官方 npm 源,而不是 CNPM、淘宝源等镜像源,否则会导致发布失败。

切换到官方源:

1
npm config set registry https://registry.npmjs.org/

验证当前源:

1
npm config get registry

2. 准备代码

首先,确保你的项目目录中有一个 package.json 文件。如果还没有,可以通过运行 npm init 命令创建。在初始化过程中,你需要填写包名、版本、入口文件等信息。

关键字段检查:

  • name: 包的全局唯一名称(在 npmjs.com 上搜不到才能用)
  • version: 版本号,每次发布必须更新(遵循语义化版本规范)
  • main: 包的入口文件(如 index.js)
  • license: 开源许可证(如 MIT、Apache-2.0)

2. 处理忽略文件

创建 .npmignore 文件来排除无需发布的文件,如测试代码、配置文件等:

1
2
3
4
5
6
node_modules/
.git/
.vscode/
test/
*.log
.env

如果没有 .npmignore 文件,npm 会默认使用 .gitignore

3. 注册 npm 账号

前往 npmjs.com 注册账号。注册完成后,在终端执行 npm login 命令登录。

4. 发布到 npm

在项目根目录运行 npm publish 命令即可发布。如果包名包含作用域(如 @myorg/utils),需要添加 --access public 参数。

测试阶段我们发布的包基本上都是放在个人作用域下面的,所以这一点一定要注意。

5. 验证安装

发布成功后,可以通过 npm install your-package-name 命令测试安装,并在代码中引入验证功能是否正常。

常见问题和注意事项

包名冲突

如果发布时提示包名已被占用,需要修改 package.json 中的 name 字段为唯一名称,可以考虑添加前缀。

删除已发布的同名包

如果你之前发布过同名包,现在想删除并重新发布,可以使用以下方法:

  1. 使用 npm unpublish 命令删除包:
1
npm unpublish your-package-name --force

注意:此操作只能在发布后 72 小时内执行。超过 72 小时需要联系 npm 支持。

  1. 删除后,更新 package.json 中的版本号,然后重新发布:
1
npm publish

版本重复

每次发布都必须更新版本号。可以手动修改 package.json 中的 version 字段,也可以使用 npm version patch 命令自动升级小版本号。

权限不足

确保已通过 npm login 登录且是该包的拥有者。

版本规范

遵循语义化版本(MAJOR.MINOR.PATCH)规范:

  • MAJOR: 不兼容的 API 修改
  • MINOR: 向后兼容的功能新增
  • PATCH: 向后兼容的问题修复

敏感信息

切勿在包中提交 .env 文件、密钥等敏感信息。

更新流程

修改代码后,需要更新版本号再重新发布。

撤销包

如果不小心发布了错误的包,需在 72 小时内联系 npm 支持,或使用 npm unpublish --force 命令立即删除公开包。

如何在保证安全的情况下使用私有npm包?

付费

将npm账号转为组织,然后就可以通过将用户加入组织的方式,使用私有包。
这个挺贵的,每个用户每个月7美元,对我们这种情况不可行。

直接通过 Git 仓库地址来安装 npm 包

可直接安装未发布到 npm registry 的包、内部私有包或特定分支/提交的代码,很适合我们的场景。
可通过提交哈希、标签或分支精确定位依赖版本,避免意外更改。
但是也有风险,若指向分支,拉取的是该分支最新提交,可能带来不确定性(除非使用锁定文件)。

另外我们内网不能联网,不能这样写。

类似这样:

1
2
3
4
5
6
"dependencies": {
"my-private-package": "git+https://github.com/username/repository.git#main",
"another-package": "git+ssh://git@github.com:username/another-repo.git#v2.1.0",
"specific-commit": "git+https://github.com/username/project.git#a1b2c3d4e5f",
"version-range": "git+https://github.com/username/repo.git#semver:^1.0.0"
}

内外网环境问题

我们开发阶段是在外网,能这么搞;但是发布阶段是在公司内网,不能联网,有没有什么办法可以根据不同的环境,切换调用不同的package.json配置呢?
使用 overrides 字段 (npm 8+)
可以在 package.json 中使用 overrides 字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "my-app",
"scripts": {
"build:dev": "cross-env NODE_ENV=development npm run build",
"build:prod": "cross-env NODE_ENV=production npm run build"
},
"overrides": {
"production": {
"some-dependency": "2.0.0"
},
"development": {
"some-dependency": "1.0.0"
}
}
}

如何本地跨npm包调试?

使用 npm link 进行本地开发:如果你在开发一个 Git 仓库中的包,并想在另一个项目中测试修改,可以使用 npm link。这会在全局创建一个符号链接,指向你的包目录,方便实时调试,而无需频繁提交和安装。

第一步:在包项目中创建全局链接

  1. 进入包项目的根目录​:
1
cd /path/to/your-package

请确保该目录包含有效的 package.json 文件,其中 name 字段(如 "my-awesome-package")将是你在其他项目中链接时使用的名称。

  1. 运行以下命令,在全局的 node_modules 目录中创建一个指向你当前包目录的符号链接:
1
npm link

成功后,你的包就可以在全局范围内被访问了。

第二步:在应用项目中链接包

  1. 进入需要用到本地包的应用项目的根目录​:
1
cd /path/to/your-project
  1. 运行以下命令,告诉应用项目使用刚刚创建的全局链接:
1
npm link <package-name>

请将 <package-name> 替换为包项目 package.json 中定义的 name(例如,如果 name 是 my-awesome-package,则命令为 npm link my-awesome-package)。
此命令会在你的应用项目的 node_modules 目录内创建一个符号链接,直接指向本地的包项目。

开始实时调试

现在,你可以在应用项目中像平常一样导入和使用你的本地包了

1
2
const myPackage = require('my-awesome-package');
// 或 import myPackage from 'my-awesome-package';

最关键的是​:此后你在包项目(your-package)中进行的任何代码修改,在保存后,都会立刻在应用项目(your-project)中生效,无需重新发布或重新安装。这极大提升了开发和调试效率。

其他信息

公共账号

账号:hivis
邮箱:thsdatavis@126.com
密码:见我本地信息《外网NPM包发布信息》Ths@xxxxxx

统一命名规范:
@hivis/aigc
@hivis/standard-chart
@hivis/hivis