expressjs/express
Factory
Active contributors: dougwilson, ulisesgascon, wesleytodd
Purpose
lib/express.js is the entry point of the package. It exports createApplication, which builds and returns a fresh Express app. It also exposes the request/response prototypes, the Router and Route constructors from the external router package, and the body-parser/serve-static middleware factories.
Directory layout
lib/
└── express.js # 81 linesindex.js at the repo root simply does module.exports = require('./lib/express').
Key abstractions
| Symbol | File | Purpose |
|---|---|---|
createApplication() |
lib/express.js |
Builds an app function, mixes in EventEmitter and application prototypes, exposes app.request / app.response, calls app.init(). |
exports.application |
lib/express.js |
The application prototype (also exported as proto). Useful for monkey-patching. |
exports.request |
lib/express.js |
The request prototype (req from lib/request.js). |
exports.response |
lib/express.js |
The response prototype (res from lib/response.js). |
exports.Router |
lib/express.js |
Re-export of Router from the router npm package. |
exports.Route |
lib/express.js |
Re-export of Router.Route. |
exports.json, exports.urlencoded, exports.text, exports.raw |
lib/express.js |
Re-exports of body-parser factories. |
exports.static |
lib/express.js |
Re-export of the serve-static package. |
How it works
graph TD
Caller[user code: const app = express'()'] --> CA[createApplication]
CA --> AppFn[app = function 'req,res,next' -> app.handle]
AppFn --> Mix1[mixin EventEmitter.prototype]
Mix1 --> Mix2[mixin application proto]
Mix2 --> ReqProto[app.request = Object.create req with .app]
ReqProto --> ResProto[app.response = Object.create res with .app]
ResProto --> Init[app.init '()']
Init --> Return[return app]The interesting trick is that app is a plain JavaScript function whose prototype is augmented with the application and EventEmitter prototypes via merge-descriptors. This makes app(req, res) a valid Node HTTP request listener while preserving all the methods you'd expect (app.use, app.get, app.on, ...).
Object.create(req, { app: { ... } }) creates a per-app copy of the shared request prototype with .app pointing back to this specific app. Same for res. When app.handle later does Object.setPrototypeOf(req, this.request) for an incoming request, the req object inherits these methods plus the back-reference.
Integration points
- Reads
./application,./request,./responsefor the three prototypes. - Reads the external
routerpackage to exposeRouterandRoute. - Reads
body-parserforjson,raw,text,urlencoded. - Reads
serve-staticforstatic. - Read by
index.js(the package entry point). - Read by user code (
require('express')orimport express from 'express').
Entry points for modification
- To add or remove a top-level export from the package, edit
lib/express.js. Be aware: the public API surface is heavily depended on, so changes need TC discussion. - To change the order of mixin or the request/response prototype wiring, you also edit this file. Mounted-app inheritance, however, lives in
app.defaultConfiguration(see Application).
Source reference
// lib/express.js (excerpt)
exports = module.exports = createApplication;
function createApplication() {
var app = function (req, res, next) {
app.handle(req, res, next);
};
mixin(app, EventEmitter.prototype, false);
mixin(app, proto, false);
app.request = Object.create(req, {
app: { configurable: true, enumerable: true, writable: true, value: app },
});
app.response = Object.create(res, {
app: { configurable: true, enumerable: true, writable: true, value: app },
});
app.init();
return app;
}Key source files
| File | Purpose |
|---|---|
lib/express.js |
The factory, public exports, re-exports |
index.js |
Re-exports lib/express.js (one-liner) |
Related pages
- Application — the prototype mixed into the returned function.
- Request — what
app.requestinherits from. - Response — what
app.responseinherits from. - Architecture for the diagrammed picture.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.