当前位置: 首页 > 后端技术 > Node.js

Express源码分析一:express实例的构造方法

时间:2023-04-03 15:00:34 Node.js

文档分析和解读express这个热门库的实现原理。从用户的角度来看,express的入口应该是:constexpress=require('express');从express仓库的package.json和index.js可以看出express的入口位于./lib/express。如下图所示。/lib/express主要包括以下几个部分:express实例的构造函数:createApplicationexpress提供的实例对象:application、request、responseexpress提供的路由函数:Router、Routeexpress默认支持的中间件:express.json()、express.query()等部分基本可以对应expressAPI文档。第二、三、四部分主要是简单的赋值和导出,没有过多的分析。express实例的构造函数通常在使用express时会出现如下代码:constexpress=require('express');constapp=express();而前面提到的createApplication对应的就是我们调用的express()。functioncreateApplication(){varapp=function(req,res,next){app.handle(req,res,next);};mixin(应用程序,EventEmitter.prototype,false);混合(应用程序,原型,假);//公开将根据请求设置的原型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();returnapp;}express实例createApplication类型的返回值是一个f函数,它是一个非常常见的监听器varapp=function(req,res,next){app.handle(req,res,next);};也就是说,创建的express实例本质上是一个监听器,至于如何使用,需要扩展Node.js中http模块提供的createServer方法。这是一个简单的例子consthttp=require('node:http');//创建一个本地服务器来接收来自constserver=http.createServer((req,res)=>{res.writeHead(200,{'Content-Type':'application/json'});res.end(JSON.stringify({data:'HelloWorld!',}));});服务器.listen(8000);结合上面的代码,我们可以发现express实例其实和NodeAPI创建HttpServer所需的监听器参数非常相似。为了不扩展太多额外的知识,我们可以简单粗略的理解为:express实例其实是一个监听器对应一个封装好的HttpServer,创建HttpServer的时候会用到这个监听器。express实例上的方法安装在createApplication中。接下来,我们会看到这两个mixin相关的逻辑mixin使用了merge-descriptors库,所以这两行本质上是在扩展express实例的属性和方法。mixin(应用程序,EventEmitter.prototype,false);通过合并EventEmitter的原型,使express实例具有on、once等事件监听方法。混合(应用程序,原型,假);这一行是为了在express实例上扩展更多的自定义方法。proto的内容比较多,这里就不过多展开了。在创建express实例上的request和response对象时,会在实例中添加request和response这两个属性,主要包括以下几个关键点。它们分别是根据express自身提供的request和response创建的。请求和响应的原型是Node。创建了js的http模块中的http.IncomingMessage.prototype和http.ServerResponse.prototype,并在其上扩展了一些自定义方法。实例上的request和response属性都增加了对实例的额外引用,方便在处理request和responseApplication对象时,同时访问和修改express实例app.init()进行分析。综上所述,本文的重点是分析express实例的构造函数。函数本身的内容不到十行代码,却引出了一个关键知识:express实例是封装的HttpServer对应的监听器。这个知识点在后面的分析中会经常出现。