In a simple javascript file, we can use express by adding these two lines of code at the beginning (after installing it through npm):
var foo = require('express');
var app = foo();
Now, according to the express API guide:
The app object conventionally denotes the Express application. Create it by calling the top-level express() function exported by the Express module
Since the app object is calling the top-level express() function, how come am I not able to just simply use:
var app = foo.express();
The first line assigns whatever the module 'express' exports to a variable named express. Different modules will export different things (objects, functions). Express exports a function.
The line:
var app = express()
executes the function. This function generates the express application object. This object has all the methods that you use to handle requests in your standard express apps.
The require function that was passed 'express' returns module.exports, which holds the top level function express(), something similar to:
module.exports = express(){...}
That is why we still need to call it either through:
var foo = require('express');
var app = foo();
or
var app = require('express')();
You cannot use:
var foo = require('express');
var app = foo.express();
because it was not set up that way, you could use it if the express module looked something like this:
module.exports.express = express(){...}
I don't know the reason as to why you would choose one over the other, I only know that the second technique simply exposes your function directly.
Related
I recently started learning Node/express. One doubt is bugging me for a couple of weeks now. I know what this does, and I've been able to get past it. But I cannot wrap my head around the logic used in the line const a = express().
express = require('express');
const a = express()
I don't think I have seen this before in javascript. In this case, express is an object or function (functions are also object in JavaScript) right? And this line is what gives the variable a access to lots of important methods like listen() and get(). But doesn't the syntax here is wrong? To use the express() function, we need to write like
const express = require('express');
const a = express.express()
or we need to use object destructuring to write like
const {express} = require('express');
const a = express()
Perhaps the confusion is in assuming that the default export of the express module is something other than a function, but as others have pointed out, the default export of express is a function. Once imported, the returned value of that function is an instance of Express which is where you then have access to all those methods you mentioned.
Imagine that the definition of function express and the object it returns looks something like
class Express {
// Implementation of Express server
}
// You're importing this and calling the function, receiving a new instance of this class. In reality this could be a class or object for all I know.
export default function express() {
return new Express()
}
Going through the socket.io's get-started, and I come across a module requirement I can't find clear an explanation of:
var app = require('express')();
var http = require('http').Server(app);
the author describes these lines:
Express initializes app to be a function handler that you can supply to an HTTP server (as seen in line 2)
I haven't found explanations for this usage in any of the documentations for require that I have read. So, what is happening here? Socket.io is irrelevant to my question. It's only referenced to provide a bit of context. Not sure if this is a simple or complex question...
When you require('express'), you are importing something. That something is whatever the Express framework chooses to export. If you look at index.js here, we have the following:
module.exports = require('./lib/express');
Which you can see it just imports from a sub directory of the project. But you can see it specifically imports express.js. By default (shown here), it exports a function called createApplication:
exports = module.exports = createApplication;
/**
* Create an express application.
*
* #return {Function}
* #api public
*/
function createApplication() {
// ...
}
So when you require('express') it will resolve to function createApplication() which is just a function. Which is why you have the extra (), it's just executing/calling the returned function.
See Higher-order function.
Let's say I have an application as following:
server.js (main) is requiring different external node packages, like underscore.js.
var Underscore = require("underscore");
server.js is also requiring some modules defined in my application it-self; For example it could requires a Router module, to handle Express routes.
var Router = require("./sources/router.js");
I have then my router.js file as following :
var Router;
Router = (function() {
function Router(app, oauth) {
app.get('/', function(request, response) {
// ...
});
}
return Router;
})();
module.exports = Router;
Questions:
If I want to use underscore inside my Router module, should I re-require again ? Should I do that for every modules ? What is the impact?
I would end up with something like:
var Router;
Router = (function() {
Router.prototype.underscore = require("underscore");
function Router(app, oauth) {
app.get('/', function(request, response) {
// this.underscore. ...
// using underscore ...
});
}
return Router;
})();
module.exports = Router;
and
var Underscore = require("underscore");
var Router = require("./sources/router.js");
router = new Router();
I could obviously also inject as a parameter it when initializing Router, but this doesn't look to me like a viable option in an application where I may end up using dozens of packages, especially for very general purpose package like this one.
var underscore = require("underscore");
var Router = require("./sources/router.js");
var router = new Router(underscore);
Alternatively I could set the underscore var as a global one, but I don't really like this option.
Is there any other options ?
What is the impact of systematically importing packages in every modules - in term of execution time, memory ?
I would like to understand the behavior of the node engine in such cases.
Yes, you should just require it again. Node caches required modules, so the second time you require something it doesn't actually run that file; it just returns the cached object. So the memory impact is basically 0 (an extra pointer to the same object, more or less) and the execution time is similarly negligible (the cost of a lookup in an object by the module name).
This means that the objects returned by the two requires aren't just identical; they're literally the same object. Any change to one will affect the other. Because of this, you can extend the module in one place and get those extensions everywhere.
my routes are defined in an external folder
./routes
here's the way i define the routes in my server.js file
app.get('/', routes.index);
app.post('/validation', register.valid);
the register.valid module, which is originally written in
./routes/validation.js
is responsible for creating a new user account and register it into a database (MongoDB).
How can i access an object from server.js in validation.js ? First, i thought declaring the object before defining my routes would resolve the case, but actually it doesn't seem to be the solution.
I'm assuming your current code already does work (that is, you receive the posted data), but you need access to another object from validation.js.
If your code works, then you probably have this line in server.js:
var register = require('./routes/validation');
And you need acess to the variable obj in the validation module. You could have a function inside the validation module:
var foo;
exports.configure = function(obj) {
foo = obj;
}
The exports mean the variable configure will be accessible to modules which "require" the validation module. This way you can do, inside the server.js module:
register.configure(obj);
app.post('/validation', register.valid);
The exact configuration of this will depend on what you are actually trying to accomplish. Sometimes, for example, it's good to have a database object stored in a global variable.
Generally in this kind of structure server.js will create the app object and then pass that to individual routes modules via a function. I do it by having each router module export a single function like this:
//routes/validation.js
function setup(app) {
app.get(....blah
app.post(....blah
}
module.exports = setup;
Then I tie that together in server.js like this:
//server.js
var express = require('express');
var app = express();
require('./routes/validation')(app);
See also my express_code_structure sample project for other code organization tips.
I have an Express.js Node web app. Inside my app.js, I generate a string during app initialization:
// app.js
var mongourl = /* based on process.env.VCAP_SERVICES constant */;
Now, I have a script that I load into app.js via require():
// app.js
var db = require('./db');
This script needs to use the mongourl variable defined in my app.js. What would be a good approach to perform this. I have found that I can just set the string as a process.env value, e.g.
// app.js
process.env.mongourl = /* creating the string */;
which then can be accessed in db.js via process.evn.mongourl but I'm not sure if this is a good pattern.
// in db.js you could require an app config.js file
var config = require('config');
// then access via config.db.url
// or you can pass stuff to modules
var db = require('./db')(mongourl);
// or in app.js use app.set()
app.set('mongourl', mongourl);
// then wherever you need it: app.get('mongourl')
I'm not sure if this is a good pattern
It isn't, you just pollute the global object that doesn't belong to you. Consider using a namespace, at least.
A more idiomatic approach would be to create a constructor function for the db connection which takes the string.
It doesn't have to be an actual constructor you could just add
var dburl;
exports.init = function(param) {
dburl = param:
}
Environmental variables aren't meant for that really as they are global and can be seen (and collide with) other modules. Setting it explicitly means it's local and you have much more explicit control of how it's defined if you need it async.