0

I'm getting a very odd error when I try to require a node module. To illustrate the problem here is the code I am trying to require:

module.exports = (function(){
  this.say = function(message) {
    console.log(message);
  }
})();

Now when I require this module I get 'Cannot read property 'say' of undefined when I try to use it as follows:

var person = require('./Person.js')
person.say('Hello World!');

And yet, if I define the module as follows it works fine ...

module.exports = {
    say : function(message) {
       console.log(message);
    }
};

I even tried this notation that also worked ...

module.exports = new Person();
function Person(){
  this.say = function(message) {
    console.log(message);
  }
};

Does anyone have any idea why the first notation doesn't work properly?

ra9r
  • 3,876
  • 2
  • 35
  • 48

2 Answers2

1

The reason is your first notation doesn't return anything to export.

module.exports = (function(){
  this.say = function(message) {
    console.log(message);
  }
  return this;
})();

I guess this should solve your problem.

Prashant Agrawal
  • 634
  • 8
  • 22
  • Wouldn't the use of (function() {...})() not return an instance of an object? – ra9r Feb 07 '16 at 07:33
  • Ah, no I see now what you mean. It isn't the same as invoking the new operator, but instead invokes it as a function. - Thanks! – ra9r Feb 07 '16 at 07:36
  • I guess I could also use the **new** operator as follows ... new (function(){...}). @PrashantAgrawal thanks again! – ra9r Feb 07 '16 at 07:39
  • Yeah, also see this http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript ....It gives great description how new works. – Prashant Agrawal Feb 07 '16 at 07:43
0

module.exports is an object that will be returned upon require calls for that file. So assume you want write a library that does some logic, some is private, other is public. and you want to expose only your public function to other people to invoke, what your file may look like is:

// Some require calls you maybe using in your lib
function privateFunc(s) {
  console.log(s);
}

function publicFunc(s) {
  privateFunc("new log: " + s);
}

module.exports = {
  log: publicFunc
}

You later will use it as follows:

var logger= require('myLib');
logger.log("my log");

This will output:

new log: my log

Thats maybe deeper than what you actually wanted, but it is meant to understand the flow of things

buddy123
  • 4,657
  • 8
  • 42
  • 65