Module Caching
Here's a common interview question: "If you require the same module in multiple files, how many times is it loaded?" The answer might surprise you – **only once**! This is because Node.js caches modules after they're first loaded. Understanding this caching behavior is crucial for writing efficient code.
How Module Caching Works
When you `require()` a module for the first time, Node.js:
- Loads the file.
- Executes the code.
- Caches the result.
- Returns the cached result on subsequent `require()` calls.
Think of module caching like a library book. The first time you borrow it, you take it home. The next time you want it, you don't go buy a new copy – you just borrow the same book again.
Demonstrating Module Caching
counter.js
let count = 0;
function increment() { count++; return count;}
function getCount() { return count;}
console.log('Counter module loaded!');
module.exports = { increment, getCount };a.js
const counter = require('./counter');
console.log('In a.js, count =', counter.increment());b.js
const counter = require('./counter');
console.log('In b.js, count =', counter.increment());main.js
require('./a');require('./b');Run `node main.js`:
Counter module loaded!In a.js, count = 1In b.js, count = 2Notice: "Counter module loaded!" printed only once, and the count is shared between a.js and b.js.
Implications of Module Caching
- Singleton Pattern: Modules act as singletons – you get the same instance everywhere.
- Shared State: If a module has state (like our counter), that state is shared across all requires.
- Performance: Caching makes repeated requires fast.
When You Might Want to Avoid Caching
Sometimes you want a fresh instance each time. For example, a database connection pool or a logger with a different context. In such cases, export a **factory function** that creates new instances.
logger-factory.js
class Logger { constructor(name) { this.name = name; } log(message) { console.log(`[${this.name}] ${message}`); }}
<!-- Export a factory function, not the class itself -->module.exports = (name) => new Logger(name);app.js
const createLogger = require('./logger-factory');
const logger1 = createLogger('App1');const logger2 = createLogger('App2');
logger1.log('Hello'); <!-- [App1] Hello -->logger2.log('World'); <!-- [App2] World -->Clearing the Cache (Advanced)
You can manually clear a module from the cache, but this is rarely needed:
<!-- Get the module path -->const modulePath = require.resolve('./counter');
<!-- Delete from cache -->delete require.cache[modulePath];
<!-- Next require will load fresh -->const counter = require('./counter');Two Minute Drill
- Node.js caches modules after the first `require()`.
- The same module instance is shared across all files that require it.
- This creates a singleton pattern and enables shared state.
- Export factory functions if you need fresh instances each time.
- Caching improves performance but requires understanding for correct state management.
Need more clarification?
Drop us an email at career@quipoinfotech.com
