本文来自V同学投稿的源码共读第六期笔记,写得很有趣。现在已经进行到第十期了。你或许经常看见 npm 更新的提示
。
npm 更新提示
面试官可能也会问你,组件库更新了,怎么让使用组件的人都知道。本文分析这个提示的原理实现,很有趣。
Hello,大家好,这里是V同学
今天我们又来看源码了
今天若川大大没有写源码阅读的掘金文章
正好,可以让我们一试身手
考验一下我们之前跟随着川大的源码所锻炼的源码阅读能力
今天我们要看的是 update-notifier 的源码
老样子,在我们阅读源码之前,先分析一手,看看这个到底是干嘛用的吧
这个是我们本期源码阅读的代码仓库
大家可以先克隆下来,我们且慢慢分析
我们可以用5W1H分析法来试着去分析一下
那么什么是5w1h呢,简单来说就是从
这六个纬度去思考
那我们就一个一个来
首先,我们要来看看本期源码是什么
通过度娘,我们可以大致的了解到,我们本期要看的源码
似乎是一个和更新有关的工具,可以更新你的npm包和cli应用程序
我们在看一下仓库的readme
现在就非常的清晰明了了,这是一个以非入侵的方式通知你更新的这么一个工具
那么我们为什么要读它的源码呢
有一下几点
1. 美化终端输出信息,描绘边框。
2. 我们可以学会怎么去开启子进程
3. 给一个node方法作为传参的几种方式
4. 通过configstore这个库我们能够持久化存储一些信息
5. 通过latest-version获取对应pkg包的最新版本信息
谁应该去读他的源码
以下几类人适合去读他的源码,当然也适合来看看我的源码阅读的文章
1. 源码爱好者
2. 学习爱好者
3. 希望能学到东西的人
4. V同学的粉丝
……
在我的源码阅读的文章里面,我会一步一步的手摸手教你怎么去拆分阅读以及调试源码
在哪里学的话,这个大家可以视实际情况而定
什么时候学的也取决于你的最佳学习时间,每个人的最佳的专注和学习时间不一样
具体的话视个人情况而定
那么我们就到了最关键的一点
怎么去读
没有度过源码的同学请放心
跟着V同学走,手摸手,包你药到命除
额不不不,是药到病除
刚刚,我们把仓库的地址克隆下来了,那么接下来我们就安装一下依赖吧
进入到对应的仓库地址
输入一下命令
npm i
或者
yarn
测试非常的重要,他可以让我们非常清晰的了解
一个框架的功能以及作者写这个测试的意图,所以我们看源码,可以先看看测试
我这边用的是 vscode
找到 package.json 文件,点击调试
进入测试
有人说了,我用的不是vscode怎么办呢
其实也简单的
首先还是先问问百度,你是用的编译器是否有对应的测试插件
没有的话,可以在编译器的控制台输入测试中的命令
npm run test
或者
yarn test
即可运行对应的测试,这个是看全部代码的方式
具体通过测试看源码的案例,可以看我的这一篇笔记
今天我们只看核心代码
所以我们进入example 这个 JS 文件里面去
这个案例非常的简单,一共就17行代码
运行第四行作者给我们的命令
node example
我们发现没有反应,那么这是怎么一回事呢
我们来看一下注释
You have to run this file two times the first time
翻译过来就是第一次必须运行此文件两次
嘿,我运行过的别的程序都只需要运行一次,就你要运行两次,你搞特殊是吗
那么我们仔细来想想,要运行两次呢?
我们在来看看注释
This is because it never reports updates on the first run
翻译过来就是
这是因为它不会在第一次运行时报告更新
我们带着第一次为什么不会更新的问题来看源码
对于vscode进行node调试
我把过程放在以下gif图里面,大家可以进行参考
首先我们在example里面打上断点
然后进入调试
我们这时候发现,断点进来了
我们点击调试的↓按钮
我们发现我们进到了index.js文件里面
所以这个就是他的核心文件
我们进入到了183行
在往下走,我们进入到了第一部分
我们传入的参数会被option接到
然后对拿到的对象进行数据清洗,只保留需要的数据
如果没有需要的数据,就给他抛出个错误
接下来把需要的数据挂载到实例对象身上
检查更新时间是否符合规范
知识点:process.env 是 Node.js 中的一个环境对象。其中保存着系统的环境的变量信息。
通过获取process检查是否禁用更新
知识点:isCi的作用是如果当前环境是持续集成服务器,则返回true
判断是否在Npm脚本中通知
判断一下你是否禁用更新了
知识点:ConfigStore的作用是轻松加载和保留配置,而无需考虑在哪里以及如何
知识点:Chalk的作用是让你的终端更美观好看,具体在Vue-release这篇文章中有提到过
如果你没禁用的话,帮你把包名通过ConfigStore
进行持久化存储,顺便把最后一次检查的时间更新成现在
接下来我们顺着代码的路径,走到了中间这一行
进去的第一目光我们的卡姿兰大眼睛就可以看到好几个判断
第一个判断的大概意思是
如果你没有本地存储或者禁用更新的情况下,那么就不执行了,我们就说拜拜了
接下来,他拿到我们的之前存进去的update对象来更新
这里有一个关键点,就是我们之前埋下的坑
他第一次为什么不执行
因为这里第一次的时候,我们没有执行过check.js这个文件
所以我们这里的这个update是空的
这里在埋下一个点,为什么updata是空的导致他只执行一次呢,这个后文会讲到
我们接着往下看
知识点:spawn => 详情请参考spawn
这里通过spawn
开启一个子进程,运行check.js
,然后把options
作为调用check.js
的命令行参数
接下来我们就进入到了check.js文件里面
const options = JSON.parse(process.argv[2]);
这一段代码,意思是把我们刚才通过控制台传的option参数拿过来
知识点:latestVersion => 获取最新版本的 npm 包
拿过来之后新建一个实例 ,然后去拿到对应的包名、最新版本、当前版本、版本差别的信息
拿到信息之后,更新一下最后一次检查更新对应的时间
在顺便把信息塞到持久化存储当中的update里面、
然后关闭spawn
打开的子进程,返回原来的函数里面
当拿到最新版本的信息之后,他会把对应的实例对象返回出去
返回到了example.js文件里面
返回到了example之后去执行notify
虽然说,之前的update被存进去了,但是在notify的时候没有被读出来
所以就导致之前的update因为是空的,在最开始的时候,进不去notify的函数,就被return掉了
这就是为什么第一次执行的时候,什么都不返回的原因了
知识点:is-installed-globally:检查您的软件包是否已全局安装
知识点:is-yarn-global:检查您的yarn包是否已全局安装
接下来他会检查你是不是全局安装了,全局是不是用的yarn安装的
接下来就是控制你的控制台,在你的控制台上输入一些安装命令
知识点:boxen:在终端中创建框
完成之后,通过boxen构建一个框框,然后用template去显示更新信息
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8