1. 源码简介
update-notifier 作用:Update notifications for your CLI app (检测 npm 包是否有更新)。
本质就是开了 child_process 运行在后台,如果检查到有可用更新版,会将结果保存在 .update 属性中。
简单例子:
const updateNotifier = require('update-notifier');
updateNotifier({
pkg: {
name: 'public-ip',
version: '0.9.2'
},
updateCheckInterval: 24 * 60 * 60
}).notify();
学习目标:
1)学习 update-notifier 源码,输出记录文档。
源码地址:
https://github.com/yeoman/update-notifier
2. update-notifier 源码
源码其实就一个 200 行不到的 index.js 文件,乍一看用到了很多包,但核心是 UpdateNotifier 构造函数。它接收一个 options 对象,输出一个 UpdateNotifier 实例。这个实例有一个属性 update,是用来标记是否有可用更新版,如果有,就输出更新信息,运行上面简单例子结果如下(存在可用更新版):
UpdateNotifier 构造函数有三个函数:check() 检查,fetchInfo() 拉取信息,notify() 通知。
以上面的简单例子结合源码为例:
// 初始化 UpdateNotifier 实例
const updateNotifier = require('update-notifier');
// 对应源码中 UpdateNotifier constructor 部分的代码 + check函数
constructor(options = {}) {
this.options = options;
// ... 省略了部分源码,主要是容错处理和字段检测
}
check() {
// 当存在以下情况时停止检查
if (!this.config || this.config.get('optOut') || this.disabled) {
return;
}
// 获取相关包的更新信息 第一次检查时是 undefined
this.update = this.config.get('update');
if (this.update) {
// 如果有更新,赋值
this.update.current = this.packageVersion;
// 删除缓存的数据
this.config.delete('update');
}
if (Date.now() - this.config.get('lastUpdateCheck') < this.updateCheckInterval) {
return;
}
// 子进程
spawn(process.execPath, [path.join(__dirname, 'check.js'), JSON.stringify(this.options)], {
detached: true,
stdio: 'ignore'
}).unref();
}
// 调用实例的 notify 函数
updateNotifier({
pkg: {
name: 'public-ip',
version: '0.9.2'
},
updateCheckInterval: 24 * 60 * 60
}).notify();
// 对应源码中的 notify 函数
notify(options) {
// 满足以下情况时不需要通知(比如没有更新的时候不需要通知)
const suppressForNpm = !this.shouldNotifyInNpmScript && isNpm().isNpmOrYarn;
if (!process.stdout.isTTY || suppressForNpm || !this.update || !semver().gt(this.update.latest, this.update.current)) {
return this;
}
// 需要通知的情况,控制台输出更新信息
// 省略部分描写UI的源码...
// 此处return的this,option配置已改变
return this;
}
3. 总结
总体流程引用【凌晨三点半】的笔记:
- const updateNotifier = new UpdateNotifier({})
- 初始化 constuctor
- updateNotifier.check()
- 判断是否执行 check.js,如果执行:
- updateNotifier.fetchInfo()
- set(‘lastUpdateCheck’)
- set(‘update’)
- notify()
【凌晨三点半】的笔记很详细,细节满满的,感谢~