使用express时,代码会这样写:
var express = require('express');
创建一个express的应用,代码:
var app = express();
那么express()是什么?它执行createApplication()
//express.js exports = module.exports =createApplication; /** * Create an express application. * * @return {Function} * @api public */ function createApplication() { var app = function(req, res, next) { app.handle(req, res, next); }; mixin(app, EventEmitter.prototype, false); mixin(app, proto, false); app.request = { __proto__: req, app: app }; app.response = { __proto__: res, app: app }; app.init(); return app; //执行的结果就是app是一个实例,它有私有成员对象:request和 response,同时继承Event模块中的EventEmitter的原型。 }
在express.js中,要区分下面两个包:
var Route = require('./router/route'); var Router = require('./router'); //对外都暴露Route和Router,他们两者有些不同, //Router是Route的超集,两者的联系只在Router.route用到。调用Router.route会得到一个route,不过给Router.stack添加了一个Layer, //该Layer通过Router的参数和route.dispatch和用户的path来定义的。 //route只有三个成员,stack数组(储存Layer对象),path(路由的路径)和method对象。 //其中stack数组与Router一样,同时两个对象的原型都有methods的和all的方法 exports.Route = Route; exports.Router = Router;
express也继承了application.js中的方法。执行app.init();
app.init = function init() { //给app类/对象赋值三个公用成员, 在初始的过程中,有一个成员变量很关键,就是router this.cache = {}; this.engines = {}; this.settings = {}; // 初始化配置,在研究defaultConfiguration之前,抽象下app.set函数,它就是给setting赋值的函数,同时针对key = "etag" 和 query parser以及"trust proxy"进行特殊的的设置。 this.defaultConfiguration(); };
app还挂有很多方法,这些可以在express的api中的application的方法找到!其中最重要的方法是app.use,它用来构造路由所执行的函数的一个数据结构_router,express在执行过程中,会遍历这个结构。
1.1app.use方法
//use的使用 var express = require('express'); var app = express(); function handlerWrap(){ console.log("1"); } app.use("/", handlerWrap); //路径/会调用hanlerWrap方法
app.use源码
this.lazyrouter(); app.lazyrouter = function lazyrouter() { //给a公有变量_router赋值,它是对象Router的实例。 if (!this._router) { //实例化Router this._router = new Router({ caseSensitive: this.enabled('case sensitive routing'), //false strict: this.enabled('strict routing') //false }); //router.use(path,fn); 为path建立layer,有多少个fn,就建立多少个Layer,然后把这个layer压入router.stack数组中。初始定义了两个Layer this._router.use(query(this.get('query parser fn'))); //this.get('query parser fn')为一个函数: this._router.use(middleware.init(this)); } };
if (!fn || !fn.handle || !fn.set) { //handlerWrap函数为handler、 set成员!,如果fn函数没有handle,或者set函数,调用router.use(path,fn)。也就是说那不是express的实例,大部分插件都会直接执行。 return router.use(path, fn); //rounter.use直接把该函数构造成一个Layer成员,实际上是给router.stack添加一个layer成员。 } debug('.use app under %s', path); fn.mountpath = path; //如果是express的对象,那么给express这个对象成员mountpath赋值为path(可能含有正则); fn.parent = this; //fn变成子express对象,当前的express为父。 // restore .app property on req and res //执行use,封装了fn, router.use(path, function mounted_app(req, res, next) { var orig = req.app; //这里看的不太懂。 fn.handle(req, res, function (err) { req.__proto__ = orig.request; res.__proto__ = orig.response; next(err); }); }); // mounted an app console.log("fn="+JSON.stringify(fn)); fn.emit('mount', this); // 进入router/index.js中,执行proto.use()方法。 // 实际上是给router.stack添加一个layer成员, var layer = new Layer(path, { sensitive: this.caseSensitive, strict: false, end: false }, fn); layer.route = undefined; //给layer.route赋值undefined this.stack.push(layer);