Search⌘ K

CommonJS Modules

Explore the structure and behavior of CommonJS modules in Node.js. Understand how the require() function loads modules synchronously, how exports and module.exports define a module's public API, and the caching mechanism that optimizes module loading. This lesson helps you grasp the internals of Node.js module loading and design patterns for effective module definition.

CommonJS is the first module system originally built into Node.js. Node.js’ CommonJS implementation respects the CommonJS specification, with the addition of some custom extensions.

Let’s summarize two of the main concepts of the CommonJS specification:

require() is a function that allows us to import a module from the local filesystem.

exports and module.exports are special variables that can be used to export public functionality from the current module.

A homemade module loader

To understand how CommonJS works in Node.js, let’s build a similar system from scratch. The following code creates a function that mimics a subset of the functionality of the original require() function of Node.js.

Let’s start by creating a function that loads the content of a module, wraps it into a private scope, and evaluates it:

Node.js
function loadModule(filename, module, require) {
const wrappedSrc =
`(function (module, exports, require) {
${fs.readFileSync(filename, 'utf8')}
})(module, module.exports, require)`
eval(wrappedSrc)
}

The source code of a module is essentially wrapped into a function, as it was for the revealing module pattern. The difference here is that we pass a list of variables (module, exports, and require) to the module. Make a note of how the exports argument of the wrapping function is initialized with the content of module.exports (we’ll talk more about this later.)

Another important detail to mention is that we’re using ...