Use global module in node - node.js

I have a node application with some modules.
I would like to use one of my module in this way:
Init the module inside server.js (the first file called from npm)
When the request is passed from socket set the request configuration inside my module
Use the module with the request configuration in other modules.
Example:
module.js
'use strict';
const Module = require('module');
let module = new Module({
some_information
});
function test(message) {
module.info(message);
}
function configureRequest(request) {
module.configure({
payload: {
request: request
}
});
}
module.exports = {
info,
configureRequest
};
server.js (little piece of code)
let module = require('./src/module.js');
get_request.js
let module = require('./src/logger.js');
let another = require('./src/another.js');
scServer.on('connection', function (socket) {
module.configureRequest(socket.request);
module.info('test'); //inside it there is request
another.start();
});
another.js
let module = require('./src/logger.js');
module.info('test'); //inside it there isn't request
As you can see inside another.js I require again my global module so the request is not set, I don't want if is possible to pass every time the request into all modules (I have many and many modules that use the global module)
How can I solve?

What I usually do is use consign module to autoload my modules inside my app. https://github.com/jarradseers/consign

Related

Imported module is undefined when there's a circular dependency between the modules when one module is in the parent directory of the other module

file structure is
-src
--Visitor
---visitor.model.js
---Sessions
----session.model.js
In visitor.model.js file
const {Sessions} = require('./Sessions/session.model');
const Visitor = {};
Visitor.visitorFunc = () => {
}
Sessions.sessionFunc();
module.exports = {Visitor: Visitor};
In session.model.js file
const {Visitor} = require('../visitor.model.js');
const Session = {};
Sessions.sessionFunc = () => {
}
Visitor.visitorFunc();
module.exports = {Session: Session};
when I do imports like this in Visitor file Session is undefined. What is the reason for that.. Is it calling import recursively ?
Circular dependencies are allowed in node
https://nodejs.org/api/modules.html#modules_cycles
When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.
Since Session and Visitor sounds like database models with an M:N relationship circular dependencies are the way to go (e.g.: Join query)
How to deal with cyclic dependencies in Node.js
Node.js Module.Exports Undefined Empty Object
But it would be less messy to avoid them if you can.
As #prashand above has given the reasons you would have to do imports and calling imported functions after exporting current module.. above example is working with a slight change as follows
const Visitor = {};
Visitor.visitorFunc = () => {
console.log('hello from visitor model');
}
module.exports = {Visitor: Visitor};
// import session.model after exporting the current module
const {Session} = require('./Sessions/session.model');
// then call the required function
Session.sessionFunc();
Simply just use exports.someMember = someMember instead of module.exports = { someMember }.
Your visitor.model.js file is outside the Sessions directory. In order to import session.model.js you need to give absolute path to that file. So your require statement should be like this
const { Sessions } = require('../Sessions/session.model.js');

Custom module in Node.js

I am new to NodeJS programming so I was trying make simple custom module by extending one module to another which prints in console log.
ExtendMod.js
var exports = module.exports = {};
exports.tutorial = function() {
console.log("N Tutotial");
}
app.js
var Tutor=require('./ExtendMod.js');
exports.NodeTutorial = function() {
console.log("Node Tutorial")
function pTutor() {
var PTutor=Tutor
PTutor.tutorial;
}
}
console.log(require('./thirdNode.js').NodeTutorial());
I have extended ExtendMod.js in app.js.
Question: Why an empty braces after exports when we create my first module and also in app.js we didn't take exports as a variable is it global?
My output :
Node Tutorial
N Tutorial
Undefined
What is this undefined?

How Do I create a NodeJS Module?

I have read the details on NodeJS site : https://nodejs.org/api/modules.html. I don't understand how modules work, and what are the minimal steps for creating a module, and how npm can help me.
How can I create a module?
How do I use a module?
What does putting it on npm mean?
Note: this is a self answered question, with the purpose of sharing knowledge as a canonical.
You can create a NodeJS module using one line of code:
//mymodule.js
module.exports = 3;
Then you can load the module, by using require:
//app.js
require('./mymodule.js')
I added './' because it is a module of one file. We will cover it later.
Now if you do for example:
var mymodule = require('./mymodule.js');
console.log(mymodule); // 3
You can replace the number 3, with a function, for example:
//mymodule.js:
module.exports = function () {
console.log('function inside the module');
};
Then you can use it:
var mymodule = require('./mymodule.js');
mymodule();
Private variables:
Every variable you define inside A module will be defined only inside it:
//mymodule.js
var myPrivateVariable = 3;
publicVariable = 5; // Never user global variables in modules
//It's bad-pracrtice. Always add: var.
module.exports = function() {
// Every function of the module can use the private variables
return myPrivateVariable++
};
//app.js
var mymodule = require('./mymodule.js');
console.log(mymodule()); // return 3
console.log(mymodule()); // return 4
Reuse modules:
One more thing you need to know about NodeJS modules, is that if you use the same module twice(require it), it will return the same instance, it will not run in twice.
for example:
//app.js
var mymodule1 = require('./mymodule.js');
var mymodule2 = require('./mymodule.js');
console.log(mymodule1()); //return 3
console.log(mymodule2()); //return 4 (not 3)
console.log(mymodule1()); //return 5
As you see in the example below, that private variable is shared between all the instances of the module.
A module package
If your module contain more than one file, or you want to share the module with others, you have to create the module in separate folder, and create a package.json file for the module.
npm init will create package.json file for you.
For modules, there are 3 required parts:
package.json
{
"name" : "You module name",
"version" : "0.0.3"
}
Now, you can publish the module, using npm publish. I recommend you publish all your modules to github as well, then the module will be connected to your github page.
What you publish to NPM will be accessible by everyone. So never publish modules that contain private data. For that you can use private npm modules.
Next steps
Modules can return more than one function or one variable. See this samples in which we return an object.
module.exports.a = function() {
// ..
};
module.exports.b = function() {
// ..
};
// OR
myObj = {
a:3,
b:function() {
return this.a;
}
};
module.exports = myObj;
More info:
Read about package.json files
Versioning in you modules best practice
More best practive for NodeJS modules
Private modules, using private npm
Related Questions:
What is the purpose of Node.js module.exports and how do you use it?
module.exports vs exports in Node.js
Creating module in node.js is pretty simple!!!
You may consider module as a set of functionalities you can use in other code by simply just requiring it.
for eg:Consider a file functional.js having the content:
function display(){
console.log('i am in a display function');
}
module.exports = display;
Now just require it in any other module like:
var display = require('./functional');
display()
Output:i am in a display function
Similarly you can do:
var exports = module.exports = {};
exports.display = function(){
console.log('i am in the display function');
}
or you do the same for objects like:
var funObj = {
hello:function(){
console.log('hello function');
},
display:function(){
console.log('display function');
}
};
module.exports = funObj;
There are two main ways for wiring modules. One of them is using hard coded dependencies, explicitly loading one module into another using a require call. The other method is to use a dependency injection pattern, where we pass the components as a parameter or we have a global container (known as IoC, or Inversion of Control container), which centralizes the management of the modules.
We can allow Node.js to manage the modules life cycle by using hard coded module loading. It organizes your packages in an intuitive way, which makes understanding and debugging easy.
Dependency Injection is rarely used in a Node.js environment, although it is a useful concept. The DI pattern can result in an improved decoupling of the modules. Instead of explicitly defining dependencies for a module, they are received from the outside. Therefore they can be easily replaced with modules having the same interfaces.
Let’s see an example for DI modules using the factory pattern:
class Car {
constructor (options) {
this.engine = options.engine
}
start () {
this.engine.start()
}
}
function create (options) {
return new Car(options)
}
module.exports = create

Scope of JS Functions outside Node Modules

I know that in Node, if you've got variables defined outside your module.exports, it's still locally meaning it's not poluting the global namespace. It's not public. What's public is what's defined in your module.
However what about functions. Do they act the same as variables? Could function names that live outside module.exports collide?
example:
myFirst.js
var iAmStillPrivate = "private";
module.exports = {
...whatever code I wanna expose through this module
}
function find(somethingId)
{
..some code
};
mySecond.js
var iAmStillPrivate = "private";
module.exports = {
...whatever code
}
function find(somethingId)
{
..some code
};
do the find() conflict and pollute the global namespace?
Should I do this instead?:
mySecond.js
var iAmStillPrivate = "private";
module.exports = {
find: find(id)
...whatever code
}
var find = function find(somethingId)
{
..some code
};
or doesn't it matter throwing it into a variable? good practice? doesn't really matter?
CONCLUSION
mySecond.js (I'm a mother fu**ing module. I create an implicit anonymous function that wraps everything in here when I'm 'required' inside other .js files)
`var iAmStillPrivate = "private";` (no I'm scoped to the module, the root anonymous function that is...)
(module.exports - I'm allowing this stuff to be public. When I say public in node,that is...public in that the stuff in here is accessible to other modules in other .js files or whatever.)
module.exports = {
...whatever code
}
(I'm still a function scoped to the module but I've not been exported so I'm not available to other modules, I only belong to the module (the root anonymous function)
function find(somethingId)
{
..some code
};
Functions in each module of NodeJs are local for that module and do not conflict with functions of other modules with the same name.
Think about it as though the module was wrapped in a function.
Also you really don't need to define a variable for your functions because at the end it doesn't matter, the scope of functions and variables of these two lines are the same and local for module:
var find = function find(somethingId) ...
function find(somethingId) ...
Side Question
Also in you comment you asked about this scenario:
what if I have a function in global scope and a module also has a private function with the same name. do they conflict?
What happens is that inside your module any call to that function will trigger the local function not the global one. once you are outside of that module or inside another modules any call to that function will trigger the global function.
Let's look at it with an example. suppose our Node app starting point is index.js here its content:
echo('one');
require('./include.js')
echo('three');
function echo(txt){
console.log("we are in index.js", txt);
}
And here is a module called include.js:
echo('two');
function echo(txt){
console.log("we are in include.js", txt);
}
if you run this app using node index.js command, the output should be:
we are in index.js one
we are in include.js two
we are in index.js three
See? All the functions are there working as I explained earlier.

Are node.js modules need to be wrapped inside the module pattern?

To ensure proper isolation, I tend to wrap each node.js module that I write inside a function scope:
(function() {
var express = require('express');
var jade = require('jade');
var moment = require('moment');
exports.someFunction = function() {
// do something
};
exports.otherFunction = function() {
// do something else
};
})();
I've been doing this for some time now, but I have the feeling that node.js' module system is actually doing this for me, or (in other words) that the above code is equivalent to the following code:
var express = require('express');
var jade = require('jade');
var moment = require('moment');
exports.someFunction = function() {
// do something
};
exports.otherFunction = function() {
// do something else
};
Are the two really equivalent?
In particular, I am interested to know whether is the isolation level is the same: are the express, jade or moment variables local to the module? (i.e., I'd like to make sure that they are not defined in the global scope or interfere with any other definition outside of this module).
Variables declared within a module are local to that module. It is safe to omit your enclosing function.
From the Node.js docs:
Variables local to the module will be private, as though the module was wrapped in a function

Resources