終於騰出手來學習express。express在node.js中一株獨秀。好像任何一種有主導的托管平台的語言,都出現這現象——馬太效應。express是社區的共同孩子,里面聚集上社區最好的常用模塊。從源碼來看,它分為八大塊,application.js, express.js, middleware.js, request.js, response.js, utils.js, view.js與router。
express.js相當於過程式語言的main函數,是一個入口,吐出express這個工廠函數。
從代碼組織來看,我們會發現一個有趣的現象。引入語句總是位於上方,主程序夾在中間,主程序用到的一些輔助函數放在后面。在node.js,我們會頻繁看到ES5的一些新方法,這也node.js的特色之一。
var connect = require('connect') , proto = require('./application') , Route = require('./router/route') , Router = require('./router') , req = require('./request') , res = require('./response') , utils = connect.utils; /** * Expose `createApplication()`. */ exports = module.exports = createApplication; /** * Expose mime. */ exports.mime = connect.mime; /** * Create an express application. * * @return {Function} * @api public */ function createApplication() { var app = connect(); utils.merge(app, proto); app.request = { __proto__: req, app: app }; app.response = { __proto__: res, app: app }; app.init(); return app; } /** * Expose connect.middleware as express.* * for example `express.logger` etc. */ for (var key in connect.middleware) { Object.defineProperty( exports , key , Object.getOwnPropertyDescriptor(connect.middleware, key)); } /** * Error on createServer(). */ exports.createServer = function(){ console.warn('Warning: express.createServer() is deprecated, express'); console.warn('applications no longer inherit from http.Server,'); console.warn('please use:'); console.warn(''); console.warn(' var express = require("express");'); console.warn(' var app = express();'); console.warn(''); return createApplication(); }; /** * Expose the prototypes. */ exports.application = proto; exports.request = req; exports.response = res; /** * Expose constructors. */ exports.Route = Route; exports.Router = Router; // Error handler title exports.errorHandler.title = 'Express';
這個JS文件會返回一個函數,叫做express,其實就是這句exports = module.exports = createApplication;
另一個難點是__proto_的應用, 我們知道prototype是應用於構造函數,而__proto_則是應用於它的實例,簡單來說它相當於 obj.constructor.prototype。
app.response = { __proto__: res, app: app };
我們可以想象response這個對象被賦以了一個原型,叫做res,它的特權方法與屬性放到app中。 req 與res都是內置對象的一個實例的加強版。