express源码分析

关于本次对express源码的学习,我想带着 :point_down: 几个问题来阅读源码:

序号 问题描述
1 express所导出的模块中都有哪些元素
2 express中的methods(get/post/put/delete等)、set、use、all方法是如何实现的
3 express针对req、res追加的属性都有哪些
4 express中的渲染引擎是如何实现的
5 从express的实现中可以学到什么

:stars: 在回答上述的问题时,先看 :point_down: 的一个模块结构图:

Express

:stars:connect类似,express也是一个中间件函数(关于中间件的知识,可以看下之前关于中间件实现原理文档)中所描述的, express入口 同样从一函数开始,通过返回的带reqresnext等参数的方式,来提供给到相关的http模块作为回调,使得每一个请求动作都经过这个express框架!唯一不同的是,这个创建出来的app继承了EventEmitter,使得我们可以通过on/emit的方式来设置对应的监听以及触发监听!!

:earth_africa: 另外的,根据这个中间件,在创建成功的app中,默认都提供了queryexpressInit两个中间件,用于做一些初始化工作以及参数的解析动作!

一、express中所导出的模块都有哪些元素

Express中的Router,针对客户端请求的中间件库函数

1、Router

每一次客户端请求时创建的一个路由对象(这里是所有的请求都共享的Router对象),用以缓存处理客户端请求的路由执行路径对象堆栈Layer,它底层也是一中间件实现类,用来自动从stack列表中获取每一个中间件对象。

2、Route

用来精准匹配路径的一个路由器对象,一般与Layer关联,Route与Router的关系就有点类似于vue-router中的Route与Router两者的关系,前者代表精准匹配客户端请求路径,后者用户缓存客户端执行时所有中间件的执行顺序

3、Layer

用来代表每一个被加入进来的中间件对象,其缓存的handle属性则指向用户设置的中间件回调函数!!

4、那么这三个模块之间是如何配合工作的?

express使用Layer包装中间件的过程

要想理解这三个模块之间是如何协同的,先看一下 :point_down: 的一个关于其使用方式

  1. 常规的最普遍的使用方式 常规的最普遍的使用方式 :point_right: 将回调缓存在_router中的stack中的Layer中的Route中的stack中的Layer中的handle属性中;
  2. 使用了两个连续的中间件处理的方式 使用了连续的两个中间件 :point_right: 将两个回调缓存在_router中的stack中的Layer中的Route中的stack中的两个Layer中的对应handle属性中;
  3. 使用了use的方式 通过use使用连续的两个中间件 :point_right: 将两个回调缓存在_router中的stack中的Layer中的对应handle属性
  4. 使用了route精准匹配的方式 route精准匹配 :point_right: 将回调缓存在_router中的stack中的Layer中的Route中的stack中的Layer中的handle属性中;
  5. 采用Router模块化使用的方式 采用router模块化使用的方式 :point_right: 将两个回调缓存在_router中的stack中的Layer中的对应handle属性,且拥有以名字为router的Layer
  6. 采用混用的方式 混合使用的方式

:stars: 将上述的情况进行一个总结就是:使用use(包括Router)的方式,将会将所有的中间件按照定义顺序依次作为一Layer存储在app._router.stack中,而其他的中间件则存储在app._router.stack.route.stack

:point_up: :u6709: 这么些不同的关于路由的使用方式,对应的匹配规则,那么这三者之间她们是如何协同工作的呢:

最简单的express的get中间件监听日志输出 首先先看一下关于express的一个运行日志输出,如上图所示,也就是在设置自定义的中间件的时候,express已经帮助我们设置好了这个express的基础中间件了, 相应的,这边也同时整理了关于这个设置对应中间件的一个过程,如 :point_down: 图所示: express设置中间件的一个过程

二、express中的methods(get/post/put/delete等)、set、use、all的实现过程

通过对引用的http-methods所提供的所有方法进行一个迭代器,并对每一个方法统一进行追加对应的函数方法,使得app可以直接调用对应的method方法,而其中的调用顺序路径如下: express中的get方法调用的逻辑

三、express针对req、res所追加的属性都有哪些?

  1. req.route,发生于Router中间件的handle处理过程,用来精准匹配对应的path,并捆绑相应的fn中间件回调函数到Layer中的handle属性中;
  2. req.params,发生于Router中间件的handle处理过程,用来捕获客户请求所传递的参数数据;
  3. req.query,发生于express所提供的公共的query中间件的过程中,根据请求类型来获取对应的查询参数;
  4. res的一系列响应动作,详见之前的文章

四、express中的渲染引擎是如何实现的?

首先,先来看一下关于模版引擎的使用与实现: 渲染引擎的使用 渲染引擎的使用二 视图引擎的实现 :confused: 为什么使用res.render()方法,就可以实现一个html页面的渲染结果呢? 概括成一句话,就是:根据预先存留的关于如何标志唯一渲染引擎的标示,然后在响应的时候,通过引擎的render函数,将结果渲染成为一个html字符串,通过res.render函数来渲染出去,而所提供的视图渲染引擎,一般都提供了对应的express的一个兼容处理动作!

五、从express的实现中可以学到什么?

  1. 通过在导入的http-method方法数据枚举中,采用[]的方式来为对象添加属性,实现动态化添加所有的http请求方法的回调处理动作;
  2. 中间件允许嵌套中间件的方式,可以是在某个具体的中间件中采用中间件的技巧,使得在某个中间件内部可以通过预先定义好的中间件顺序来执行对应的逻辑动作!

results matching ""

    No results matching ""