发布 NPM 包
1. 项目初始化
执行 npm init
创建 package.json
文件,需特别注意 name
字段的命名规则。普通包直接使用 package-name
格式,带范围的包必须采用 @scope/package-name
格式。此时系统会自动校验命名是否符合 npm 命名规范,包括长度限制(最大 214 字符)和禁用字符等。
2. 作用域包的特殊处理
当使用 @user/package
格式时,需在 package.json
中显式声明作用域:
{
"name": "@your-username/package-name",
"version": "1.0.0",
"publishConfig": {
"access": "public"
}
}
作用域包默认视为私有(即使未订阅 npm 付费服务),必须通过 publishConfig.access
字段或命令行参数 npm publish --access=public
强制公开。
3. 模块入口设计
在 main
字段指定 CommonJS 入口文件(如 index.js
),现代包建议同时配置 module
字段指向 ESM 模块文件(如 esm/index.mjs
)。通过 exports
字段实现条件导出:
{
"exports": {
".": {
"import": "./esm/index.mjs",
"require": "./index.js"
}
}
}
4. 发布前验证
运行 npm pack --dry-run
生成 .tgz
压缩包但不实际发布,可检查包含的文件结构是否符合预期。建议配置 .npmignore
文件排除测试用例、构建工具配置等非必要文件,该文件优先级高于 .gitignore
。
5. 认证与发布
执行 npm login
完成认证(需开启两步验证),随后使用精确发布命令:
# 普通包
npm publish
# 作用域包首次发布
npm publish --access=public
# 后续更新
npm version patch && npm publish
6. 作用域包与普通包的区别
类似 @babel/core
的作用域包与普通包 babel-core
相比,具有以下优势:
命名空间隔离:作用域包通过 @scope/
前缀创建虚拟命名空间,使不同开发者可以发布同名包而不冲突。例如 @babel/core
与 @vue/cli
共享全局注册表但互不影响,这种结构特别适合组织级代码管理。
访问控制机制:普通包默认全局可见,而作用域包的可见性可配置。企业用户可通过 npm org
命令创建团队级作用域,配合 npm token
实现细粒度权限管理,这是普通包不具备的企业级功能。
7. 402 错误
发布公共范围的包时,可能会收到以下错误:
npm ERR! code E402
npm ERR! 402 Payment Required - PUT https://registry.npmjs.org/.... - You must sign up for private packages
尝试发布公共范围的包时会发生这种情况。默认访问级别为私有。要解决此问题,可以使用如下命令设置包的可访问性:
npm config set access public
或者在 package.json
文件中添加以下配置:
{
"publishConfig": {
"access": "public"
}
}