如何在expressjs中重载app.listen的function

我一直在试图创build(基本上)一个工厂函数,为我所拥有的十几个小型专用服务器configuration和构build一个expressjs服务器。 对于这部分我想扩大听function。

我想知道这个最好的方法。 我也在这里寻找一个可重用的deviseselect。

服务器正常创build:

var httpServer = express(); ... 

由于快递的devise方式(不知道我是否正确),我无法访问{whatever} .prototype.listen。 所以我提出了两种方法。

在当前范围中使用附加variables:

  var oldListen = httpServer.listen; httpServer.listen = function(callback){ ... oldListen.call(httpServer, options.port, options.host, function(){ ... if ( typeof callback == 'function' ) callback(); }); }; 

哪个工作,是相当直接的,但我有一个variables提升疣。 我也有一个封闭的解决scheme,但我认为它可能太钝了,是实际的:

 httpServer.listen = (function(superListen){ return function(callback){ ... superListen.call(httpServer, options.port, options.host, function(){ ... if ( typeof callback == 'function' ) callback(); }); }; })(httpServer.listen); 

这两个例子都是工厂环境的一部分,我故意减less传递给函数的参数。

任何帮助,将不胜感激。

如果你坚持“超载”,确保你实现原来的足迹(这是超载的性质)。 Express listen只是节点内部http监听方法的一个别名:

 server.listen(port, [host], [backlog], [callback]); 

更新: Express甚至build议使用节点的服务器API来定制实现: http : //expressjs.com/4x/api.html#app.listen

否则,你应该创build自己的自定义listen方法,这将被定义为:

 httpServer.myCustomListen = function (callback) { httpServer.listen.call(httpServer, options.port, options.host, callback); } 

第二个select是你最好的select,但为了它的工作,你必须扩展快速库。 Express是开源的,并在Github上托pipe。 把它叉起来,随意修改。 定期引入新的更新,以便与核心库保持同步。 我总是用节点模块来做这个事情。

这样做有两个好处:

  1. 您可以完全控制自定义代码,但是您可以随时了解原作者编写的代码。

  2. 如果您发现错误或构build了一个很酷的function,您可以提交拉取请求,以使整个社区受益。

您将首先分叉存储库,然后获取的URL,克隆它,然后添加对原始“上游”回购的引用:

 git clone [url_to your_fork] cd express git remote add upstream git@github.com:strongloop/express.git 

然后你可以把更改推到你自己的回购( git push )。 如果你想从原始的回购获得更新,你可以从上游回购git pull upstream mastergit pull upstream master

如果你想添加一个项目的npm模块,你可以使用下面的代码:

 npm install git://github.com/[your_user_name]/express.git --save 

正如Victor的回答指出的那样,express的原型在express/lib/application.js 。 该文件用于构buildexpress,并通过express/lib/express.jsapplication名称空间导出。 因此, .listen函数可以使用express.appliction.listen来引用。

可以使用这个方法:(类似于Victor的方法)

 var express = require('express'); express.application._listen = express.application.listen; express.application.listen = function(callback) { return this._listen(options.port, options.host, callback); }; 

也可以使用Lo-dash的_.wrap函数,如果你不想将自己的基本函数存储在一个variables中。 它看起来像这样:

 var express = require('express'); var _ = require('lodash'); express.application.listen = _.wrap(express.application.listen, function(listenFn) { return listenFn(options.port, options.host, callback); // Called with the same this }; 

但是,使用这些方法会遇到你在你的问题中提到的问题(variables提升,创build一个额外的variables)。 为了解决这个问题,我通常会创build自己的express.application子类,并replace该子类中的.listen函数,并告诉express使用该子类。 但是,由于express的当前结构,你不能用express()函数本身来replace你自己的子类中的express.application

因此,我要做的就是完全接pipeexpress.application.listen因为它只有两行。 这相当简单!

 var express = require('express'); var http = require('http'); express.application.listen = function(callback) { return http.createServer(this).listen(options.port, options.host, callback); }; 

你甚至可以做一个https选项!

 var express = require('express'); var http = require('http'); var https = require('https'); express.application.listen = function(callback) { return (options.https ? http.createServer(this) : https.createServer({ ... }, this)) .listen(options.port, options.host, callback); }; 

注:其他答案之一提到分叉和修改它。 对于这样一个小function,我会有一段艰难的时间。

您应该可以轻松地重载快速监听function。 您可以在以下对象path中访问它: express.application.listen

所以,你可以实现这样的东西:

 var express = require('express'); express.application.baseListen = express.application.listen; express.application.listen = function(port) { console.log('Port is: ' + port); this.baseListen(port); }; 

listen函数的实现位于express模块​​文件夹下的以下path中: node_modules\express\lib\application.js

绑定并监听给定主机和端口上的连接。 此方法与节点的http.Server#listen()相同。

 var express = require('express'); var app = express(); app.listen(3000); 

express()返回的应用程序实际上是一个JavaScript函数,它被devise成作为callback函数传递给节点的HTTP服务器来处理请求。 这使您可以轻松地为应用程序的HTTP和HTTPS版本提供相同的代码库,因为应用程序不会从这些代码inheritance(这只是一个callback):

 var express = require('express'); var https = require('https'); var http = require('http'); var app = express(); http.createServer(app).listen(80); https.createServer(options, app).listen(443); 

app.listen()方法是以下方便的方法(如果您希望使用HTTPS或同时使用HTTPS,请使用上述技巧):

 app.listen = function(){ var server = http.createServer(this); return server.listen.apply(server, arguments); }; 

参考 : http : //expressjs.com/api.html

希望这可以帮助。