We've already seen a couple of examples of this module format, with the simple.js example, and the programs we examined in Chapter 2, Setting up Node.js. So let's take a closer look.
CommonJS modules are stored in files with the extension .js.
Loading a CommonJS module is a synchronous operation. That means that when the require('modulename') function call returns, the module has been located and completely read into memory and is ready to go. The module is cached in memory so that subsequent require('modulename') calls return immediately, and all return the exact same object.
Node.js modules provide a simple encapsulation mechanism to hide implementation details while exposing an API. Modules are treated as if they were written as follows:
(function() { ... contents of module file ... })();
Thus, everything within the module is contained within an anonymous private namespace context. This is how the global object problem is resolved; everything in a module that looks global is actually contained within this private context.
Objects and functions can be exposed from a CommonJS module by means of two free variables Node.js inserts into this private context: module and exports:
- The module object contains several fields that you might find useful. Refer to the online Node.js documentation for details.
- The exports object is an alias of the module.exports field. This means that the following two lines of code are equivalent:
exports.funcName = function(arg, arg1) { ... };
module.exports.funcName = function(arg, arg2) { .. };
Your code can break the alias between the two if you do this:
exports = function(arg, arg1) { ... };
Do not do that, because exports will no longer be equivalent to module.exports. If your intent is to assign a single object or function to be what's returned by require, do this instead:
module.exports = function(arg, arg1) { ... };
Some modules do export a single function because that's how the module author envisioned delivering the desired functionality.