Node.js使用命令行工具来检查更新
随着Node.js的普及,用Node.js开发命令行工具变得越来越简单。一个成熟的命令行工具应该考虑如何从一开始就“优雅地”通知用户未来的版本更新。当然,最好的方法是当用户在终端执行命令时,向用户提示相关信息。
本文将给出一个易于使用、高效且可定制的方法。下面是源代码:GITHUB。欢迎大家点赞。接下来,我将解释如何实现它。
使用
让我们简单了解一下如何使用这个npm包:
const updater=require(' pkg-updater ');const pkg=require('。/package . JSON’);//命令行工具本身的包信息更新程序({'pkg' : pkg})。然后(()={/*在这里启动命令行工具*/});更新程序({ 'pkg': pkg,//自定义注册表' registry ' 3360 ' http://XXX . registry.com ',//请求的自定义dist-tag,默认值为最新的' tag' 3360' next ',//自定义检查间隔,默认值为1h '检查间隔' : 24 * 60 * 60 * 1000。//自定义更新提示信息“更新消息‘:’包更新从%=当前%到%=最新%”。//自定义强制更新的版本更新级别。默认值为“主要”级别:“次要”)。然后(()={/*在此启动命令行工具*/});Updater({ 'pkg': pkg,//logic ' onversionchange ' : function *(opts){ } })。然后(()={/*在此启动命令行工具*/});效果如下:
实现
用法很简单,我们来看看它的实现。
要求
先把需求整理一下。命令行检查更新程序至少应该提供以下功能:
最新版本可以远程获得
可以根据检查结果进行提示
当版本不兼容时,可以直接退出,强制用户升级程序
获取版本
获取最新版本的功能看似简单,就是发送请求从“某处”获取信息。但是有一些问题我们需要考虑:
哪里可以获取版本信息?
获取版本信息的策略是什么?(什么时候能拿到?如何处理获得的信息?)
从哪里获取版本信息
我们的命令行工具通常使用npm分发,最简单的方法是直接通过注册表获取它们。通过请求https://registry.npmjs.org/{name}/{dist-tag}.可以获得包对应标签的版本信息,结果如下:
//https://registry . npmjs . org/co/latest { ' name ' : ' co ',' version' :' 4.5.0'}在实际实现中,我们应该允许调用者自定义注册表地址、请求的dist-tag等。这样才能有更多的定制。
获取版本信息的策略
想到的第一个方法是,用户每次执行命令时都会获得一次版本信息。这种获取策略应该是最简单和实时的。
但这个策略实际上并不合适:
每次执行命令时,都需要发送一个请求来检查它。如果网络延迟,会阻碍命令的执行,影响用户体验
工具的版本更新不是很频繁,所以不需要实时检查
影响网络请求的因素很多,不能保证每次都能成功。应该提供本地缓存机制来存储请求的成功结果,并避免版本信息不可用
基于以上几点,我们设计了以下收购策略:
将发送网络请求获取版本信息的逻辑放在独立的后台进程中执行,确保主命令的执行不被阻塞
请求成功后,版本信息和检查时间会缓存到用户机器中
每次执行命令时,只读取本地缓存的版本信息,不发送网络请求
根据缓存的检查时间和当前时间,在一个时间间隔内不会创建额外的后台检查过程
将上述策略翻译成代码可能如下:
//读取本地缓存const checkinfo=yield updater的检查结果。读取check info(opts);const LastCheck=CheckInfo . LastCheck;const last version=CheckInfo . last version;//根据版本信息提示用户/.//在时间间隔内,直接返回if (date。now ()-last checkopts。check interval){ return;}//创建背景检查进程尝试{require ('child _ process ')。产卵(过程。execpath,[需要(' path ')。join(_ dirname,' _ check.js ')、JSON . stringify({ ' pkg ' : opts . pkg、//包信息' tag' 3360OPTS.tag、//dist-tag ' log file ' : opts . log file checked、//缓存文件路径' registry' : opts。registry//registry address})],{'stdio' : ['ignore ',' ignore ',' ignore'],' disconnected ' : true })。unref();} catch(e) {}后台进程执行的_check.js文件也很简单,如下所示:
const opts=JSON . parse(process . argv[2]);让lastVersion=尝试{//发送获取最新版本的请求const URL=normalize URL(opts . registry '/' opts . pkg . name '/'(opts . tag | | ' latest ');const res=yield got.get(url,{ 'json': true,' time out ' : 60 * 1000 });if(RES . body RES . body . version){ last version=RES . body . version;}} catch(e) {}//如果获取失败,最新版本为当前版本(package.version)if(!last version){ last version=opts . pkg . version;}让数据=yield util . readjson(opts . log file);if(!data[opts . pkg . name]){ data[opts . pkg . name]={ };}数据[opts.pkg.name]。lastVersion=lastVersion//最新版本的数据[opts.pkg.name]。last check=date . now();//检查时间//写入缓存yieldutil . write JSON(opts . log file,data);给出提示
当版本更新时,我们应该在终端提示用户。这里有两个问题:
提示文案问题
提示复印显示间隔的问题(总是显示?定期显示?)
我们的策略是:
提供默认提示副本,明确说明当前版本、最新版本和更新方法,允许调用者自定义提示副本
只要有更新,就会一直显示提示副本,因为我们希望用户经常更新
实现代码大致如下:
//compare version const type=updater . diff type(opts . pkg . version,lastversion,opts . level);If (type) {//Render提示信息const str=updater . template(opts . updatemessage | | updater . defaultopts . updatemessage)({ ' colors ' : updater . colors,' name': opts.pkg.name,' current': opts.pkg.version,' latest': opts.lastVersion,' command ' : ' NPM I-g ' opts . pkg . name });//prompt console . log(updater . boxen(str,{'padding' : 1,' margin' : 1,' border style ' : ' classic ' });}强制升级
对于npm模块,更新a.b.c版时一般有三种情况:
补丁:c位,小版本更新,通常是bug修复
次要:B位,中间版本更新,一般增加新功能和bug修复
专业,位a,大版本更新,一般不兼容升级
我们希望当远程版本以major的形式更新时,命令行工具会直接退出,迫使用户在使用之前进行升级。这样可以保证我们推送一个大版本后,所有用户都可以立即更新,而不是继续使用旧版本,造成版本碎片的问题。
实现代码大致如下:
//compare version const type=updater . diff type(opts . pkg . version,lastversion,opts . level);If (type) {//Render提示信息const str=updater . template(opts . updatemessage | | updater . defaultopts . updatemessage)({ ' colors ' : updater . colors,' name': opts.pkg.name,' current': opts.pkg.version,' latest': opts.lastVersion,' command ' : ' NPM I-g ' opts . pkg . name });//prompt console . log(updater . boxen(str,{'padding' : 1,' margin' : 1,' border style ' : ' classic ' });//不兼容的更新,如果(类型=='不兼容'){ process }则让进程直接退出。出口(1);}}摘要
命令行检查和更新看似简单,但仔细想想,还是有很多细节。希望这篇文章能对你有所启发。
版权声明:Node.js使用命令行工具来检查更新是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。