// 创建get,post,put, delete等方法
var methods = require('methods');
methods.forEach(function(method){
Route.prototype[method] = function(){
var handles = flatten(slice.call(arguments));
for (var i = 0; i < handles.length; i++) {
var handle = handles[i];
if (typeof handle !== 'function') {
var type = toString.call(handle);
var msg = 'Route.' + method + '() requires a callback function but got a ' + type
throw new Error(msg);
}
debug('%s %o', method, this.path)
var layer = Layer('/', {}, handle);
layer.method = method;
this.methods[method] = true;
this.stack.push(layer);
}
return this;
};
});
express原理分析
application
统一监听入口,利用http模块createServer注入
this
, 实现对所有请求的拦截处理模块提供app.set, app.use, app.route, app.enable, app.disable, app.render, app.listen, app.engine等方法 其中app.use, app.get, app.post, app.route等方法实际上就是调用route的相应方法,实现相应路径处理中间件的注册。后面会说到route的这些方法都做了那些事情。
request
request 相对比较简单,express以http.IncomingMessage.protoType为原型,创建了一个新的req对象。并在其之上添加一些方法和一些获取头部信息的getter
response
response 是以http模块ServerResponse.protoType为原型创建的res对象, 添加了很多常用的方法, 具体可以参考api文档, 比如:
typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');
res.sendFile 返回文件
重点说下res.render这个方法, 咱们服务端渲染的利器。render调用了express自定义的render方法,express专门创建了一个view.js来处理render. view提供了设置engine,查找并解析提供的目录下html文件, 最后通过fs.statSync将文件内容返回到客户端
middleware
middleware!
middleware是整个express处理的核心思想,整个express router机制都是基于中间件思想去处理。
路由的初始化都会先初始化query,init作为初始执行中间件,其中init添加locals至res对象。query添加query到res对象。保证每个请求进来都会先执行这两个中间件。
layer
router, route, layer结合实现了对路由的中间件处理体系,是整个express的核心部分,先说说layer
layer实例主要有如下属性:
layer实例主要的方法:
route
每一个路径创建一个route route有dispatch,all等方法, route里面每一个中间件对应添加了一个layer实例,设置当前路径为根路径及其对应的的处理函数
route实例对应的属性
route实例对应的方法
post, get, put, all等注入中间件方法
每一个方法的调用会创建一个layer挂在当前route的stack属性下
router
负责处理所有路由过来的请求,设置相应路径的处理中间件,每一个路径都会创建一个Route, 路径下的每一个中间件都会创建一个Layer实例推入当前Route.stack处理栈。当请求进来时命中相应路径时,通过route.dispatch方法遍历stack里面layers,并进行method匹配,匹配上之后就会执行。通过next逐个往后传递。
router里面有几个重要的方法
至此,express的所有模块咱们就说完了。中间件和路由的思想是express的核心,整个中间件的执行过程也j借鉴了node.js流式Steam处理的思想,从前往后逐个处理修改参数或者返回结果。express的灵活之处在于,可以在请求的任意环节添加任意中间件进行我们想要的处理。后续我会继续写koa的源码解析。一步一步剖析现在主流node.js框架的实现。