FileUtil.js:
exports.a = function(pre) {
var module = {}
module.writeStringToFile = function writeStringToFile() {
casper.log(pre + " succ");
};
return module
}
main.js:
var casper = require('casper').create();
var FileUtil = require('FileUtil').a('xxx')
FileUtil.writeStringToFile() //xxx succ
That works, but what I want is var FileUtil = require('FileUtil')('xxx') instead of require('FileUtil').a('xxx').
I tried exports = function(pre) ..., but it doesn't works.
So, how to make a custom CasperJS module with custom parameter?
If you want var FileUtil = require('FileUtil')('xxx') to be your object then you need to use module.exports. It can export a single object, which can even be a function:
module.exports = function(pre) {
var module = {}
module.writeStringToFile = function writeStringToFile() {
casper.log(pre + " succ");
};
return module
}
Of course, it would be a better form to rename the inner module variable to something else.
Related
I made a set of functions and none of them is working. Here's one of them, for example:
function squareArea(side) {
var sArea = side * side;
return sArea;
}
And this is how I require the module:
var mfs = require("m-p-formulas-js");
var test = mfs.squareArea(2);
console.log(test)
It returns this error:
TypeError: mfs.squareArea is not a function
What should I do to solve this?
You aren't exporting the function so it doesn't exist on the required module object. Assuming you're using ES5, use module.exports which contains the module's exports:
function squareArea(side) {
var sArea = side * side;
return sArea;
}
module.exports = {
squareArea: squareArea
};
You could also shorten it to this using the exports shortcut:
exports.squareArea = squareArea;
You need to export the function to make it available to others. Add the following to the bottom of your definition of m-p-formulas-js module:
module.exports = {
squareArea
}
I have a module like below
'use strict';
var val = GlobalVariable.someMethod();
...
...
module.exports = myExportedClass;
I am calling it with require('./myModule');. But would like to know if GlobalVariable can be dynamically injected.
I have tried this method, though I know that this does not work :)
(function(GlobalVariable) {
require('./myModule');
})(SomeOtherGlobalVariable);
So it did not, because module will execute in different scope. Is there any other way where I can pass my own version of GlobalVariable when using require.
Yes, it can be injected. Do something like the following:
module.exports = function(injectedObject) {
return {
doSomething: function() {
return injectedObject.something();
}
}
};
you can pass you variable as an argument when requiring it
yourvariable="value";
var file = require('./myModule')(yourvariable);
or can pass it separately, as file now contain function reference of module.exports
yourvariable="value";
var file = require('./myModule');
file(yourvariable)
your module will look like as:
module.exports = function(yourVaraible) {
yourVaraible.myfunction = function() {
};
return yourvariable;
};
i'm looking for the best way to overrid a method in a custom module node.js.
I'm working on a custom middleware who will help me to automatically load some custom module. Like security, users etc...
But i want to be able to override some methods if i need something like a custom security hand check.
For now the only way i found is to export a function who will replace my method and expose context variables.
// CUSTOM MODULE EXAMPLE
// ========================================
var myVar = "Hello ";
var myVar2 = "!";
var method = function() {
return "world" + myVar2;
}
module.exports.loadModule = function() {
console.log(myVar + method());
};
module.exports.overrideMethod = function(customMethod) {
method = customMethod;
};
module.exports.myVar2 = myVar2;
And my main app will be like that:
// MAIN APP EXAMPLE
// ========================================
var myCustomModule = require('customModule.js');
myCustomModule.overrideMethod(function() {
return "viewer" + myCustomModule.myVar2;
});
myCustomModule.loadModule();
What do you think? Am i on the good way?
Thanks for reading.
Tom
Generally I treat any module that has mutable global state like this to be a mistake. Instead, I'd opt for creating an object with these methods and having a way to pass in overrides.
// CUSTOM MODULE EXAMPLE
// ========================================
var DEFAULT_PREFIX = "Hello ";
var DEFAULT_SUFFIX = "!";
var DEFAULT_METHOD = function() {
return "world" + DEFAULT_SUFFIX;
};
module.exports = function(options){
var method = options.method || DEFAULT_METHOD
return {
loadModule: function(){
console.log(myVar + method());
}
};
};
module.exports.DEFAULT_SUFFIX = DEFAULT_SUFFIX;
Then you can use this like this:
// MAIN APP EXAMPLE
// ========================================
var myCustomModule = require('customModule.js');
var loader = myCustomModule({
method: function() {
return "viewer" + myCustomModule.DEFAULT_SUFFIX;
}
});
loader.loadModule();
I have two different js files that use the same module.
file1.js:
var mod1 = require('commonmodule.js');
mod1.init('one');
file2.js:
var mod2 = require('commonmodule.js');
mod2.init('two');
(both these files file1.js, file2.js are loaded inside my server.js file, they themselves are modules)
now in commonmodule.js:
var savedName;
exports.init = function(name)
{
savedName = name;
}
exports.getName = function()
{
return savedName;
}
I noticed that this savedName is always overridden dependent on who set it last.So it doesn't seem to work. How would I get a module to maintain state?
Note: I also tried to set savedName as exports.savedName in the commonmodule.js but it doesn't work either
You can just create a new instance every time the module is required:
commonmodule.js
function CommonModule() {
var savedName;
return {
init: function(name) {
savedName = name;
},
getName: function() {
return savedName;
}
};
}
module.exports = CommonModule;
file1.js
var mod1 = new require('./commonmodule')();
mod1.init('one');
console.log(mod1.getName()); // one
file2.js
var mod2 = new require('./commonmodule')()
mod2.init('two');
console.log(mod2.getName()); // two
modules in and of themselves are simple object instances. A single instance will be shared by all other modules (with the caveat that it is loaded via the same path). If you want state, use a class and export a constructor function.
example:
//Person.js
function Person(name) {
this.name = name;
}
module.exports = Person;
To use it:
var Person = require("./Person");
var bob = new Person("Bob");
Modules are not like classes/class functions; by default, mod1 and mod2 will refer to the same module due to caching. To keep track of per-instance state, you'll need a constructor function or something similar inside your module, e.g.
var mod = require('commonmodule.js');
var state = new mod.init('one');
Where init defines the stateful object. You could also have it return an object literal, in which case you wouldn't have to use new (e.g. var state = require('commonmodule.js').init('one');)
(This is assuming you want the module to have other, shared state in addition to the per-instance state; if that is not the case, Peter Lyons' method would be simpler.)
You could perhaps remove from cache your module. Like that:
file1.js:
var mod1 = require('commonmodule.js');
mod1.init('one');
file2.js:
delete require.cache[require.resolve(modulename)];
var mod2 = require('commonmodule.js');
mod2.init('two');
But I don't find it very convenient and clean.
But you could also clone it or make a small proxy.
Also you could create classes:
var savedName;
exports.obj = {}
exports.obj.prototype.init = function(name)
{
savedName = name;
}
exports.obj.prototype.getName = function()
{
return savedName;
}
Then :
var mod2 = new (require('commonmodule.js'))();
mod2.init('two');
I'm trying to understand the difference between the following two alternate representations of what I thought was the same functionality.
apiRegistry1.js
module.exports = function () {
var apiRegistry = {};
var files = fs.readdirSync('./apis');
for (var index in files) {
var fileName = files[index];
var module = fileName.split('.')[0];
apiRegistry[module] = require('../apis/' + module);
}
// console.log(apiRegistry) --> Prints {key: moduledef ..}
return apiRegistry;
};
vs
apiregistry2.js
var apiRegistry = {};
var files = fs.readdirSync('./apis');
for (var index in files) {
var fileName = files[index];
var module = fileName.split('.')[0];
apiRegistry[module] = require('../apis/' + module);
}
// console.log(apiRegistry) --> Prints {key: moduledef ..}
module.exports = apiRegistry;
server.js
var apiRegistry1 = require('./includes/apiregistry1')(); // returns {key: moduledef ..}
var apiRegistry2 = require('./includes/apiregistry2'); //returns {}
apiRegistry1 behaves as I would expect, but 2 doesn't. On some level it makes sense that 1 is a function and is evaluated when it's called, and that's why it works but I don't understand why printing the value within the module always works, but referencing outside of it doesn't. Is there something fundamental about how require works that I'm missing?
var module = fileName.split('.')[0];
is the culprit.
Because of how scoping works in JavaScript, that module variable isn't local to the for loop but instead the whole file. Thus, when you use it at the end:
module.exports = apiRegistry;
you are setting the exports property on your own module variable instead of the one node expects you to use. Changing to using another variable name solves your problem:
var apiRegistry = {};
var files = fs.readdirSync('./apis');
for (var index in files) {
var fileName = files[index];
var myModule = fileName.split('.')[0];
apiRegistry[myModule] = require('../apis/' + myModule);
}
// console.log(apiRegistry) --> Prints {key: moduledef ..}
module.exports = apiRegistry;