Module exports and method call - node.js

I'm trying to developp a module with nodejs. My code is something like this :
var fs = require('fs');
module.exports.method1 = function () {
// Some stuff
}
module.exports.method2 = function ()
{
// Some stuff
}
I would like to do something like :
module.exports.method2 = function (url, dir, name)
{
this.method1();
}
How to do this ?

var fs = require('fs');
exports.method1 = function () {
// Some stuff
}
exports.method2 = function ()
{
exports.method1();
}

To make it a little bit swankier you could do something like:
module.exports = {
function1: function(){
//some stuff
},
function2: function(){
this.function1();
}
};
If you want private scope:
module.exports = function(){
var myPrivateVar = 'foo';
var publicObject = {
function1: function(){
//some stuff
console.log(myPrivateVar);
},
function2: function(){
this.function1();
}
};
return publicObject;
}
The difference is though that you need to invoke it where the former is just an object reference. The second example is more like a constructor function... require + invoke... var myMod = myModule(); myMod.function2() will output 'foo'
IMHO this is a more object-oriented way of doing it rather than exporting each individual function. This allows for better separation and cleaner code.

Related

Initialize a module when it's required

I have a module with some initialization code inside. The init should be performed when the module is loaded. At the moment I'm doing it like this:
// in the module
exports.init = function(config) { do it }
// in main
var mod = require('myModule');
mod.init(myConfig)
That works, but I'd like to be more concise:
var mod = require('myModule').init('myConfig')
What should init return in order to keep mod reference working?
You can return this, which is a reference to exports in this case.
exports.init = function(init) {
console.log(init);
return this;
};
exports.myMethod = function() {
console.log('Has access to this');
}
var mod = require('./module.js').init('test'); //Prints 'test'
mod.myMethod(); //Will print 'Has access to this.'
Or you could use a constructor:
module.exports = function(config) {
this.config = config;
this.myMethod = function() {
console.log('Has access to this');
};
return this;
};
var myModule = require('./module.js')(config);
myModule.myMethod(); //Prints 'Has access to this'

How to initialize in module pattern

How can i initialize async.queue "for" the global module scope?
The example bellow shows the main problem, that qq is undefined, not yet known or its only defined locally in a function scope.
The target is to access a "module-global" q in different module member functions.
So creating a module pattern version of the example in https://github.com/caolan/async#queue
I know why the // not working-code isn't valid, it is only too show which declaration ideas i tried.
Additional i m aware of how to solve the problem by using a different pattern, but that wouldn't answer the question.
var mymodule = (function() {
'use strict';
var async = require('async');
// var q = async.queue(mymodule.qq); // not working
// var q ; // not working
var mymodule = {
// q = async.queue(this.qq); // not working
init: function() {
// var q = async.queue(this.qq); // local not global
// q = async.queue(this.qq); // not working
q.drain = function() {
console.log('all items have been processed');
}
},
add: function(task) {
this.q.push(task);
},
qq: function(task, callback) {
console.log(task);
callback();
},
};
return mymodule;
}());
'use strict';
var async = require('async');
var mymodule = function(){
//This will be you constructor
//You can do something like this
this.queue = async.queue(function(task, callback){
console.dir(task);
}, 4);
};
//Now start adding your methods
mymodule.prototype.add = function(task){
this.queue.push(task, function(){});
};
mymodule.prototype.qq = function(task, callback){
// ..
callback()
};
//export it
module.exports = mymodule;

Not a string or buffer. Module Crypto

I created on the module util.js a function myHash() for reuse in different parts of my code but not working.
Error message: this._binding.update(data, encoding); Not a string or buffer.
app.js
...
GLOBAL.util = require('./util');
GLOBAL.dateFormat = util.dateFormat;
GLOBAL.myHash = util.myHash; /***** My function *****/
...
app.post('/test', function(req, res){
...
var pass_shasum = myHash('test');
...
util.js
var crypto = require('crypto');
function myHash(msg) {
return crypto.createHash('sha256').update(msg).digest('hex');
}
exports.util = {
...
myHash: myHash(),
...
};
Any suggestions?
Solution:
Modify util.js
var crypto = require('crypto');
/* Define var */
var myHash = function (msg) {
return crypto.createHash('sha256').update(msg).digest('hex');
};
module.exports = {
...
myHash: myHash, /* Is a variable not a method. Thanks #robertklep */
...
};
You shouldn't execute the function in your exports statement (the msg argument will be undefined which indeed is not a string or a buffer):
exports.util = {
...
myHash: myHash, // don't use myHash()
...
};
Also, when you export your code like this, you have to require it like this:
GLOBAL.util = require('./util').util;
(although I would suggest not using globals).
If you don't want the extra .util, export like this:
module.exports = {
...
myHash : myHash,
...
};

Declare multiple module.exports in Node.js

What I'm trying to achieve is to create one module that contains multiple functions in it.
module.js:
module.exports = function(firstParam) { console.log("You did it"); },
module.exports = function(secondParam) { console.log("Yes you did it"); },
// This may contain more functions
main.js:
var foo = require('module.js')(firstParam);
var bar = require('module.js')(secondParam);
The problem I have is that the firstParam is an object type and the secondParam is a URL string, but when I have that it always complains that the type is wrong.
How can I declare multiple module.exports in this case?
You can do something like:
module.exports = {
method: function() {},
otherMethod: function() {},
};
Or just:
exports.method = function() {};
exports.otherMethod = function() {};
Then in the calling script:
const myModule = require('./myModule.js');
const method = myModule.method;
const otherMethod = myModule.otherMethod;
// OR:
const {method, otherMethod} = require('./myModule.js');
To export multiple functions you can just list them like this:
module.exports = {
function1,
function2,
function3
}
And then to access them in another file:
var myFunctions = require("./lib/file.js")
And then you can call each function by calling:
myFunctions.function1
myFunctions.function2
myFunctions.function3
in addition to #mash answer I recommend you to always do the following:
const method = () => {
// your method logic
}
const otherMethod = () => {
// your method logic
}
module.exports = {
method,
otherMethod,
// anotherMethod
};
Note here:
You can call method from otherMethod and you will need this a lot
You can quickly hide a method as private when you need
This is easier for most IDE's to understand and autocomplete your code ;)
You can also use the same technique for import:
const {otherMethod} = require('./myModule.js');
module.js:
const foo = function(<params>) { ... }
const bar = function(<params>) { ... }
//export modules
module.exports = {
foo,
bar
}
main.js:
// import modules
var { foo, bar } = require('module');
// pass your parameters
var f1 = foo(<params>);
var f2 = bar(<params>);
This is just for my reference as what I was trying to achieve can be accomplished by this.
In the module.js
We can do something like this
module.exports = function ( firstArg, secondArg ) {
function firstFunction ( ) { ... }
function secondFunction ( ) { ... }
function thirdFunction ( ) { ... }
return { firstFunction: firstFunction, secondFunction: secondFunction,
thirdFunction: thirdFunction };
}
In the main.js
var name = require('module')(firstArg, secondArg);
If the files are written using ES6 export, you can write:
module.exports = {
...require('./foo'),
...require('./bar'),
};
One way that you can do it is creating a new object in the module instead of replacing it.
for example:
var testone = function () {
console.log('test one');
};
var testTwo = function () {
console.log('test two');
};
module.exports.testOne = testOne;
module.exports.testTwo = testTwo;
and to call
var test = require('path_to_file').testOne:
testOne();
You can write a function that manually delegates between the other functions:
module.exports = function(arg) {
if(arg instanceof String) {
return doStringThing.apply(this, arguments);
}else{
return doObjectThing.apply(this, arguments);
}
};
There are multiple ways to do this, one way is mentioned below.
Just assume you have .js file like this.
let add = function (a, b) {
console.log(a + b);
};
let sub = function (a, b) {
console.log(a - b);
};
You can export these functions using the following code snippet,
module.exports.add = add;
module.exports.sub = sub;
And you can use the exported functions using this code snippet,
var add = require('./counter').add;
var sub = require('./counter').sub;
add(1,2);
sub(1,2);
I know this is a late reply, but hope this helps!
use this
(function()
{
var exports = module.exports = {};
exports.yourMethod = function (success)
{
}
exports.yourMethod2 = function (success)
{
}
})();
also you can export it like this
const func1 = function (){some code here}
const func2 = function (){some code here}
exports.func1 = func1;
exports.func2 = func2;
or
for anonymous functions like this
const func1 = ()=>{some code here}
const func2 = ()=>{some code here}
exports.func1 = func1;
exports.func2 = func2;
You can use like i did below... for both functions and arrow functions :
greet.js :
function greetFromGreet() {
console.log("hello from greet module...");
}
const greetVar = () => {
console.log("greet var as a arrow fn/...");
};
module.exports = { greetVar, greetFromGreet }; // ---- multiple module export...
// -----------------------------------------------
app.js :
const greetFromGreets = require("./greet");
greetFromGreets.greetFromGreet();
greetFromGreets.greetVar();
// -----------------------------------------------
Inside your node module you can export various functions such as:
module.exports.eat = eat;
function eat() {
.......
return *something*;
};
module.exports.sleep = sleep;
function sleep() {
.......
return *something*;
};
Note that you are not calling the functions while exporting them.
Then while requiring the modules you can require as:-
const task = require(__dirname + "/task.js");
//task is the name of the file
let eat = task.eat();
let sleep = task.sleep();
Two types module import and export.
type 1 (module.js):
// module like a webpack config
const development = {
// ...
};
const production = {
// ...
};
// export multi
module.exports = [development, production];
// export single
// module.exports = development;
type 1 (main.js):
// import module like a webpack config
const { development, production } = require("./path/to/module");
type 2 (module.js):
// module function no param
const module1 = () => {
// ...
};
// module function with param
const module2 = (param1, param2) => {
// ...
};
// export module
module.exports = {
module1,
module2
}
type 2 (main.js):
// import module function
const { module1, module2 } = require("./path/to/module");
How to use import module?
const importModule = {
...development,
// ...production,
// ...module1,
...module2("param1", "param2"),
};
module1.js:
var myFunctions = {
myfunc1:function(){
},
myfunc2:function(){
},
myfunc3:function(){
},
}
module.exports=myFunctions;
main.js
var myModule = require('./module1');
myModule.myfunc1(); //calling myfunc1 from module
myModule.myfunc2(); //calling myfunc2 from module
myModule.myfunc3(); //calling myfunc3 from module
Use the export keyword
module.js
export {method1, method2}
And import them in main.js
import {method1, method2) from "./module"
If you declare a class in module file instead of the simple object
File: UserModule.js
//User Module
class User {
constructor(){
//enter code here
}
create(params){
//enter code here
}
}
class UserInfo {
constructor(){
//enter code here
}
getUser(userId){
//enter code here
return user;
}
}
// export multi
module.exports = [User, UserInfo];
Main File: index.js
// import module like
const { User, UserInfo } = require("./path/to/UserModule");
User.create(params);
UserInfo.getUser(userId);
You can use this approach too
module.exports.func1 = ...
module.exports.func2 = ...
or
exports.func1 = ...
exports.func2 = ...
Adding here for someone to help:
this code block will help adding multiple plugins into cypress index.js
Plugins -> cypress-ntlm-auth and cypress env file selection
const ntlmAuth = require('cypress-ntlm-auth/dist/plugin');
const fs = require('fs-extra');
const path = require('path');
const getConfigurationByFile = async (config) => {
const file = config.env.configFile || 'dev';
const pathToConfigFile = path.resolve(
'../Cypress/cypress/',
'config',
`${file}.json`
);
console.log('pathToConfigFile' + pathToConfigFile);
return fs.readJson(pathToConfigFile);
};
module.exports = async (on, config) => {
config = await getConfigurationByFile(config);
await ntlmAuth.initNtlmAuth(config);
return config;
};
module.exports = (function () {
'use strict';
var foo = function () {
return {
public_method: function () {}
};
};
var bar = function () {
return {
public_method: function () {}
};
};
return {
module_a: foo,
module_b: bar
};
}());

How to spy on a property that is not exported

I have a module "sitescollection" like this:
var site = require('./site'); // <- this should be stubbed
var sitesCollection = function(spec) {
var that = {};
that.sites = {};
that.findOrCreateById = function(id) {
if (typeof(that.sites[id]) == "undefined") {
that.sites[id] = site({id: id}); // <- its used here
}
return that.sites[id];
};
return that;
};
module.exports = sitesCollection;
so within sitescollection, site is a module that is not exported. But inside the code, i use it. Now i'm writing jasmine specs for #findOrCreateById().
I want to spec my the findOrCreateBy() function. But i want to stub the site() function, because the spec should be independent from the implementation. Where do i have to create the spyed method on?
var sitescollection = require('../../lib/sitescollection');
describe("#findOrCreateById", function() {
it("should return the site", function() {
var sites = sitescollection();
mysite = { id: "bla" };
// Here i want to stub the site() method inside the sitescollection module.
// spyOn(???,"site").andRetur(mysite);
expect(sites.findOrCreateById(mysite.id)).toEqual(mysite);
});
});
You can achieve this using https: //github.com/thlorenz/proxyquire
var proxyquire = require('proxyquire');
describe("#findOrCreateById", function() {
it("should return the site", function() {
// the path '../../lib/sitescollection' is relative to this test file
var sitesCollection = proxyquire('../../lib/sitescollection', {
// the path './site' is relative to sitescollection, it basically
// should be an exact match for the path passed to require in the
// file you want to test
'./site': function() {
console.log('fake version of "./site" is called');
}
});
// now call your sitesCollection, which is using your fake './site'
var sites = sitesCollection();
var mysite = {
id: "bla"
};
expect(sites.findOrCreateById(mysite.id)).toEqual(mysite);
});
});

Resources