Caching of Modules in NodeJS
In this post, I am talking about caching of Modules in NodeJS.
We have the following files
1 2 3 4 5 6 7 | //greet.js module.exports = { greeting: "Hello!" , greet: function (){ console.log(this.greeting); } } |
01 02 03 04 05 06 07 08 09 10 | //app.js var greet1 = require ( "./module/greet" ); greet1.greet(); greet1.greeting = "Yooo!" ; greet1.greet(); var greet2 = require ( "./module/greet" ); greet2.greet(); |
On executing node app.js
, on first glance, we’d expect the output to be:
1 2 3 | Heyyyyyy? Yooo! Heyyyyyy? |
Our logic is that greet2.greet()
would print “Heyyyyyy?” because it’ll get a fresh copy of module.export from greet.js file.
But on the contrary, the output of the above program is:
1 2 3 | Heyyyyyy? Yooo! Yooo! |
So what actually happens is that – when greet1
function calls require("./module/greet")
function, a new module for greet.js
is created and compiled. After compilation and before returning node stores the cached copy of module.exports
in the variable cachedModule.exports
, and then returns module.exports
Since objects in Javascript are passed by reference, cachedModule.exports
points towards the same location in memory where greet1
points at. Now when we made a change to greet1
by mutating the greeting
property, cachedModule.exports
too changes because ultimately both cachedModule.exports
and greet1
are the same. They point to the same object.
So now when greet2
calls the require("./module/greet")
function, instead of recompiling greet.js
, node checks if there’s a cached copy of module.exports.
If found, it returns it and hence saves time which would’ve got lost in recompiling greet.js
.
So greet2
essentially gets the same object which is pointed towards by greet1
. This is the reason greet2.greeting()
prints “Yooo!”.
Node also provides a feature to delete the stored cache. It’s done by executing the following statement:
1 | delete require .cache[ require .resolve(module)] |
So if one wants to always reload the module, he can add this function:
1 2 3 4 | function requireUncached(module){ delete require .cache[ require .resolve(module)] return require (module) } |
Takeaways from this lesson:
Whenever a module is required, node checks if there exists cached copy of its module.exports. If exists it returns the cached copy, otherwise it compiles that module and makes cached copy of its module.exports and then returns module.exports.
Published on Web Code Geeks with permission by Himnash Jain, partner at our WCG program. See the original article here: Caching of Modules in NodeJS Opinions expressed by Web Code Geeks contributors are their own. |