I don't read books, never went to school, I just read other people's code and always wonder how things work. ——TJ Holowaychukjavascript
这篇文章的主要的目的是经过研究express核心源码,让咱们对express深刻理解,不只会用express,还要理解其背后的思想,提升开发效率。研究express源码,学习大神的代码结构。本文只介绍核心代码和核心流程,类型判断和express的使用等不包括在内。java
express里的核心文件是index、express、application、router/index、router/layer、router/route。 index里只有一句话git
module.exports = require('./lib/express');
复制代码
导入express,并导出。express文件里是导出许多api,像express、express.Router等。咱们开发是用到的express(),其实是执行createApplication()。application里是和app相关的api。 router/index里是和router相关的代码,router能够理解成路由器,把各个请求发给route。咱们不会直接调用router/layer里的方法,layer是一个抽象概念,在express里中间件、路由都放在app._router.stack里,stack里的每一个元素就是一个layer。 route里也有一个stack,里面的元素也是layer。github
const express = require('express');
const app = express();
app.get('/', (req, res,next)=>{
res.send('Hello World');
next()
});
app.listen(3000,()=>{
console.log('server is ok');
});
复制代码
function createApplication() {
var app = function(req, res, next) {
app.handle(req, res, next);
};
//把proto的方法给app等初始化操做。
return app;
}
复制代码
app.get = function(path){
this.lazyrouter();
var route = this._router.route(path);
route[method].apply(route, slice.call(arguments, 1));
return this;
};
复制代码
var layer = Layer('/', {}, handle);
layer.method = method;
this.methods[method] = true;
this.stack.push(layer);
复制代码
proto.route = function route(path) {
var route = new Route(path);
var layer = new Layer(path, {}, route.dispatch.bind(route));
layer.route = route;
this.stack.push(layer);
return route;
};
复制代码
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
复制代码
在express里建立路由主要由这几种方法:express
this.lazyrouter();
var route = this._router.route(path);
route[methods](fn);
复制代码
proto.route = function route(path) {
var route = new Route(path);
var layer = new Layer(path, {}, route.dispatch.bind(route));
layer.route = route;
this.stack.push(layer);
return route;
};
Route.prototype[method] = function(){
//把参数转化成数组 handles
for (var i = 0; i < handles.length; i++) {
var handle = handles[i];
var layer = Layer('/', {}, handle);
layer.method = method;
this.methods[method] = true;
this.stack.push(layer);
}
return this;
};
复制代码
//Route的数据结构
{
methods:{},
path:path,
stack:[
Layer{
handle:handle
method:method
...
}
]
}
复制代码
var layer = new Layer(path, {}, fn);
layer.route = undefined;
this.stack.push(layer); //app._router.stack.push(layer)
复制代码
//app.use建立的layer
Layer{
route:undefined,
handle:fn
}
//app.get建立的layer
Layer{
route:route,
handle:route.dispatch.bind(route)
}
复制代码
Layer{
route:undefined,
handle:router
}
复制代码