Search⌘ K

Module Definition Patterns (II)

Explore module definition patterns in Node.js, focusing on caching mechanisms that enable shared instances similar to singletons. Understand how exporting instances works, creating new instances cautiously, and the potential risks of modifying the global scope or other cached modules. Learn when and how these patterns can be applied safely.

Exporting an instance

We can leverage the caching mechanism of require() to easily define stateful instances created from a constructor or a factory, which can be shared across different modules. The following code shows an example of this pattern:

Node.js
// file logger.js
class Logger {
constructor (name) {
this.count = 0
this.name = name
}
log (message) {
this.count++
console.log('[' + this.name + '] ' + message)
}
}
module.exports = new Logger('DEFAULT')

This newly defined module can then be used as follows:

Node.js
// main.js
const logger = require('./logger')
logger.log('This is an informational message')

Because the module is cached, every module that requires the logger module will actually always retrieve the same instance of the object, thus sharing its state. This pattern is very much like creating a singleton. However, it doesn’t guarantee the ...