Please explain the basic server setup code of Express.js - node.js

In this code snippet:
Const express = require('express')
Const app = express();
/*Typeof express = function
Typeof app = function*/
app.get()
My question is: if app is a function then how can we use a dot operator with it to call get function, and if we are creating a object of function express then why didn't we use new keyword to create an object.
Secondly, module.exports exports the literals in object format then why we are getting typeof express here a function.
If I am wrong anywhere, please correct me.

In JavaScript functions are objects, so this is valid:
function x() {
console.log("this is x()");
}
x.y = function() {
console.log("this is x.y()");
}
x();
x.y();
Express and other JavaScript tools use this feature extensively.
If you're used to other languages where functions are just functions and not objects themselves this will seem extraordinarily strange.

Related

What is the second pair of parenthesis in "require('express')()" in node.js?

I'm following the socket.io chat application tutorial here - https://socket.io/get-started/chat/
and it's using express framework. There's a code in the tutorial that is:
var app = require('express')();
var http = require('http').Server(app);
and if I just use 'require('express')' without the second parenthesis it doesn't work. What does the second parenthesis do and where could I find documentation for the syntax?
The type returned from require('express') is a function. The second set of parenthesis is you actually invoking the function to create an instance of an express app.
It's the equivalent of you doing
const express = require('express');
const app = express();
The require('express') call returns a function and hence you need to call that returned function in order to initialisation an express app. For example, the main entry file of express might look like
function one(){/*some code here*/}
function two(){/* some other code here*/ }
Module.exports = one;
So essentially what happens is that when you require express the above code is included and the one function is exported for you to use and hence you need to call that function that's why you have that extra parenthesis

What doesn't nodejs relate 'this' as the object that encapsulates the function?

I wrote the following code in nodejs:
var express = require('express');
var app = express();
app.message = "helloworld";
app.get('/check', function (req,res) {
res.end("GET request OK");
console.log(this.message);
});
app.listen(4000);
When I run the code and send a GET request, the line:
console.log(this.message);
prints "undefined".
However, when I change it to:
console.log(app.message)
I get "helloworld".
I thought that this variable should represent the object that invoked the function. If so, why doesn't this object include the attribute .message ?
this can be whatever the author of the library intends it to be. It could be the app instance or it could be the global object.
In this case, it appears it's the global object.
As a sidenote too, it's not recommended to add expando properties to an existing library like that.

Testing Node Application with mocha

I have the following test application based on a template provided by openshift.
server.js:
var express = require('express');
exports.NodeTestApp = function () {
self.cache_get = function (key) {
return 'Would be a value here';
};
}
server_test.js:
var server = require('../server');
describe('Server', function(){
describe('Startup',function(){
it('sets up routes during startup',function(){
var app = server.NodeTestApp();
app.cache_get('/');
expect(app.routes.size).to.equals(5);
})
})
})
When I run this test I get an error message that cache_get is not defined.
TypeError: Cannot read property 'cache_get' of undefined
at Context.<anonymous> (test/server_test.js:7:16)
I would have thought that everything that is specified in the NodeTestApp function is available via variable app. IntelliJ even shows me the function as a valid call. Any idea why I get this error ?
Thanks in advance.
Oliver
I figured out the problem with above code. To instantiate the app variable the new keyword has to be used. I didn't think that this is required as I would have thought its purely a function call and not a constructor call, which requires the new keyword. Below is the working code for your reference.
var app = new server.NodeTestApp();

Difference between initating an express object in nodejs?

I can use express in two ways, that is I can initialize it in two ways:
var app = express(); or var app = new express();
From the looks of things, both are calling a constructor, so is there really any difference between the two, I'm mainly asking performance wise, is there really any difference, because I seemed to have experienced none.
If there is no real difference how come every tutorial I've seen does it the first way and not the second way, because the second one seems to be clearer.
In this case calling express() as a function is more correct.
https://github.com/visionmedia/express/blob/8a1e865e37016f279d957f04117007c36ac195e3/lib/express.js#L32
function createApplication() {
var app = connect();
utils.merge(app, proto);
app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };
app.init();
return app;
}
This is basically a factory function, not a constructor. Using the new keyword will create an unnecessary object that will immediately be discarded since the createApplication returns an object, the automatic this that the new keyword creates is discarded (this is just how the JavaScript language works).
So the answer is both versions work fine, but using new is unnecessary here.

Extend View class in Express on Node.js

I'd like to override the View class in the Express framework, used in Node.js. I want to augment the lookup method, but I can't see a way to do this without altering the Express and App modules. I'd favour deriving from the Express framework, but I can't figure out a neat way to do this.
Any ideas?
Thanks
It seems to me you should be able to:
var View = require('express/lib/view');
// Keep reference to original lookup method
var _lookup = View.prototype.lookup;
// Override lookup method
View.prototype.lookup = function (path) {
// Your implementation here
};
Update:
Run this as a demonstration:
var View = require('express/lib/view');
var _lookup = View.prototype.lookup;
var express = require('express');
View.prototype.lookup = function (path) {
console.log('LOOKUP!!! ' + path);
return _lookup.call(this, path);
};
var app = express();
app.get('/', function (req, res) {
res.render('foo.jade');
});
app.listen(3000);
Run
node app & sleep 1 && curl localhost:3000
I hope this will demonstrate the viability of this way of overriding a method.
It depends on which version of Express you are using.
You can easily augment the view lookup code only if your app is using Express prior to version 3
Since Express 3.0 that's not doable anymore.
You can check one of my old related answers for sample code:
Multiple View paths on Node.js + Express

Resources