这篇文章是express源码浏览
系列文章的第一篇,这个系列的文章次要目标是想从一个Node.js的初学者的视角,联合express
的API文档去剖析解读express
这个热门库的实现原理。
express的入口
从使用者的角度来看,express的入口应该是:
const express = require('express');
通过express仓库的package.json以及index.js能够看出,express整体的入口位于./lib/express
。如下图
./lib/express
次要蕴含以下几个局部:
- express实例的构造函数:createApplication
- express提供的实例对象:application、request、response
- express提供的路由性能: Router,Route
- express默认反对的middlewares: express.json()、express.query()等
这几个局部基本上能够和express的API文档对应起来
2、3、4局部次要就是简略的赋值导出,不做过多的剖析
express实例的构造函数
通常在应用express
的时候会呈现以下代码:
const express = require('express');const app = express();
而后面提到的createApplication
就是对应咱们调用的express()
.
function createApplication() { var app = function(req, res, next) { app.handle(req, res, next); }; mixin(app, EventEmitter.prototype, false); mixin(app, proto, false); // expose the prototype that will get set on requests app.request = Object.create(req, { app: { configurable: true, enumerable: true, writable: true, value: app } }) // expose the prototype that will get set on responses app.response = Object.create(res, { app: { configurable: true, enumerable: true, writable: true, value: app } }) app.init(); return app;}
express实例的类型
createApplication
的返回值是一个function
,而且是在express应用中很常见的listener
var app = function(req, res, next) { app.handle(req, res, next);};
也就是说,创立的express实例实质上是一个listener,至于怎么应用,咱们须要额定延长一下Node.js中http模块提供的createServer办法。上面是一个简略的示例
const http = require('node:http');// Create a local server to receive data fromconst server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ data: 'Hello World!', }));});server.listen(8000);
联合下面的代码,能够发现express实例其实和Node API创立一个HttpServer所须要的listener参数很类似,为了不延长太多额定的常识,咱们先能够简略粗犷的了解为:express实例其实就是一个封装过的HttpServer对应的listener,这个listener会在创立HttpServer的时候被应用。
express实例上的办法挂载
在createApplication
中咱们接下来会看到两个mixin
相干的逻辑mixin
应用的是merge-descriptors这个库,所以这两行实质上都是在拓展express实例上的属性和办法。
mixin(app, EventEmitter.prototype, false);
通过合并EventEmitter的原型,让express实例上领有了on
、once
等这些事件监听办法。
mixin(app, proto, false);
这一行则是给express实例上拓展更多的自定义办法,proto
内容比拟多,这边不做过多的延长。
express实例上的request、response对象
在创立express实例的时候,会给实例减少request
和response
这两个属性,次要蕴含一下关键点
- 它们别离是以 express本人提供的
request
和response
为原型 创立 - express本人提供的
request
和response
为原型 别离是以Node。js的http
模块中的http.IncomingMessage.prototype
和http.ServerResponse.prototype
创立,并在下面拓展了一些自定义办法。 - 实例上的
request
和response
属性都额定减少了实例的援用,不便在解决申请和响应的时候,能够同时拜访和批改express实例
app.init()
这部分延长的常识比拟多,前面会放在express中application对象中去剖析。
总结
这篇文章的重点次要剖析了express
实例的构造函数,函数自身内容比拟少不过十多行代码,然而带出了一个重点常识:express实例是一个封装过的HttpServer对应的listener ,这个知识点将会在前面剖析中经常出现。