npm自定义包发布

本文以自定义工具函数库为例,讲解工具包项目从发布到 npm 中央仓库、维护及使用的过程。

image-20220427185535158

项目准备

创建工具包项目

安装 Node 和 Git

检查是否已经安装 node(node 中自带 npm)

1
2
3
# windows:cmd命令
node -v
npm -v

如果 node 与 npm 命令不识别,说明你尚未安装 node;或者者未配置环境变量,导致当前路径下无法识别命令。安装 node,自行解决,这里不再赘述。

Git 的安装自行解决

创建项目

1
2
3
4
5
# 创建一个空的项目文件夹:huatree-utils
# 在文件夹下执行命令
npm init -y
# 或者yarn
yarn init -y

npm 命令,详见官网

yarn 命令,详见官网

初始化 git 和配置忽略项

1
2
# 初始化
git init

项目根目录下创建.gitignore,配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.DS_Store
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log

bower_components
coverage

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.local

下载依赖包

1
npm i webpack webpack-cli -D

配置 webpack

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const path = require('path')
module.exports = {
// 模式
mode: 'development', // 也可以使用压缩方式 production
// 入口
entry: './src/index.js',
// 出口
output: {
// 打包文件夹
path: path.resolve(__dirname, 'dist'),
// 打包文件
filename: 'huatree-utils.js',
// 向外暴露的对象的名称
library: 'htUtils',
// 打包生成库可以通过esm/commonjs/reqirejs的语法引入
libraryTarget: 'umd'
}
}

在入口 JS 中导出功能

src/index.js

1
2
3
4
export function test() {
document.write('测试自定义包')
console.log('test()')
}

配置打包命令

package.json

1
2
3
4
"scripts": {
"build:watch": "webpack --watch",
"build": "webpack"
}

项目进行打包

1
npm run build:watch

测试使用自定义包

test/first.html

1
2
3
4
5
6
<body>
<script src="../dist/huatree-utils.js"></script>
<script>
htUtils.test()
</script>
</body>

image-20220427172208754

发布流程

完善 package.json

name:必须是唯一的名称(在 npm 在线中央仓库中没有同名的)

main:必须指定为打包生成的 js 文件

keywords:指定一些方便别的程序员搜索到当前库的关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"name": "ht-utils",
"version": "1.0.0",
"description": "huatree-自定义工具函数库",
"main": "dist/huatree-utils.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:watch": "webpack --watch",
"build": "webpack"
},
"keywords": ["test", "..."],
"repository": {
"type": "git",
"url": "https://github.com/huatree/ht-utils"
},
"author": "醉梦",
"license": "MIT",
"devDependencies": {
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2"
}
}

!

关联 github、填好作者、协议、项目描述、版本。

注意项目根目录带上 README.md 使用介绍。

了解package.json文件更多配置信息,详见

npm 配置

npm 配置的中央仓库不能是淘宝镜像

发布前必须执行:

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

不用发布时:

1
2
# 淘宝镜像url可能有改变,根据实际情况使用url
npm config set registry http://registry.npm.taobao.org/

查看配置:

1
npm config list

注册 npm 中央仓库账号

注册地址,详见

关键信息:用户名、密码、邮箱(需要验证)

添加用户

执行

1
2
3
4
5
npm adduser
# 或者
npm login
# 退出登录
npm logout

登录 npm 仓库:依次指定用户名、密码、邮箱

  • 密码输入过程不可见

  • 下次登录的时候,可能会输入验证码,验证码会通过输入的邮箱发送。

发布仓库

执行

1
npm publish

如果发布失败,出现 npm 403 错误,一般是库名已存在(重复了),修改 name 为唯一值,再发布。

仓库维护

更新代码后再发布

修改项目库的版本号:package.json 中的 version,例如从 1.0.0 改为 1.0.1。

! 版本号注意一定要变大

修改代码后重新打包、发布

1
2
3
npm run build
# 登录情况下执行
npm publish

强制删除已发布的库

! 72 小时内可删除,超过则无法删除

登录情况下执行

1
npm unpublish --force

使用自定义工具包

下载工具包

1
2
# 名称是你前面指定发布的库名(位于package.json中的name参数)
npm i huatree-utils

网页中引入并使用

1
2
3
4
<script src="./node_modules/ht-utils/dist/huatree-utils.js"></script>
<script>
htUtils.test()
</script>

模块化引入并使用(ESM 方式)

1
2
import { test } from 'ht-utils'
test()

模块化引入并使用(CommonJS 方式)

1
2
const { test } = require('ht-utils')
test()

取消发布

发布的包(如A)72小时内,可以取消发布(从注册表中删除包)。取消发布后,如果需要再次发布此包,需要使用新的版本号,并且24小时后才可发布该包的任何新版本。

包重命名

采用弃用包的某个版本方案解决。

没有任何专用的方法可以做到这一点。一种常见的技术是使用 npm-deprecate 来给出一个警告,指示新的包名称。

1
npm deprecate my-project-name@"<= latest-version" "This project has been renamed. Install using new-project-name instead."

例:

1
npm deprecate my-thing@"<= 0.2.3" "This project has been renamed. Install using my-new-thing instead."

issues

引入ht-m-utils报错:ReferenceError: self is not defined

ht-m-utils项目中,需修改配置webpack.config.js,加入globalObject: 'this'

1
2
3
4
5
module.exports = {
output: {
globalObject: 'this'
}
}

详见

Warning: To load an ES module, set “type“: “module“ in the package.json or use the .mjs extension

如果项目中没有配置ES6的ESM转ES5,引入ht-m-utils运行时,会出现这个问题。

解决方案:配置ES6转ES5,或者package.json加入"type": "module",以便支持ESM

了解更多

相关链接

[1] npm 发布包和删除包(2019 最新攻略)

[2] Web 前端自定义工具函数库

[3] Renaming a published NPM module

[4] npm-deprecate