express 精读

tj.jpg

先上传tj大神的照片,表示膜拜

刚知道,他是学设计的,刚知道他长得也这么设计,也刚听说,要想成为他一样的大神,要读源码。于是有了这篇文章。

express 框架

  • application, request, response, router 四大块
  • 核心的思想是中间件,基础是node的http模块
  • 中间件的基础是 layer, 核心是router

application


express 返回的 createApplication方法,在当在应用层执行const app = express()的时候,返回的还是一个函数 function(req, res, next){ ... app.handle ...},application 的作用就是在app上挂载,自己封装的request,response,mixin继承proto, EventEmitter.prototype对象方法。

 function createApplication() {
 var app = function(req, res, next) {
   app.handle(req, res, next);
 };

 mixin(app, EventEmitter.prototype, false);
 mixin(app, proto, false);

 // expose the prototype that will get set on requests
 app.request = Object.create(req, {
   app: { configurable: true, enumerable: true, writable: true, value: app }
 })

 // expose the prototype that will get set on responses
 app.response = Object.create(res, {
   app: { configurable: true, enumerable: true, writable: true, value: app }
 })
 app.init();
 return app;
}

中间件


  • application 的主要扩展在 proto,分析的时候主要抓住 app = handle(req, res, next)。由app.handle 到 router.handle,主要逻辑就在此。
  • node 模块http创建web服务类似 http.createServer(app).listen(80); 框架的重点是封装app。app就是中间件的有序执行集合。
  • 什么中间件的重点是 app.use 和 app[method]。
var express = require('./index');
var app = express();
// 声明中间件
app.use(function cc(req,res,next){
console.log("111");
next();
})

app.get('/users', function(req, res, next) {
console.log(11111)
next();
}, function(req, res, next) {
console.log(22222)
next();
}, function(req, res, next) {
console.log(33333)
next();
}, function(req, res, next) {
console.log(44444)
res.send('hello world')
})

var server = app.listen(8081, function() {
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})

打印中间件:


image.png

注意:前两个中间件是框架自带,第三个是use声明的中间件,第四个是app[method]声明的。

  • 有序执行是声明的顺序 和 next 方法
    next 有两个 router/index.js 和 router/route.js 文件中各有一个next
    *** 第一个next是上图中四个红色箭头指向的中间件依次执行的保证。
    *** 第二个next是第四个箭头中route.stack各个layer顺序执行的保证。
    app中的 res, req, next 就是这么一个layer 传到下一个layer。碰到route不等于undefined时候,在进入下一层 layer,直到最后一个中间件,调用res.send 终结返回,完成一个http请求。

router.handle里面 next() 函数是处理各种中间件的。while 循环遍历 stack(初始化所有中间件的数组)。遍历出所有符合当前路由中间件(layer),
next 一个一个处理,然后返回。

response / request


相对比较简单,关键是看如何跟框架结合。

  • request.js 中 var req = Object.create(http.IncomingMessage.prototype); req 是基于node http模块当原型链重新声明 req。又在req自身属性上挂在一些自定义的常用到的方法。
  • 同理 response.js 中 var res = Object.create(http.ServerResponse.prototype); res 也是基于node http重新声明的。挂在自己的常用函数。
    application中。自己封装的res, rep都是直接挂在到app静态属性上的。
    • 1: 是为了暴露出去,用户可以自行扩展。
    • 2: 是为了柯里化,传入到中间件中。
      在每个声明中间件 无论使用use 还是什么app[method] 都需要先执行 lazyrouter


      image.png

      第一个use 默认的中间件是为了处理请求参数匹配路径
      第二个use 是为了初始化res和req


      image.png

注意:其实并没有执行,只是先把app 传过去,app上挂在了,res, rep 返回了一个中间件,当用户请求的时候,先去执行这个中间件。

image.png

感悟


分析别人源码,是习惯,先掌握主要脉络反推用户的框架思想,提升格局。在逐行分析,理解框架写法的优雅。先抓大放小,再锱铢必较。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容