Function declaration and calls in nodejs files - javascript

I am reading some source files and see that functions have been written and called in two different patterns. I am going to describe the two patterns first and then how they are called in the main file.
First pattern :
File module1.js:
function a(req,res,next){
//do somethin
}
module.exports.a = a;
seconds pattern :
File module2.js
module.exports = function(){
return function(req,res,next){
/* do something here */
}
}
File main.js
var mod1 = require('module1');
var mod2 = require('module2');
server.use(mod1.a);
server.use(mod2());
What confuses me is why mod1 and mod2 have been written so differently. What is the right way of writing these

The second pattern is useful if you need to pass in a configuration object or other information (e.g. a database instance) to the middleware that it will use for requests.
Either way is acceptable, it just depends on your needs.

Related

Node.JS Module/Object that spans several files?

I am working on supporting a REST API that literally has thousands of functions/objects/stats/etc., and placing all those calls into one file does not strike me as very maintainable. What I want to do is have a 'base' file that has the main constructor function, a few utility and very common functions, and then files for each section of API calls.
The Problem: How do you attach functions from other files to the 'base' Object so that referencing the main object allows for access from the subsections you have added to your program??
Let me try and illustrate what I am looking to do:
1) 'base' file has the main constructor:
var IPAddr = "";
var Token = "";
exports.Main = function(opts) {
IPAddr = opts.IPAddr;
Token = opts.Token;
}
2) 'file1' has some subfunctions that I want to define:
Main.prototype.Function1 = function(callback) {
// stuff done here
callback(error, data);
}
Main.prototype.Function2 = function(callback) {
// stuff done here
callback(error,data);
}
3) Program file brings it all together:
var Main = require('main.js');
var Main?!? = require('file1.js');
Main.Function1(function(err,out) {
if(err) {
// error stuff here
}
// main stuff here
}
Is there a way to combine an Object from multiple code files?? A 120,000 line Node.JS file just doesn't seem to be the way to go to me....not to mention it takes too long to load! Thanks :)
SOLUTION: For those who may stumble upon this in the future... I took the source code for Object.assign and back ported it to my v0.12 version of Node and got it working.
I used the code from here: https://github.com/sindresorhus/object-assign/blob/master/index.js and put it in a separate file that I just require('./object-assign.js') without assigning it to a var. Then my code looks something like this:
require('./object-assign.js');
var Main = require('./Main.js');
Object.assign(Main.prototype, require('./file1.js'));
Object.assign(Main.prototype, require('./file2.js'));
And all my functions from the two files show up under the Main() Object...too cool :)
At first each file works in its own scope, so all local variables are not shared.
However, as hacky approach, you may just add Main into global scope available everywhere by writing global.Main = Main right after you define it, please make sure that you require main file first in list of requires.
The better(who said?) approach is to extend prototype of Main later, but in this case you may need to update a lot of code. Just mix-in additional functionality into base class
file1.js
module.exports = {
x: function() {/*****/}
}
index.js
var Main = require('main.js');
Object.assign(Main.prototype, require('file1.js'));
Shure.
constructor.js
module.exports = function(){
//whatever
};
prototype.js
module.exports = {
someMethod(){ return "test";}
};
main.js
const Main = require("./constructor.js");
Object.assign( Main.prototype, require("./prototype.js"));

Node define unique variable that I need to use across the modules

Currently I am just passing my fileNamePrefix like that:
let shortid = require('shortid');
let fileNamePrefix = shortid.generate();
module1.run(fileNamePrefix); //generating a file based on `fileNamePrefix` `xxxxx.f1.json`
module2.run(fileNamePrefix); //generating a file based on `fileNamePrefix` `xxxxx.f2.json`
module3.run(fileNamePrefix); //generating a file based on `fileNamePrefix` `xxxxx.f3.js
Which I think in not quite right, I might need to pass more things to my modules later on, so I want to avoid to pass that as function params.
What is the best way to approach that in nodejs?
Will global object like global.fileNamePrefix = shortid.generate(); will do in that case or would you approach that different? I just read that global is not good...
You can use either singleton approach or approach suggested by #Сергей Тертичный
Singleton :
//shortid.js
var fileSingleTon = module.exports = {
fileNamePrefix: null,
getFileNamePrefix: function() {
return fileSingleTon.fileNamePrefix || fileSingleTon.generate()
},
generate: function() {
console.log('generating..');
return fileSingleTon.fileNamePrefix = 'your_file_prefix';
}
}
//module1.js
var fileNamePrefix = require('./shortid').getFileNamePrefix();
//do stuff for module1
//module2/js
var fileNamePrefix = require('./shortid').getFileNamePrefix();
//do stuff for module1
and so on..
Even now you are calling require('./shortid').getFileNamePrefix(); multiple times, generate function is getting called only once.
Node Caching approach :
Consider you have shortid.js as following :
// A: block of code to do some manipulations
// B : module.exports = manipulation result.
So basically in node js "modules" core module which is responsible for giving us module.export functionality executes whatever is here above export(in abode example the part A) only for the first time and caches it even if you have required in in multiple other files. However, it only executes the functions or block of code in every require which is inside export. So you can use this approach where your A block will have login to generate fileNamePrefix and then B just returns it.
Just create module like that:
// unicname.js
let shortid = require('shortid');
let fileName = shortid.generate();
module.exports = {fname: fileName};
//module1.js
const {fname} = require('./unicname.js');
....
Since the node.js caching the modules the value will be calculated only one time so you can get same value in all your modules.

NodeJS: Single object with all requires, or "standard" paths in code?

So, I'm a big fan of creating global namespaces in javascript. For example, if my app is named Xyz I normally have an object XYZ which I fill with properties and nested objects, for an example:
XYZ.Resources.ErrorMessage // = "An error while making request, please try again"
XYZ.DAL.City // = { getAll: function() { ... }, getById: function(id) { .. } }
XYZ.ViewModels.City // = { .... }
XYZ.Models.City // = { .... }
I sort of picked this up while working on a project with Knockout, and I really like it because there are no wild references to some objects declare in god-knows-where. Everything is in one place.
Now. This is ok for front-end, however, I'm currently developing a basic skeleton for a project which will start in a month, and it uses Node.
What I wanted was, instead of all the requires in .js files, I'd have a single object ('XYZ') which would hold all requires in one place. For example:
Instead of:
// route.js file
var cityModel = require('./models/city');
var cityService = require('./services/city');
app.get('/city', function() { ...........});
I would make an object:
XYZ.Models.City = require('./models/city');
XYZ.DAL.City = require('./services/city');
And use it like:
// route.js file
var cityModel = XYZ.Models.City;
var cityService = XYZ.DAL.City;
app.get('/city', function() { ...........});
I don't really have in-depth knowledge but all of the requires get cached and are served, if cached, from memory so re-requiring in multiple files isn't a problem.
Is this an ok workflow, or should I just stick to the standard procedure of referencing dependencies?
edit: I forgot to say, would this sort-of-factory pattern block the main thread, or delay the starting of the server? I just need to know what are the downsides... I don't mind the requires in code, but I just renamed a single folder and had to go through five files to change the paths... Which is really inconvenient.
I think that's a bad idea, because you are going to serve a ton of modules every single time, and you may not need them always. Your namespaced object will get quite monstrous. require will check the module cache first, so I'd use standard requires for each request / script that you need on the server.

Select which files to 'require' at run-time - node.js

I have a parser for a language I'm implementing and I would like to allow the user to issue a request to use outside implementations of their own functions in a .js file they create. So, for example:
functions.js
var functions = {
var func1 = function(){/*...*/}
}
module.exports = functions;
toparse.mylanguage
#bind "functions.js"
x = func1();
And in my node.js server I would use var functions = require('./functions') and have the parser direct the execution to the relevant function. I assume that they upload the .js file to the same folder they uploade the .mylanguage file.
What would be a good way to do this?
EDIT: to clarify, I don't know the name of the .js file before #bind is used, so I can't require it specifically beforehand.

NodeJS - How to reference function in one require() file from another require() file?

This is my second weekend playing with Node, so this is a bit newbie.
I have a js file full of common utilities that provide stuff that JavaScript doesn't. Severely clipped, it looks like this:
module.exports = {
Round: function(num, dec) {
return Math.round(num * Math.pow(10,dec)) / Math.pow(10,dec);
}
};
Many other custom code modules - also included via require() statements - need to call the utility functions. They make calls like this:
module.exports = {
Init: function(pie) {
// does lots of other stuff, but now needs to round a number
// using the custom rounding fn provided in the common util code
console.log(util.Round(pie, 2)); // ReferenceError: util is not defined
}
};
The node.js file that is actually run is very simple (well, for this example). It just require()'s in the code and kicks off the custom code's Init() fn, like this:
var util = require("./utilities.js");
var customCode = require("./programCode.js");
customCode.Init(Math.PI);
Well, this doesn't work, I get a "ReferenceError: util is not defined" coming from the customCode. I know everything in each required file is "private" and this is why the error is occuring, but I also know that the variable holding the utility code object has GOT to be stored somewhere, perhaps hanging off of global?
I searched through global but didn't see any reference to utils in there. I was thinking of using something like global.utils.Round in the custom code.
So the question is, given that the utility code could be referred to as anything really (var u, util, or utility), how in heck can I organize this so that other code modules can see these utilities?
There are at least two ways to solve this:
If you need something from another module in a file, just require it. That's the easy one.
Provide something which actually builds the module for you. I will explain this in a second.
However, your current approach won't work as the node.js module system doesn't provide globals as you might expect them from other languages. Except for the things exported with module.exports you get nothing from the required module, and the required module doesn't know anything of the requiree's environment.
Just require it
To avoid the gap mentioned above, you need to require the other module beforehand:
// -- file: ./programCode.js
var util = require(...);
module.exports = {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
};
requires are cached, so don't think too much about performance at this point.
Keep it flexible
In this case you don't directly export the contents of your module. Instead, you provide a constructor that will create the actual content. This enables you to give some additional arguments, for example another version of your utility library:
// -- file: ./programCode.js
module.exports = {
create: function(util){
return {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
}
}
};
// --- other file
var util = require(...);
var myModule = require('./module').create(util);
As you can see this will create a new object when you call create. As such it will consume more memory as the first approach. Thus I recommend you to just require() things.

Categories