Node modules are each in their own scope. By default, nothing in module a
is visible to module b
. Doing a require()
on a module is NOT like including the source. It loads the file runs the code and then the only things that are available to the outside world are:
- Any functions or properties that are explicitly exported from the module by assigning to
module.exports
.
- Any functions or properties that are explicitly assigned to the
global
object in node.
So, if you want something in b.js
to be exposed to the outside world, you do like this:
// b.js
module.exports.callMe = function() {
console.log("I'm in module b");
}
And, then in a.js
, you can do this:
// a.js
var b = require('./b.js');
b.callMe();
This is how the module system works in node.js. It is very different than just including a <script>
tag in a browser web page. You can read more about the module system in these references:
Understanding module.exports and exports in Node.js
What is the purpose of Node.js module.exports and how do you use it?
Node.js Handbook - How require()
Actually Works
Internally, node.js loads a module's code and then inserts it into a wrapper function. So, each top level variable in a node module is actually only a local variable in that module function. This is why nothing is globally declared or shared by default. It is done this way on purpose so that each module comes with it's own private area for storing it's state and will not, by default, interfere with the variables of any other module.
You then explicitly export only the property/function interfaces that you want to make public and even then, they are still not exported as public symbols so again they cannot conflict with anything else.
So, the b.js code above actually gets transformed into this when node.js runs it:
(function (exports, module, require, __filename, __dirname){
module.exports.callMe = function() {
console.log("I'm in module b");
}
})(...);
The (...)
contains actual variables that are passed to the module.