Multiple require() from the same library in the same module - node.js

I'm looking at the sources of the #slack/client npm package for NodeJs and see that right at the top they have this:
var forEach = require('lodash').forEach;
var bind = require('lodash').bind;
var has = require('lodash').has;
var isArray = require('lodash').isArray;
var isEmpty = require('lodash').isEmpty;
var isObject = require('lodash').isObject;
What's the point in cherry picking all this from the lodash module when you can make it more succinct by only including the whole lib once and then using the methods you need?
// Include the whole lib
var _ = require('lodash');
// And later
if (_.isObject(...)) // etc
It's not like they are using each method many times. In fact, most are used just once or twice. Also, it is my understanding that even when partially requiring part of a module, the whole thing is eval()'d, so there is no advantage memory or performance-wise.
I find this package to be very well written so I'm curious to know why they chose to do this.

Related

Node modules as constructor function

I'm working on my first NodeJS project. I started building modules in the classical way as I read on books and over the internet.
As the project started growing I decided to split modules in small reusable pieces. That lead me to have a lot of require at the top of the file and sometime the risk to tackle circular dependencies. Moreover, this approach, doesn't really fits with testing because I had to require all the dependencies to make tests. I asked other developers a better way to solve this problem and most of them suggested me to use dependency injection with function constructor.
Suppose I have ModuleA and ModuleB,
ModuleC requires both ModuleA and ModuleB. Instead of requiring these modules an the top of the page I should pass them as argument in a constructor function.
e.g.
module.exports = function ModuleC(moduleA, moduleB) {
//module implementation here....
function doSomething() {}
return {
doSomething
}
}
the problem with this approach, that at first looked good, is that in the main entry point of the application I have to require and instantiate all the module to pass.
const ModuleA = require("./moduleA");
const ModuleB = require("./moduleB");
const ModuleC = require("./moduleC");
const moduleA = new ModuleA();
const moduleB = new ModuleB();
const moduleC = new ModuleC(moduleA, moduleB);
moduleC.doSomething();
Now with only 3 modules I had to write 7 line of code to use a function of a module. If I had 20 modules to work with the main entry point of the application would be a nightmare.
I guess this is not the best approach and even with this method, testing is not easy.
So, I ask you to suggest/explain me the best way to achieve this simple task that I'm finding, maybe harder than it is, while starting exploring the NodeJS word. Thanks.
Code re-usability can also be achieved if you put all of your codes in a single file. Creating smaller modules is not the only solution. consider the following codes written in a file allLogic.js(let).
var allFunctions = function(){ };
var allFunctionsProto = allFunctions.prototype;
allFunctionsProto.getJSONFile = function(fileName){
var that = this; //use 'that' instead of 'this'
//code to fetch json file
};
allFunctionsProto.calculateInterest = function(price){
var that = this; //use 'that' instead of 'this'
//code to calculate interest
};
allFunctionsProto.sendResponse = function(data){
var that = this; //use 'that' instead of 'this'
//code to send response
};
//similary write all of your functions here using "allFunctionsProto.<yourFunctionName>"
module.exports = new allFunctions();
Whenever I need to get any JSON file I know that the logic to get JSON file has already been written in allLogic.js file, hence I will require this module and use that as below.
var allLogic = require('../path-to-allLogic/allLogic.js');
allLogic.getJSON();
this approach is far better than creating tons of module for each work. Of course if the module gets longer you can create new module but in that case you need to consider separation of concern otherwise the circular dependency will haunt you.
As you are using you moduleA and moduleB in moduleC, if you put all of the codes from moduleA, moduleB and moduleC in a single module as I have pointed out you can reference the functions and all of the separate functions inside that module using that and those are also available after require.

Node.js + testing: DI vs hard dependencies

I'm working on some repo. And add refactoring to extract some functionality into class
The question is -- I prefer to use passing dependencies from outside (DI). But I see that it's not common pattern for node.js application.
So the question - is there any good examples ( links to repos ) where guys use DI for providing dependencies.
The opposite opinion is -- "We always can use proxyquire module to mock dependencies"
P.S
example for code I propose is
// use
const inst = new Cls(getDep1(), getDep2());
// where getDep1 / getDep2 provide dependencies from side modules
instead of
//Cls
const dep1 = require('dep1');
const dep2 = require('dep2');
module.exports = function Cls() {
// deps usage
}
// and
const inst = new Cls();
The question is about arguments in node.js related projects
Your example is about as clear as it gets. If you want to configure a stub/mock in a test for a class dependency without using proxyquire or mockery or some other require patcher, then you have to provide another point of entry into your code.
you could explicitly use DI like in your example:
function Cls(dep1, dep2) {
this.dep1 = dep1;
this.dep2 = dep2;
}
Which could live off by itself, then your calling code would be responsible for importing your class, configuring its dependencies, and instantiating it correctly. That way your Cls is isolated and unit testable itself.
You could also expose the dependencies that need to be handled as public properties:
const dep1 = require('dep1');
const dep2 = require('dep2');
module.exports = function Cls() {
this.dep1 = dep1;
this.dep2 = dep2;
}
That could allow the module that Cls is defined in to also contain the code that associates it with its deps, while still allowing your unit tests to easily configure Cls with mock/stub objects. This relies on requires to be side effect free :(
var cls = new Cls();
cls.dep1 = new SomeStub();
cls.dep2 = new SomeStub();
cls.exercise();

Best practice on avoid duplicated requires in nodejs

I have multiple js files, all have the same requires in the beginning like
var config = require("config");
var expect = require("chai").expect;
var commonAssertions = require('../../../utils/common_assertions.js');
var commonSteps = require('../../../utils/common_steps.js');
I am thinking about putting all of them in one file and just require this single file.
I am wondering if there is any best practice or convention on this in nodejs.
Remember that require() must always return a Javascript object, module.exports.
So if you were to extract this to a different file, that would be perfectly fine.
includes.js
exports.config = require("config");
exports.chai = require("chai").expect;
exports.commonAssertions = require('../../../utils/common_assertions.js');
exports.commonSteps = require('../../../utils/common_steps.js');
myfile.js
includes = require('./includes')
includes.expect(true).to.be.true //For example
It is not necessarily a good or bad practice. I would say that if you expect to need the exact same modules from many different files, then go for it.

Require a file in NodeJS using a canonical or root-relative path

I have a fictional utilities package (node module) that I'm importing into my apps like so:
var sqrt = require('common-math').sqrt
However, using this same module from within the common-math module seems to be tricky. I seem to only have to options, both of which are not ideal:
Use relative path require from every single place I need to get access to the module. This can be require('../sqrt') or require('../../../lib/sqrt').
Put the module in node_modules/sqrt/index.js and then do a require('sqrt').
I just want to be able to require('common-math').sqrt just like all the consumers of this package do. I realize that I can create a node_modules/common-math folder with a symlink to my package's index.js, but is this a common/recommended practice?
Node's module loading system is very limited, but what you want is possible. However it is not as elegant as you might expect it to be:
var root = (function (p, path) {
for (; 'common-math' !== path.basename(p); p = path.dirname(p));
return p;
}(module.filename, require('path'));
var a = require(root + '/sqrt.js');
or even:
var root = (function (p) {
return p.slice(0, p.indexOf('common-math') + 1).join('/');
}(module.filename.split('/')));
var a = require(root + '/sqrt.js');

How to Use one module feature within another module in nodejs require()

I want to use one module feature within another module
file main.js
var _ = require("./underscore.js");
var foo = require("./bar.js");
foo.publish(...);
file bar.js
(function(e) {
var array = [...];
e.publish = function(t, args) {
_.each(array, function(...) {...});
});
})(exports);
I've tried a couple of variations, but I am not sure of the best way around this error:
ReferenceError: _ is not defined
Yes, you should use in every module which needs that variable, for the case of you example.
var _ = require("./underscore.js");
But if you need to transfer one object instance between several modules you can use process object to make it global. But that is BAD practice.
process._ = require("./underscore.js");
Good way to pass object instances between the modules is to pass them as function arguments, but you need to change you bar.js to return a factory function, not an object itself.
module.exports = function(_) {
var e = {};
var array = [...];
e.publish = function(t, args) {
_.each(array, function(...) {...});
});
return e;
}
In main.js:
var _ = require("./underscore.js");
var foo = require("./bar.js")(_);
foo.publish(...);
I hope you got the point.
The variable to which you assign the result is local to the module main.js, so you can't access it in bar.js. Instead, you should require the underscore module in bar.js as well.
You could also skip the var when declaring _ and make it a global variable, but that brings all the problems of global variables, like:
the bar.js module is not explicit about its dependencies, so it's harder to understand that it expects underscore to be required globally;
it requires a specific initialization order - if you later move the _ = require(underscore), you'll get undefined errors again, and it might be hard to understand why;
every other module that requires bar.js needs to also require underscore.

Resources