Reputation: 3
Below is the simple syntax to use any Node.js module
let os = require('os');
console.log("This is the user info - " , os.userInfo());
Now here , we saw that to use the already existing function of os
module we just had to use simple dot notation. And we got it by writing os.userInfo()
.
However , in case of using Express.js , below is the procedure :-
let express = require('express'); //
let app = express(); // Line 1
app.listen(\\Write_Code);
I want to know that why do we have to write let app = express();
in case we are using Express.js
Afterall , we are importing express module also. So we should be able to use it's function like
express.app.listen()
or maybe like express.listen()
. I know app
is a variable present in Express module , but I am not able to understand Why do we have to write let app = express();
.
Can anyone please let me know like what is happening when we write let app = express();
Upvotes: 0
Views: 102
Reputation: 3677
You're comparing two different things, when you require os
, it gives you a bunch of functions which is accessible within a single instance object, to simplify this, imagine it would be like this:
// os module
exports.userInfo = () {};
exports.cpus = () {};
...
whenever you require or import this module, it gives you this kind of object:
{
userInfo() {},
cpus() {},
...
}
but in the case of express, the structure is a bit different. Whenever you require it, it gives you a default function
and some other methods. By invoking the default function, it gives you an object in which you can create your own server, use middleware, etc. and it is accessible under the app
method. However, it also gives you some functions which are not under the app
, like json
, static
, etc. so this means they can be invokable without invoking default functions(i.e. express.json
).
This is similar to the OOP principle, in the case of a class you may have defined some methods and some static methods. The static methods are accessible without having to create an instance of the class(e.g. json
, static
). But the class has some other methods which we have to create an instance of the class to access them(e.g. use
, listen
).
In code, it would be like this:
// express
exports = module.exports = () => {}; // this is necessary for defining default function.
exports.json = () => {};
exports.static = () => {};
...
And when you require it, it gives you this:
[Function: () => {}] { json() {}, static() {} }
Although the current implementation of Express is not actually a class, however, in my opinion, it can be replaced with a class. The current approach is called factory function. There are some differences between the constructor function and the factory function. You may need to read more about it.(Constructor function vs Factory functions and It is particularly difficult to put asynchronous operations in a constructor.)
Upvotes: 0
Reputation: 16666
express
is a "class"1, and you can create many instances of it by calling express()
repeatedly. An instance of express
is also called an app
. And the .listen
method exists on the instance, that is, on the app
, because different instances (different app
s) can listen differently, say, on different ports.
By contrast, express.static
is a middleware that exists only once and is therefore a static property of the express
object. This middleware does not differ from app
to app
.
os.userInfo
is similarly static, because you as a user cannot observe multiple instances of an operating system at a time.
1 I put "class" in quotes after reading the comments. What remains true is that you can have several instances created by it.
Upvotes: 0
Reputation: 31
It creates an instance of the Express application. This instance is an Express function or class and is the main export of the Express
module.
The app variable created in let app = express()
is an Express
instance. It has methods for handling various HTTP requests (e.g. app.get(), app.post()), as well as settings and middleware.
By creating an instance of the Express application, you can add routes and middleware outside the functions by passing the app
variable as parameters.
You could also use one-liner
method to create Express server if you don't need any fancy custom or dynamic loading middleware for your Express.
Express()
.use(Express.json())
.all('*', (req, res) => {
res.send('Hello World')
})
.listen(8080)
Upvotes: 1
Reputation: 18249
I'm not personally familiar with the Express source code, but a quick peek on Github quickly reveals what's going on, in case it isn't obvious from the code you have to write.
What's exported as express
from that module is actually internally called createApplication
:
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;
}
and while I can't explain all the details of what that function does (because I don't know them either), it's pretty clear that this is a function that takes no arguments and returns an object representing your application. Hence why it's conventially called app
in consuming code.
As for why it works this way rather than the way you seem to want - that's a question for those who originally made Express. I don't see why it technically couldn't me made to work that way - by having that code that's currently inside createApplication
run at the top level of the module and then just have the app
object be exported. The obvious difference, and advantage for the actual approach, is that you can "instantiate" several apps at once, by doing this in your consuming code:
let express = require('express');
let app1 = express();
let app2 = express();
and then doing things with app1
and app2
which will be completely independent of each other. As to whether this is actually useful for anyone, I don't know - but it seems a very small price to pay in terms of a tiny amount of one-time extra code, in order to get this flexibility where needed.
Upvotes: 0