Node.js convention for naming - node.js

With regard to Node.js, is there a convention for naming arguments for a function that serves as a constructor.
For example, we might have:
var classVar1;
var classVar2;
exports.init = function init(classVar1_in, classVar2_in){
classVar1 = classVar1_in;
classVar2 = classVar2_in;
return {
//something
}
}
I am looking for something better than the above :) I am using ESLint, but I don't see anything there to enforce a convention like this (as it's not really possible to do this in JS without using even more conventions).

This is a good convention I've often seen, including in Node programs:
http://www.j-io.org/Javascript-Naming_Conventions/
A constructor function starting with new should always start with a
capital letter
// bad example
var test = new application();
// good example
var test = new Application();
Here is a more complete example, including constructor (1st letter upper-case) and arguments (1st letter lower-case, like all variables):
Essential Node.js: patterns and snippets
// Constructor
var Class = function(value1, value2) {
this.value1 = value1;
}
...
// properties and methods
Class.prototype = {
value1: "default_value",
method: function(argument) {
this.value2 = argument + 100;
}
};
...
// node.js module export
module.exports = Class;
...
// constructor call
var object = new Class("Hello", "2");

Related

Why does node.js don't find the function if the files requires each other [duplicate]

I've been working with nodejs lately and still getting to grips with the module system, so apologies if this is an obvious question. I want code roughly like the below:
a.js (the main file run with node)
var ClassB = require("./b");
var ClassA = function() {
this.thing = new ClassB();
this.property = 5;
}
var a = new ClassA();
module.exports = a;
b.js
var a = require("./a");
var ClassB = function() {
}
ClassB.prototype.doSomethingLater() {
util.log(a.property);
}
module.exports = ClassB;
My problem seems to be that I can't access the instance of ClassA from within an instance of ClassB.
Is there any correct / better way to structure modules to achieve what I want?
Is there a better way to share variables across modules?
Try to set properties on module.exports, instead of replacing it completely. E.g., module.exports.instance = new ClassA() in a.js, module.exports.ClassB = ClassB in b.js. When you make circular module dependencies, the requiring module will get a reference to an incomplete module.exports from the required module, which you can add other properties latter on, but when you set the entire module.exports, you actually create a new object which the requiring module has no way to access.
While node.js does allow circular require dependencies, as you've found it can be pretty messy and you're probably better off restructuring your code to not need it. Maybe create a third class that uses the other two to accomplish what you need.
[EDIT] it's not 2015 and most libraries (i.e. express) have made updates with better patterns so circular dependencies are no longer necessary. I recommend simply not using them.
I know I'm digging up an old answer here...
The issue here is that module.exports is defined after you require ClassB.
(which JohnnyHK's link shows)
Circular dependencies work great in Node, they're just defined synchronously.
When used properly, they actually solve a lot of common node issues (like accessing express.js app from other files)
Just make sure your necessary exports are defined before you require a file with a circular dependency.
This will break:
var ClassA = function(){};
var ClassB = require('classB'); //will require ClassA, which has no exports yet
module.exports = ClassA;
This will work:
var ClassA = module.exports = function(){};
var ClassB = require('classB');
I use this pattern all the time for accessing the express.js app in other files:
var express = require('express');
var app = module.exports = express();
// load in other dependencies, which can now require this file and use app
Sometimes it is really artificial to introduce a third class (as JohnnyHK advises), so in addition to Ianzz:
If you do want to replace the module.exports, for example if you're creating a class (like the b.js file in the above example), this is possible as well, just make sure that in the file that is starting the circular require, the 'module.exports = ...' statement happens before the require statement.
a.js (the main file run with node)
var ClassB = require("./b");
var ClassA = function() {
this.thing = new ClassB();
this.property = 5;
}
var a = new ClassA();
module.exports = a;
b.js
var ClassB = function() {
}
ClassB.prototype.doSomethingLater() {
util.log(a.property);
}
module.exports = ClassB;
var a = require("./a"); // <------ this is the only necessary change
The solution is to 'forward declare' your exports object before requiring any other controller. So if you structure all your modules like this and you won't run into any issues like that:
// Module exports forward declaration:
module.exports = {
};
// Controllers:
var other_module = require('./other_module');
// Functions:
var foo = function () {
};
// Module exports injects:
module.exports.foo = foo;
What about lazy requiring only when you need to? So your b.js looks as follows
var ClassB = function() {
}
ClassB.prototype.doSomethingLater() {
var a = require("./a"); //a.js has finished by now
util.log(a.property);
}
module.exports = ClassB;
Of course it is good practice to put all require statements on top of the file. But there are occasions, where I forgive myself for picking something out of an otherwise unrelated module. Call it a hack, but sometimes this is better than introducing a further dependency, or adding an extra module or adding new structures (EventEmitter, etc)
You can solve this easily: just export your data before you require anything else in modules where you use module.exports:
classA.js
class ClassA {
constructor(){
ClassB.someMethod();
ClassB.anotherMethod();
};
static someMethod () {
console.log( 'Class A Doing someMethod' );
};
static anotherMethod () {
console.log( 'Class A Doing anotherMethod' );
};
};
module.exports = ClassA;
var ClassB = require( "./classB.js" );
let classX = new ClassA();
classB.js
class ClassB {
constructor(){
ClassA.someMethod();
ClassA.anotherMethod();
};
static someMethod () {
console.log( 'Class B Doing someMethod' );
};
static anotherMethod () {
console.log( 'Class A Doing anotherMethod' );
};
};
module.exports = ClassB;
var ClassA = require( "./classA.js" );
let classX = new ClassB();
A solution which require minimal change is extending module.exports instead of overriding it.
a.js - app entry point and module which use method do from b.js*
_ = require('underscore'); //underscore provides extend() for shallow extend
b = require('./b'); //module `a` uses module `b`
_.extend(module.exports, {
do: function () {
console.log('doing a');
}
});
b.do();//call `b.do()` which in turn will circularly call `a.do()`
b.js - module which use method do from a.js
_ = require('underscore');
a = require('./a');
_.extend(module.exports, {
do: function(){
console.log('doing b');
a.do();//Call `b.do()` from `a.do()` when `a` just initalized
}
})
It will work and produce:
doing b
doing a
While this code will not work:
a.js
b = require('./b');
module.exports = {
do: function () {
console.log('doing a');
}
};
b.do();
b.js
a = require('./a');
module.exports = {
do: function () {
console.log('doing b');
}
};
a.do();
Output:
node a.js
b.js:7
a.do();
^
TypeError: a.do is not a function
The important thing is not to re-assign the module.exports object that you have been given, because that object may have already been given to other modules in the cycle! Just assign properties inside module.exports and other modules will see them appear.
So a simple solution is:
module.exports.firstMember = ___;
module.exports.secondMember = ___;
The only real downside is the need to repeat module.exports. many times.
Similar to lanzz and setec's answers, I have been using the following pattern, which feels more declarative:
module.exports = Object.assign(module.exports, {
firstMember: ___,
secondMember: ___,
});
The Object.assign() copies the members into the exports object that has already been given to other modules.
The = assignment is logically redundant, since it is just setting module.exports to itself, but I am using it because it helps my IDE (WebStorm) to recognise that firstMember is a property of this module, so "Go To -> Declaration" (Cmd-B) and other tooling will work from other files.
This pattern is not very pretty, so I only use it when a cyclic dependency issue needs to be resolved.
It is fairly well suited to the reveal pattern, because you can easily add and remove exports from the object, especially when using ES6's property shorthand.
Object.assign(module.exports, {
firstMember,
//secondMember,
});
the extremely simple solution is often:
usually you'd have the require at the top of the file ...
var script = require('./script')
function stuff() {
script.farfunction()
}
instead, just require it "in the function"
function stuff() {
var _script = require('./script')
_script.farfunction()
}
An other method I've seen people do is exporting at the first line and saving it as a local variable like this:
let self = module.exports = {};
const a = require('./a');
// Exporting the necessary functions
self.func = function() { ... }
I tend to use this method, do you know about any downsides of it?
TL;DR
Just use exports.someMember = someMember instead of module.exports = { // new object }.
Extended Answer
After reading lanzz's response I could finally figure it out what is happening here, so I'll give my two cents on the subject, extending his answer.
Let's see this example:
a.js
console.log("a starting");
console.log("a requires b");
const b = require("./b");
console.log("a gets b =", b);
function functionA() {
console.log("function a");
}
console.log("a done");
exports.functionA = functionA;
b.js
console.log("b starting");
console.log("b requires a");
const a = require("./a");
console.log("b gets a =", a);
function functionB() {
console.log("On b, a =", a)
}
console.log("b done");
exports.functionB = functionB;
main.js
const a = require("./a");
const b = require("./b");
b.functionB()
Output
a starting
a requires b
b starting
b requires a
b gets a = {}
b done
a gets b = { functionB: [Function: functionB] }
a done
On b, a = { functionA: [Function: functionA] }
Here we can see that at first b receives an empty object as a, and then once a is fully loaded, that reference is updated through exports.functionA = functionA. If you instead replace the entire module with another object, through module.exports, then b will lose the reference from a, since it will point out to the same empty object from the beginning, instead of pointing to the new one.
So if you export a like this: module.exports = { functionA: functionA }, then the output will be:
a starting
a requires b
b starting
b requires a
b gets a = {}
b done
a gets b = { functionB: [Function: functionB] }
a done
On b, a = {} // same empty object
Actually I ended up requiring my dependency with
var a = null;
process.nextTick(()=>a=require("./a")); //Circular reference!
not pretty, but it works. It is more understandable and honest than changing b.js (for example only augmenting modules.export), which otherwise is perfect as is.
Here is a quick workaround that I've found use full.
On file 'a.js'
let B;
class A{
constructor(){
process.nextTick(()=>{
B = require('./b')
})
}
}
module.exports = new A();
On the file 'b.js' write the following
let A;
class B{
constructor(){
process.nextTick(()=>{
A = require('./a')
})
}
}
module.exports = new B();
This way on the next iteration of the event loop classes will be defined correctly and those require statements will work as expected.
One way to avoid it is to don't require one file in other just pass it as an argument to a function what ever you need in an another file.
By this way circular dependency will never arise.
If you just can't eliminate circular dependencies (e.g useraccount <---> userlogin), there's one more option...
Its as simple as using setTimeout()
//useraccount.js
let UserLogin = {};
setTimeout(()=>UserLogin=require('./userlogin.js'), 10);
class UserAccount{
getLogin(){
return new UserLogin(this.email);
}
}
//userlogin.js
let UserAccount ={};
setTimeout(()=>UserAccount=require('./useraccount.js'), 15);
class UserLogin{
getUser(){
return new User(this.token);
}
}

node.js module export how to use data amoung all modules?

I would like to use updated (and only then) globals among all node modules. How to do that? Questions are in code.
app.js
var data = 'data';
var global = require('glob.js')(data);
// here we are require your globals variables and we corectly 'set them'
console.log(globals.glob1);
// we can use them here
glob.js
module.exports = function(data)
{
var globs = {
glob1 : data.toLowerCase(),
glob2 : data.toUpperCase()
}
return globs;
}
mod.js
var global = require('glob.js'); // I require globals but they are not set...
function funct(someOtherData, someMoreData)
{
var test = global.glob1;
console.log(test);
// why I can't use globals here ? How can I use corectly set globals (globals need to be updated first - app.js, then ALL other modules should be able to use correctly set globals)?
}
module.export = funct;
For the answer scroll down to the TLDR section below but do read on to understand why.
Part1 - the difference between a function and a function call
Your first mistake is that you are exporting a function, not an object:
module.exports = function(data) // <---- this is a function
{
var globs = {
glob1 : data.toLowerCase(),
glob2 : data.toUpperCase()
}
return globs;
}
and in app.js you do this:
console.log(globs.glob1); <--- globs is a function, not an object
when you should be doing this:
console.log(globs().glob1);
Why is this? OK, lets forget for a moment your module. Consider the following code:
var a = function(){ return 2 };
console.log(a); // do you expect this to print a function or 2?
console.log(a()); // what do you expect this to print?
This is a very basic rule about functions in all programming languages, not just javascript: to get the return value you need to call the function. So in your code:
function myExportedFunction (data) {
// some logic here...
return globs;
}
console.log(myExportedFunction); // prints a function
console.log(myExportedFunction()); // prints the globs object
console.log(myExportedFunction().glob1); // prints value of glob1
So it's simple really. There is no magic syntax going on. You've just forgotten to return the glob object and are using the function pointer instead. Obviously the function has no glob1 property so it's correct for it to be undefined.
Part2 - function local variables
OK. So let's say you made the changes I recommended above. There's an obvious problem with the way the function was written. What happens when you do this:
var glob = require('glob.js')();
console.log(glob.glob1); // <--- prints "undefined"
So the first problem is you're not checking if you're passing data or nothing. So every time you call the function you will overwrite the stored value.
There's another problem, you are always returning a different object every time you call the function. Let's look at how local variables work when returned:
function a () {
var data = {}
return data;
}
var x = a();
var y = a();
x.testing = 1;
y.testing = 2;
console.log(x.testing); // prints 1
console.log(y.testing); // prints 2
So, every time you call a function that creates a local variable you are returning a different object. Actually what's doing this is not really the variable but the object literal syntax:
var a = {};
// is basically the same as
var a = new Object();
If we change the above example to:
function a () {
return {};
}
it would still behave the same.
TLDR
So, how do we fix it? Simple, create the object outside of the function and check if we pass data to initialize:
var globs = {
glob1 : "",
glob2 : ""
}
module.exports = function(data)
{
globs.glob1 = data.toLowerCase();
globs.glob2 = data.toUpperCase();
return globs;
}
Now everything should work:
In app.js
var global = require('glob.js')(data);
In mod.js
var global = require('glob.js')();
Epologue - modules are singletons
It may or may not be obvious to you why the above should work. In case you already know why I'm writing this as reference to future readers.
In node.js modules are implemented as proper singletons. Therefore in node if you want a singleton all you need to do is write a module, you don't need to implement any special code for it.
What this means is that all module globals (module scoped variables) are shared amongst all requires. Here's a very simple module to share one variable amongst all modules:
shared.js
var x = "";
module.exports = {
set: function (val) {x=val},
get: function () {return x}
}
a.js
var shared = require('./shared');
shared.set("hello world");
b.js
var shared = require('./shared');
console.log(shared.get()); // prints "hello world"
We're using this feature to declare a shared glob variable in the code above.
You can use the global. variable identifier to set global variables in NodeJS, instead of var, example:
app.js
var data = 'data';
var glob = require('./glob.js');
glob(data);
// here we are require your globals variables and we corectly 'set them'
console.log(global.gl.glob1);
var mod = require('./mod.js');
mod();
// we can use them here
glob.js
module.exports = function(data)
{
console.log("setting globals");
global.gl = {
glob1 : '1' + data,
glob2 : '2' + data
}
// return global.gl; // can be removed
}
mod.js
function funct(someOtherData, someMoreData)
{
var test = global.gl.glob1;
console.log(test);
test = global.gl.glob2;
console.log(test);
// why I can't use globals here ? How can I use corectly set globals (globals need to be updated first - app.js, then ALL other modules should be able to use correctly set globals)?
}
module.exports = funct;
As you can see in glob.js, i switched to var globs = to global.gl = and then in mod.js used it as global.gl.
Running app.js outputs:
setting globals
1data // From app.js
1data // From mod.js imported in app.js
2data // From mod.js imported in app.js
There are 2 options:
Use nodejs global variable (not recommended)
Create shared module
You chose 2nd option, but did it a bit wrong way by exporting a function. When you import the package and call the function it always creates new globs object and fulfill it with your data. Instead you can export an object. Simple example
glob.js
Global object is defined here
module.exports = {
glob1: '1',
glob2: '2'
};
mod.js
You can change global object here, like
var globs = require('./glob');
module.exports.updateGlob1 = function(data) {
globs.glob1 = data;
};
app.js
Here if you access global variable you can see it updated
var globs = require('./glob');
var mod = require('./mod');
mod.updateGlob1('1 plus 2');
console.log(globs.glob1); // Output: '1 plus 2'
There can be more complex examples, as for module design pattern often IIFE is used.
UPDATE
Another example using IIFE.
glob.js
module.exports = (function() {
var glob1 = 'initial value';
return {
// Getter method
getGlob1() {
return glob1;
},
// Setter method
setGlob1(value) {
glob1 = value;
}
}
})();
mod.js
var shared = require('./shared');
module.exports.testFn = function() {
// Access global variable with getter method
console.log('In mod.js', shared.getGlob1());
};
app.js
var shared = require('./shared');
var mod = require('./mod');
// Print initial value
console.log('Initial', shared.getGlob1());
// Set new value to global variable
shared.setGlob1('new value');
// Print updated value
console.log('In app.js', shared.getGlob1());
// Use global variable in mod.js file
mod.testFn();

Using a helper class easily in expressjs

I'm using a pretty barebones expressjs app and want to add a library/helper to store some useful code. Ideally, I'd like it to work as a module. However, I'm unable to get it to work. Here's what I've got:
// helpers/newlib.js
var NewLib = function() {
function testing() {
console.log("test");
}
};
exports.NewLib = NewLib;
.
// controllers/control.js
var newlib = require('../helpers/newlib').NewLib;
var helper = new NewLib();
helper.testing();
.
The error I get is ReferenceError: NewLib is not defined. I followed the design pattern (of how exports works) based on another simple module I downloaded.
What am I doing wrong?
There are two problems with your code.
First, you are assigning the NewLib function from helpers/newlib.js to newlib var, so you should use new newlib() not new NewLib():
// controllers/control.js
var newlib = require('../helpers/newlib').NewLib;
var helper = new newlib(); // <--- newlib, not NewLib
helper.testing();
Or you can rename your variable to NewLib:
// controllers/control.js
var NewLib = require('../helpers/newlib').NewLib;
var helper = new NewLib(); // <--- now it works
helper.testing();
Second, the testing function is not accessible outside the constructor scope. You can make it accessible by assigning it to this.testing for instance:
// helpers/newlib.js
var NewLib = function() {
this.testing = function testing() {
console.log("test");
}
};

Nodejs naming conventions for modules

Given this pattern :
A module defines a public API, but needs runtime information.
// Contrived example for a module abstracting a db
module.exports = function (host, schema, ...) {
// A "module-level", private, instance of an object
// that will be used by the public API of the module
var connection = getConnection(host, schema, ...);
return {
queryItems : function (arg) {
// Something that uses both the "module" level instance
// and runtime args.
return connection.query(... arg ... );
}
}
};
Another module will have to require it, than "instanciate" the module, and
use it.
// Module "bar"
var db = require("db"),
xxx = db("myhost", "myschema");
xxx.queryItems("Test"):
In "traditionnal" OO, the first module would expose a class constructor, and by conventions those
have a first capital letter, so you would write
var Db = require("db"),
db = new Db("....", "....");
And there is not ambiguity ; the meaning of "var cat = new Cat()" is pretty accepted ; "var felix = new Cat()" would only be used in case of multiple instances.
Is there a "canonical" / "idiomatic" way, in nodejs, to name such a module exposing functions, and the object that was returned by this function ?
(Sorry if too subjective, I'm looking for the "established" convention rather than a "best" one.)

What is the best way to expose methods from Node.js?

Consider I want to expose a method called Print
Binding method as prototype:
File Saved as Printer.js
var printerObj = function(isPrinted) {
this.printed = isPrinted;
}
printerObj.prototype.printNow = function(printData) {
console.log('= Print Started =');
};
module.exports = printerObj;
Then access printNow() by putting code require('Printer.js').printNow() in any external .js node program file.
Export method itself using module.exports:
File Saved as Printer2.js
var printed = false;
function printNow() {
console.log('= Print Started =');
}
module.exports.printNow = printNow;
Then access printNow() by putting code require('Printer2.js').printNow() in any external .js node program file.
Can anyone tell what is the difference and best way of doing it with respect to Node.js?
Definitely the first way. It is called the substack pattern and you can read about it on Twitter and on Mikeal Rogers' blog. Some code examples can be found at the jade github repo in the parser:
var Parser = exports = module.exports = function Parser(str, filename, options){
this.input = str;
this.lexer = new Lexer(str, options);
...
};
Parser.prototype = {
context: function(parser){
if (parser) {
this.contexts.push(parser);
} else {
return this.contexts.pop();
}
},
advance: function(){
return this.lexer.advance();
}
};
In the first example you are creating a class, ideally you should use it with "new" in your caller program:
var PrinterObj = require('Printer.js').PrinterObj;
var printer = new PrinterObj();
printer.PrintNow();
This is a good read on the subject: http://www.2ality.com/2012/01/js-inheritance-by-example.html
In the second example you are returning a function.
The difference is that you can have multiple instances of the first example (provided you use new as indicated) but only one instance of the second approach.

Resources