How to pass variables into NodeJS modules? - javascript

In one of my JS files I include another one. How can I set variables in the included module?
I thought doing something like this would work
var mymodule = require('mymodule.js');
mymodule.myvariable = 'test';
And then in mymodule
this.myvariable === 'test';
But this doesn't work, it's undefined. What are the various options for passing a value into a module? I could just add the variable as a parameter to every function I call in mymodule, but that isn't ideal.
Is there a way to do it without globals, so that I can set the variables independently in various required modules, like this?
var mymodule1 = require('mymodule.js');
var mymodule2 = require('mymodule.js');
mymodule1.myvariable = 'test1';
mymodule2.myvariable = 'test2';

The problem with what you were doing is that you set the variable after importing, but this.myvariable === 'test'; was being called when the module was imported, before your variable was set.
You can have your module export a function and then call the function when you import, passing your variable as an argument.
module.exports = function(myVar) {
var myModule = {
// has access to myVar
...
};
return myModule;
};
When you import,
var myModule = require('myModule')(myVar);
If you use this method, keep in mind that you get a different instance of your module wherever you import, which may not be what you want.
If you want to set values of a module from outside the module, a good option is to have your module export an object with a setter method, and use that to set the value of the variable as a property of the object. This makes it more clear that you want this value to be settable, whereas just doing myModule.myVar = can set you up for confusion later.
module.exports = {
myVar: null,
setMyVar: function(myVar) {
this.myVar = myVar;
},
...
};
In this case you're accessing the same instance of the model wherever you import it.
Edit in response to comment
In the first option you show where you get a different instance each
time, how can I export multiple functions that each share the same
myVar? If that module exports 5 functions each that need myVar, can I
set it in one place like at import time rather than passing it into
each function?
Not entirely sure if I understand what you're describing, but you could do something like this:
module.exports = function(myVar) {
var modules = {};
modules.someModule = {...};
modules.anotherModule = {...};
...
return modules;
};
Each of these sub-modules would have access to the same myVar. So you would import as above and the result would be an object containing each of your five modules as properties. I can't say whether this is a good idea, it's getting pretty convoluted, but maybe it makes sense for your situation.

NodeJS require() will always load the module once so you will need to implement scoping into your module where different instances of the module can exist with their own internal state.
You can implement your module as a JS class like:
var MyModule = function(){};
MyModule.prototype.someFunction = function(params){
this.someVar = params;
}
MyModule.prototype.anotherFunction = function(key, value){
this[key] = value;
}
module.exports = MyModule;
Then in your code;
var MyModule = require('MyModule');
someModule = new MyModule();
// treat someModule like an object with its getters/setters/functions

Should work just fine. Here is a working example:
index.js
var module = require('./module.js');
module.myvar = 'Hello world';
module.test();
module.js
module.exports = {
test: function() {
console.log('var is', this.myvar);
}
};
Keep in mind if you use this in a closure that the scope isn't any longer the module itself. So that could be your problem.
Can you show me the part of the module code where you use this?

This is a module named StrUpperCase.js
exports.StrUpperCase = function(str) {
return str.toUpperCase();
}
In app.js:
var str = "Welcome World...";
const SUC = require('./modules/StrUpperCase');
console.log(SUC.StrUpperCase(str));

Related

meaning of module.exports= function in node.js

I am taking first steps with node.js and obviously one of the first things i tried to do was exporting some data from a module, so i tried this simple case:
dummy.js:
var user = "rally";
module.exports = {
user:user
};
and than required it from a different file like this:
var dummy = require('./dummy.js');
console.log(dummy.user); // rally
So far so good, every thing works, but now i dived into code where there is this definition in the beginning of the module:
module.exports = function(passport,config, mongoose) {}
and i don't understand whats the meaning of it and how can i work with it.
just for trying to understand i defined some variables inside this abstract function but couldn't get their value from any other file.
any idea how can i export variables from module defined like this..? so for example i could require this module and get the "Dummy" variable and use it in a different file
module.exports = function(passport,config, mongoose) {
var dummy = "Dummy";
}
It works exactly the same as the first one does, only that it exports a function instead of an object.
The module that imports the module can then call that function:
var dummy = require('./dummy.js');
dummy();
any idea how can i export variables from module defined like this..?
Since functions are just objects, you can also assign properties to it:
module.exports = function(passport,config, mongoose) {}
module.exports.user = 'rally';
However I'd argue that this is less expected if a module directly exports a function. You are probably better off exporting the function as its own export:
exports.login = function(passport,config, mongoose) {}
exports.user = 'rally';
WHAT IS A MODULE?
A module encapsulates related code into a single unit of code. When creating a module, this can be interpreted as moving all related functions into a file.
// dummy.js
var exports = module.exports = {};
The utility of dummy.js increases when its encapsulated code can be utilized in other files. This is achieved by using exports.
HOW ARE THEY INVOKED?
You could declare your functions outside of the module.exports block. Functions inside exports can be invoked exactly the same way as variables or any other object.
EXAMPLE
//dummy.js
var myVariable = "foo";
var myFunction = function(){
//some logic
};
module.exports{
myVariable : myVariable,
myFunction : myFunction,
myVariableTypeTwo : "bar",
myFunctionTypeTwo : function () {
//some logic
}
}
We can now access the publicly available methods of dummy.js as a property from any js file.
var dummy = require('./dummy.js');
dummy.myVariable; //foo
dummy.myFunction();
dummy.myVariableTypeTwo; //bar
dummy.myFunctionTypeTwo();
NOTE
In the code above, we could have replaced module.exports with exports and achieved the same result. If this seems confusing, remember that exports and module.exports reference the same object.

How to deal with mutual inclusions in Node.js?

I'm developing a Node.js application that contains a game engine, and I basically have this pattern in my engine:
A.js
var B = require('./B');
var A = module.exports = function () {
this.b = new B;
console.log(B.staticBar)
};
A.staticFoo = 'foo';
B.js
var A = require('./A');
var B = module.exports = function () {
console.log(A.staticFoo);
};
B.staticBar = 'bar';
So I want both A.staticFoo to be accessible in B.js and B.staticBar in A.js.
Any idea how to do that?
Thanks
EDIT : actually my static variables are config values, so another solution would be to group them into a config.js file and require that file in every other file, but I find it more elegant to define config variables directly as static members of related classes. Hope that's clear enough ;)
I would suggest separating your static state into a third module... By decoupling state from your module, you can operate either independently.
state.js
//state.js - changed by other modules...
module.exports = {
staticFoo: null,
staticBar: null
};
a.js
//a.js
var state = require('./state');
exports = module.exports = fnA;
...
function fnA() {
console.log(state.staticBar);
}
b.js
//b.js
var state = require('./state');
exports = module.exports = fnB;
...
function fnB() {
console.log(state.staticFoo);
}
Another example mentions something akin to dependency injection... given how modules work in JS, and that you can override for testing with proxyquire and the like, I tend to prefer the simpler requires structure over dealing with DI/IoC in JS as it muddles your project code.
I also like to do my requires, then my exports, then any methods within that module, usually just one method in a module.
It would depend on the architecture of your code. BUT, working with other people's code is always different of course.
The best choice is to separate your code into smaller module(s). If they're referencing each other it can challenging to build tests especially when the code grows.
OR
If that's not possible you could always remove coupling through the use of references.
B.js
var _A;
exports.setA = function(ref) {
_A = ref;
};
var B = exports.B = function () {
console.log(_A.staticFoo);
};
And use B.setA(A) to make sure B has a reference to use A.staticFoo

How to capture exports of a javascript file when using Browserify?

if I have a javascript file with the contents:
(function() {
return function (foo) {
return foo + "bar";
};
}());
is it possible to capture the return value from that file in a variable somehow? I'm assuming the function is returned to the auto instantiating parens and then garbage collected, but I'm not sure.
As an aside, I'm trying to expose a browserified collection of node modules to the window for testing purposes (I realize there are probably other methods for going about this, but I'm curious about this one).
Files that are included with browserify (or other CommonJS compatible system) can expose methods or values to the requiring file via module.exports. module.exports is returned from the require() statement.
Take this example:
index.js
var myClass = require("myClass");
myClass.js
module.exports = (function() {
return function (foo) {
return foo + "bar";
};
}());
index.js now has access to the function that is built in myClass.js and can use it as:
index.js
var myClass = require("myClass");
// expose the class to the global scope
window.myClass = myClass;
var result = myClass("foo ");
so the var result would have the value "foo bar".

How to separate javascript into files without using global scope?

I am loading separate .js files into my html page. These files use anonymous functions so that the global scope is not filled with global variables. For example: this is my 'utils.js' file:
(function(window){
var Utils = {
createURL: function() {
console.log("creating url");
}
};
})(window);
My question: if I have several of these .js files, how can they reference each other without using the global scope? As it stands, I can only call this function from within the same utils.js file:
var myUtils = new Utils();
You can create global modules and expose only the needed functions like this...
// In some JS file
var moduleX = (function(window){
var Utils = function(){
};
return {
"Utils" : Utils
};
})(window);
// In a some other JS file
var util = new moduleX.Utils();
Btw, you cannot instantiate a JSON object(Utils in your case). So please change that to a function.
You can use a javascript loader like
require.js
head.js
yepnope
If you don't want to use a loader, maybe you can reduce the global usage to the minimun using a design pattern like the mediator or module.
(function(window){
var app = {};
app.Utils = {
createUrl:function(){}
};
window.app = app;
})(window);
and then you can work with the app like this :
app.Utils.createUrl();
If you don't want to use a third party tool, you can wrap everything into one module by using the following pattern:
//file1
var myModule = (function(window, that){
var myVar = 1;
that.myMethod1 = function(){
console.log("i am module 1");
};
return that;
}(window, myModule || {}));
//file2
var myModule = (function(window, that){
that.myMethod2 = function(){
console.log(typeof myVar); //undefined
that.myMethod1(); //i am module 1
};
return that;
}(window, myModule || {}));
This will ensure that you only have one single global variable. But, you will of course not be able to access local variables of another file.

In Node.JS, how do I return an entire object from a separate .js file?

I am new to Node.js and trying to figure out how to request an object from a separate file (rather than just requesting a function) but everything I try--exports,module-exports,etc--is failing.
So, for example, if I have foo.js:
var methods = {
Foobar:{
getFoo: function(){return "foo!!";},
getBar: function(){return "bar!!";}
}
};
module.exports = methods;
And now I want to call a function within an object of foo.js from index.js:
var m = require('./foo');
function fooMain(){
return m.Foobar.getFoo();
};
How do I do this? I have tried all sorts of combinations of exports and module-exports but they seem to only work if I call a discrete function that is not part of an object.
You said that you tried exports, but your code doesn't show it. Anything that you want to be visible from outside your module must be assigned to (or otherwise be referable from) module.exports. In your case, where you have an object already, you can just assign it to module.exports:
var methods = {
...
};
// You must export the methods explicitly
module.exports = methods;
module.exports isn't magic, it's a normal object, and you can treat it as such. Meaning that you could have assigned your methods directly to it, as in:
module.exports.Foobar = {};
module.exports.Foobar.getFoo = function() { ... };
...
Or, as you probably know, you could event replace it with a function:
module.exports = function() { return "It's ALWAYS over 9000!!!!"; };
Only after exporting will you be able to use anything in another module.

Categories

Resources