Custom module in Node.js - 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?

Related

Send a function, module to main via object Function node.js

I work on a server in node.js, and i'm quite new to the concept.
I'm using socket.io to communicate with clients
I have many modules in my server and i try to send a function declared in a module to my main. I don't want to use exports.plugin=plugin because I try to work with the observer pattern.
I tried :
In main.js:
//Modules NPM
var express = require('express');
var observer = require('node-observer');
//Extensions JS
var mymodule = require('./mymodule');
var plugin = require('./plugin');
//Initialisation
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
...
socket.on('message', function (var1, var2) { //Come from client
socket.var1=var1;
socket.var2=var2;
observer.send(this, "Message", "varSpecification");
});
In plugin.js :
//Modules NPM
var express = require('express');
var observer = require('node-observer');
//Extensions JS
var mymodule = require('./mymodule');
var main = require("./main");
...
observer.subscribe(this, "Message", function(who, data) {
var functionToSend= new Function ("varA", "varB" ,"mymodule.function(varA, varB); socket.emit('messageOK');"); //I can't create a real function because i don't use socket.io in the module Plugin
observer.send(this, "Response", functionToSend); });
Back to the main:
observer.subscribe(this, "Response", function(who, functionReceived) {
functionReceived(socket.var1, socket.var2); //Doesn't work
});
The problem is that when I execute the function in main.js, it doesn't find mymodule and can't execute the function associated.
(ReferenceError : mymodule is not defined)
When i execute the function directly in the main.js, it works.
observer.subscribe(this, "Response", function(who, functionReceived) {
mymodule.function(socket.var1, socket.var2); //Works
});
So I guess it's a problem with the object that I send
I will be more than grateful if you can help me!
EDIT : After other tests I found the source of the problem :
var mymodule = require('./mymodule');
...
mymodule.function(a, b); //works
var functionTest= new Function('mymodule.function(a, b)');
functionTest(); //Doesn't work (mymodule is not defined)
I still want to use the second option for my project but don't know how
I used the function constructor, and i didn't know that the function is declared in the global scope.
So i had to write this to make it work :
var functionTest= new Function('mymodule', 'a', 'b','mymodule.function(a, b)');
functionTest(mymodule,a,b);
I had to pass mymodule, a and b in parameter

nodejs require statement issue

I'm new to nodejs. I have the following files and code:
// file: myfunc.js
function myfunc() { return "myfunc()"; }
exports = myfunc;
and
// file: index.js
var mf = require("./myfunc");
var mfunc = mf();
console.log(mfunc);
When I run node index.js from command line, I get the error
var mfunc = mf()
^
TypeError: Object is not a function
Why do I get this error? I saw someone else's code which I paste below and I tried to follow the same approach of trying to get require() to return a function instead of an object.
// file: index.js from another app
var express = require('express');
var app = express();
How come require('express') can return a function but require('./myfunc') can't return a function?
It should be...
module.exports = myfunc;
... instead. Quoting the doc:
If you want the root of your module's export to be a function (such as
a constructor) or if you want to export a complete object in one
assignment instead of building it one property at a time, assign it to
module.exports instead of exports.

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

How to stub out express after you require it with jasmine?

I'm trying to get the code below under test when occurred to me that I already included express at the top of this file. Can you some how monkey patch the express object after it's already loaded?
var express = require('express')
Helper = (function() {
var HelperObject = function(params) {
this.directories = params.directories;
};
HelperObject.prototype.addStaticPath = function(app) {
for(i = 0; i < this.directories.length; i++) {
var static = express.static('/public');
app.use(static);
}
};
return HelperObject;
})();
The problem is that when you create a node module the required modul is bound in the closure of the module and you can't start spying on it cause it isn't visible in your test.
There is Gently where you can override require but it will sprinkle your code with boilerplate test related code.
From the docs:
Returns a new require functions that catches a reference to all
required modules into gently.hijacked.
To use this function, include a line like this in your 'my-module.js'.
if (global.GENTLY) require = GENTLY.hijack(require);
var sys = require('sys');
exports.hello = function() {
sys.log('world');
};
Now you can write a test for the module above:
var gently = global.GENTLY = new (require('gently'))
, myModule = require('./my-module');
gently.expect(gently.hijacked.sys, 'log', function(str) {
assert.equal(str, 'world');
});
myModule.hello();

Node.js with external jQuery file

I'm having an issue utilizing an external jQuery file with node. I have several functions that I need to run but it isn't working. I created a simple function to test but the error message I keep getting is TypeError: Object # has no method 'alert_helloworld'. Here are my two files:
example.js
var jsdom = require('jsdom');
var templateparser = require('./templateparser.js');
var test = templateparser.alert_helloworld();
templateparser.js
function alert_helloworld(){
console.log("Hello World");
return false;
}
HELP!!!!
You need to use the exports object in templateparser.js:
exports = exports || {};
exports.alert_helloworld = function(){
console.log("Hello World");
return false;
}
Take a look at the modules docs: http://nodejs.org/docs/latest/api/modules.html
module.exports.alert_helloworld = function alert_helloworld(){
console.log("Hello World");
return false;
};
It's important you actually export the functions you need. node.js modules by default are wrapped in their own isolated module scope.

Resources