express源码分析1:express实例的构造函数
gsbybbgsbybb -这篇文章是express源码阅读
系列文章的第一篇,这个系列的文章主要目的是想从一个Node.js的初学者的视角,结合express
的API文档去分析解读express
这个热门库的实现原理。
从使用者的角度来看,express的入口应该是:
const express = require('express');
通过express仓库的package.json以及index.js可以看出,express整体的入口位于./lib/express
。如下图
./lib/express
主要包含以下几个部分:
这几个部分基本上可以和express的API文档对应起来
通常在使用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 from
const 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
这两个属性,主要包含一下关键点
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 ,这个知识点将会在后面分析中经常出现。
Tags 标签
node.jsexpress扩展阅读
深入理解函数调用原理
2021-01-07 14:58:59 []Deno 双周刊 #1 - Deno 获 2020 JS 年度突破开源奖
2021-01-08 08:54:29 []Spring Ioc 实例化 Bean 对象有几种方式?
2021-01-15 02:09:56 []Windows10错误在打开特定路径时导致BSOD崩溃
2021-01-19 06:56:04 []Lighthouse使用说明
2021-07-29 03:17:21 [米花儿团儿]电子物流中的EDI 应用
2021-07-28 23:52:25 [阿兵]Python实现一个简单的毕业生信息管理系统的示例代码!非常简单
2021-07-29 06:56:23 [mengy7762]MacBook Pro M1配置前端开发环境
2021-07-28 12:11:55 [summer]node js 各类数据库常用方法封装的、心路历程、、
2021-07-28 22:36:29 [wzj5cnaz]strapi安装
2021-07-29 09:16:13 [A_Ghost]加个好友,技术交流
