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
}
複製代碼