不知不觉,已经一个月没写文章了,因为刚换了工作,正好接触到了egg,以前都是只会用express起个服务,连接数据库做CRUD。没有仔细的学习一下node这门语言主流框架的演变。所以打算好好学习下框架的大致思路实现,方便以后自己造轮子。下面我就分享下我的理解,错了请轻喷,我也好再多学习点经验。
要有自己的理解
我遇到过几位前辈都跟我说过类似的话,就是学习一个框架或者封装的实现,一定要去看它的源码,直接在github上搜就好了,不要只听别人的XXX源码解析,那只是别人的见解,复杂的地方就被别人一笔带过,给你讲个思路而已。一开始我也觉得看源码很难理解,很乏味,所以内心有点抗拒,但是当我第一次学习redux源码的时候,注释多的离谱,英文也是很简单那种,遇到不理解的单词和语句就直接有道翻译划词翻译就好。所以我一般是看几遍流程,细节大致都搞不清的就去网上找资料,最起码大致的思路得捋出来
koa为何精简
核心内容就4个js文件。Koa 应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的。
图1来自源码
application
这个文件的作用是,提供了挂载中间件的方法use,并且在http.createServer的requestListener里执行了callback(compose 中间件函数列表),返回一个接收(req, res)入参的Fn. fn里根据req和res生成特定的content上下文对象,最后执行中间件compose后的函数,并且在then后返回req接口response的内容。
图2来自node官网
图3来自图2的最后一句的request的链接内容
来欣赏一下koa文档的经典middleware.gif,下面开始讲解
图4,middleware.gif
use
图5来自源码application
我们来看一下源码,是不是可以发现,注释很详细。定义了入参和返回,虽然没有用ts来改写但是也够用了。这里做了什么呢?接收一个Fn然后把它push到middleware数组里,最后返回this就是当前对象,所以能链式的调用use。
listen
图六来自源码application
创建一个http服务,并且注册request事件监听。
callback
图七来自源码application
关键库:koa-compose
通过这个就实现了,也就图四的过程。
compose方法是通过引入npm包,按住ctrl点进去发现,这个包就一个函数….
const compose = require('koa-compose');
复制代码
图八来自源码application 著名的洋葱圈模型
有没有觉得app和content这些对象很强大,怎么什么属性都有?当然是挂上去的啦。。。
图九来自源码koa-compose 著名的洋葱圈模型
一个 ctx 即可获得所有 koa 提供的数据和方法,而 koa 会继续将这些职责进行进一步的划分,比如 request 是用来进一步封装 req 的,response 是用来进一步封装 res的,这样职责得到了分散,降低了耦合,同时共享所有资源使得整个 context 具有了高内聚的性质,内部元素互相都能够访问得到。
content
这个文件呢,主要是是事件劫持(委托)给相应的对象,
关键库:delegates
类定义
采用工厂模式,new一个实例。
method
getter和setter
实现是委托,把content的访问,委托给相应的target
request 和 response
这个就靠大家去了解了,细节太多。当需要精读的时候,就要debug到引用的第三库,像上面的koa-compose和delegates一样,可以加console.log去打印一些日志。顺带一提的是,需要重新启动koa
最后
学习源码,可以新建个文件夹,然后npm init -y 生成默认的.json文件,然后执行npm install XXX、cnpm install XXX、 yarn XXX。(XXX为包名)然后安装好依赖后就愉快的学习了。一般TS文件的可阅读性比较强,因为都会有个抽象类告诉你这个方法是做什么的。然后去另一个文件找具体实现。碰到更完善的库还会有测试文件,测试文件里一般包含了这个库的绝大多数的使用方式,具体可以参考react hook的测试文件。
要放平心态去学习未知的东西。共勉~~