在我们开发NPM包的时候,经常需要测试才能保证包的正常使用,本文总结了几种测试NPM包的方法
下文中,项目名以project代替
要发布的npm包名以@zxkfall/audio-player代替,包所在的文件夹名为audio-player
1. 发布后安装包(极度不推荐)
测试NPM包最好的方法就是将其发布,然后在项目中安装包,进而测试包是否可用,流程如下
# 修改完代码后,版本号+1,然后发布
$ npm publish --access=public
# 在project根目录下安装模块
$ npm install @zxkfall/audio-player
# 自己进行对应的测试....
当然这样的流程是不推荐的,一方面,频繁的发布与安装,会消耗大量的时间,另一方面,每次发布包都需要增加版本号,这样就会导致版本号数字很大,而且由于没有经过测试就已经发布,如果测试出现问题,需要重新修改并发布,会导致版本号管理比较混乱。
正常的流程应该是在本地测试没有问题后,再将包发布,等使用者发现问题并提交后,再根据使用者的反馈,对一些代码进行修改,因此便有以下几种方法可以在本地测试包
2.通过npm link
命令
- 将开发的包创建成本地依赖包
$ cd audio-player
$ npm link
- 进入项目中,建立链接
$ cd project
$ npm link @zxkfall/audio-player
这样@zxkfall/audio-player这个包就会与项目project关联,后面包的代码更新时,project里面对应包的代码也是最新的。
如果项目要解除链接
# 在project下
$ npm unlink @zxkfall/audio-player
如果要取消模块的链接
# 在audio-player下,这样所有用到包的其他项目链接都会失效
$ npm unlink @zxkfall/audio-player
# unlink为uninstall的别名
3. 使用Yalc
yalc
可以在本地将npm包
模拟发布,将发布后的资源存放在一个全局的存储中。然后可以通过yalc
将包添加进需要引用的项目中。这时候
package.json
的依赖表中会多出一个file:.yalc/...
的依赖包,这就是yalc
创建的flie:
软链接。同时也会在项目根目录创建一个yalc.lock
确保引用资源的一致性。因此,测试完项目还需要执行删除yalc
包的操作,才能正常使用。当然,yalc
也是支持link:
链接方式
a.首先安装yalc
$ npm install yalc -g
b.发布包
# 在audio-player下
$ yalc publish
此时如果存在npm 生命周期
脚本:prepublish
、prepare
、prepublishOnly
、prepack
、preyalcpublish
,会按此顺序逐一执行。如果存在:postyalcpublish
、postpack
、publish
、postpublish
,也会按此顺序逐一执行。
想要完全禁用脚本执行需要使用
$ yalc publish --no-scripts
此时就已经将依赖发布到本地仓库了。此命令只是在本地发布包并不会主动推送到远端。
当修改包的代码后,需要重新在本地发布时,可以使用推送命令快速更新所有依赖,相当于帮依赖这个包的项目执行了update
命令
$ yalc publish --push
$ yalc push # 简写
c.添加包
进入到project,执行
$ yalc add @zxkfall/audio-player
可以看到项目中添加了yalc.lock
文件,package.json
对应的包名会有个地址为file:.yalc/
开头的项目。
也可以使用
$ yalc add @zxkfall/audio-player@1.0.0
将版本锁定,避免因为本地新包推送产生影响。
参数:
--dev
,将依赖添加进dependency
中--pure
,不会影响package.json
文件--link
,使用link
方式引用依赖包,yalc add [my-package] --link
--workspace (or -W)
,添加依赖到workspace:协议中
d.当本地的包修改完毕,重新推送后,获取更新后的版本
$ yalc update # 更新全部
$ yalc update @zxkfall/audio-player # 只更新这一个包
e.其他命令
当我们要查看本地仓库里存在的包时
$ yalc installations show
要清理不需要的包时
$ yalc installations clean @zxkfall/audio-playe
3.包内测试
很多时候,其实有些功能我们完全可以使用一些测试工具,在包内进行测试,这里以jest为例
a.安装jest
$ npm install --save-dev jest
b.使用
导出的函数
// index.js
const createAudioPlayer = () => {
console.log('CreateAudioPlayer')
};
const AudioPlayer = function () {
console.log('new')
this.createAPlayer = createAudioPlayer
}
module.exports = AudioPlayer
测试文件
// index.test.js //这里不要用import来导入,会报错
let AudioPlayer = require("../index")
describe('Test', function () {
it('should log', function () {
let mk = new AudioPlayer()
new AudioPlayer().createAPlayer()
});
});
4.使用webpack进行打包
我们很多需要用的包,都是可以直接通过CDN引用的,如果我们使用module.exports
或exports
进行导出,这样在原始的HTML文件里面,实际上是无法使用的,因为浏览器不支持es6的语法,而es5里面实际上是不识别module
或exports
的。
用webpack进行打包,如果没有定义全局变量,是无法把函数给外面的代码使用的,因为webpack打包是用的闭包,立即执行的函数,这点这里不做深入探讨。
有时候,我们希望我们开发的模块,既可以在ES5的语法环境中使用,即直接调用函数,又希望它兼容ES6语法,即通过NPM安装后,可以通过import
进行导入,这里就需要用到全局变量,以及webpack打包。
这里预设一个场景:
我们希望我们的测试可以全部在这个模块里运行,不希望通过yalc或者link指令通过另一个项目进行测试。那我们就需要新建一个index.html
文件,在index.html
里面通过script标签引入我们的js文件,配合live-server
,就可以实现实时加载更新后文件的功能。
1.安装webpack与live-server
$ npm install --save-dev webpack
$ npm install --save-dev live-server
2.根目录新建webpack.config.js
内容如下
const path = require('path');
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
watch: true //auto config file
};
3.package.json增加配置
"scripts": {
"serve": "live-server --port=8080" // 当运行npm run serve命令时,会在本地建立端口号为8080的服务器,服务器的根目录为项目的目录,会自动找到index.html文件并打开
},
4.index.js
里面的示例代码如下
const createAudioPlayer = () => {
console.log('CreateAudioPlayer')
};
const AudioPlayer = function () {
console.log('new')
this.createAPlayer = createAudioPlayer
}
window.$AudidoPlayer = AudioPlayer
module.exports = AudioPlayer
这里注意,增加了window.$AudidoPlayer = AudioPlayer
,这样AudioPlayer
这个函数才能被外部直接调用
5.新建index.html文
内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello Test
<script type="text/javascript" src="dist/index.js"></script>
<script type="text/javascript">
const audioPlayer = new window.$AudidoPlayer()
audioPlayer.createAPlayer();
console.log('ddd')
</script>
</body>
</html>
6.打包
$ webpack
7.运行live-server
$ npm run serve
之后,只要文件内容发生变化,html页面也会刷新。
8.总结
其实live-serve和vscode或者idea的一些自动刷新插件都类似,所以具体选用哪个,看自己需求,这里只是提供了一种在大部分情况下可用的一种方法。
由于我们的包发布后,其实就有一个默认的CDN链接,即
https://cdn.jsdelivr.net/npm/(packagename)@(version)/(filePath)
这里的file是相对路径,如:
https://cdn.jsdelivr.net/npm/@zxkfall/audio-player@1.0.0/dist/index.js
通常,一些静态网页需要通过以CDN的方式引入第三方组件,由于没有使用NPM进行管理,那么ES6的一些语法就无法支持,这时候,就可以使用
const audioPlayer = new window.$AudidoPlayer() //在项目中定义的
这样就实现了ES5与ES6功能的兼容。
当然,也可以使用
https://cdn.jsdelivr.net/npm/@zxkfall/audio-player@1.0.0/index.js
那么项目中就直接使用
const audioPlayer = new AudioPlayer()
进行后续的操作,这也是可以的,但是浏览器会报错,因为module这个变量实际上是无法识别的,这样用户体验就会很差。
注意发布包的时候,别忘了忽略一些文件的提交
