Monday, August 26, 2013

require in nodejs

Assuming this is the first time the module is being required.

For example ,

var x = require('file1.js');
contents of file1.js;
====================
module.exports = '123'

When the above statement is executed, a 'Module' object is created.
Module constructor function is provided below,

function Module(id, parent) {
    this.id = id;
    this.exports = {}; // the exports property which is actually return on require
    this.parent = parent;
    if (parent && parent.children) {
        parent.children.push(this);
    }

    this.filename = null;
    this.loaded = false;
    this.children = [];
}

As you see each module object has a property with name 'exports'.
This is what is eventually returned as part of require.

Next step of require is to wrap the contents of file1.js into an anonymous function like below :

(function (exports, require, module, __filename, __dirname) { 
    //contents from file1.js
    module.exports = '123;
});

And the above anonymous function is invoked the following way, module here refers to the Module Object created earlier.

(function (exports, require, module, __filename, __dirname) { 
    //contents from file1.js
    module.exports = '123;
}) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");

As we can see inside the function , exports formal argument refers to module.exports.
In essence its a convenience provided to the module programmer.

However this convenience need to be exercised with care.
In any case if trying to assign a new object to exports ensure we do it this way.

exports = module.exports = {};

If we do it following way wrong way, module.exports will still be pointing to the object created as part of module instance.

exports = {};

As as result adding anything to the above exports object will have no effect to module.exports object and nothing will be exported or returned as part of require.

No comments:

Post a Comment