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.
Related
I am trying to learn how to create a facebook Bot.
I found this amazing article on Medium which illustrates how we can create a messenger bot
In this article, The author tells us to create a verification.js. file inside controllers/verification.js. and paste the following code in it.
module.exports = (req, res) => {
const hubChallenge = req.query[‘hub.challenge’];
const hubMode = req.query[‘hub.mode’];
const verifyTokenMatches = (req.query[‘hub.verify_token’] === ‘crowdbotics’);
if (hubMode && verifyTokenMatches) {
res.status(200).send(hubChallenge);
} else {
res.status(403).end();
}
};
Now, before trying to figure out what this code does (which she have explained), I am unable to understand why haven't she included any dependencies (precisely express) in this Node.Js file?
[Update] Can someone also please explain me in length what does the above code do?
Since this code looks like NodeJS code, Shouldn't she add something like
var express = require("express");
var app = express();
and do module.exports after?
To summarise the comments under the question:
You must import modules only if you need it. That chunk of code simply exports a function that can be used in any other module by importing it.
The author's just exporting an anonymous es6 arrow function, which is totally legit. It can be imported as
import * as whateverYouNameIt from 'controllers/verification';
or
let func = require('controllers/verification');
Have a look at arrow functions and node.js module exports
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.
A perhaps pedantic question: I'm enjoying the type checking of IntelliJ and would like to know how to aid it in resolving more complex types.
In my NodeJS project I pass a SocketIO namespace into the constructor of a controller class.
I'd like IntellJ's code analysis tool to know that the SocketIO namespace inherits from EventEmitter (or at least implements its methods).
// In another file (controller.js)
function MyController(namespace){
/** #var ???? **/
this.ns = namespace;
}
MyController.prototype.doSomething = function(){
// ....
this.ns.emit('my-event'); // IntelliJ complains (rightly) that it doesn't know about emit()
}
module.exports = MyController;
// In my main file (index.js)
var Controller = require('./controller);
var http = require('http');
var io = require('socket.io')(http.createServer);
var ns = io.of('/namespace');
var ctrl = new Controller(ns);
ctrl.doSomething();
So is there a syntax for commenting JS variables (perhaps specific to Node) where you can use the module name as a namespace such that static analysis tools like this can resolve them correctly?
Within SocketIO the main class is simply 'Server' which could be easily confused for many other similar Server classes and I've not quite dug deep enough to find the class that's returned in
response to calling io.of(...)
Any help or pointers greatly appreciated!
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.