Node.js Module Loading from Cache

Node.js modules are not loaded everytime they are required. Modules are cached after the first time they are loaded. The cached version gets returned for subsquent require calls.

In the following example, we will create a configuration module (called config.js), to demostarte this fact.

1  // config.js
2  const config = {
3 development: {
4 port: process.env.PORT || 3000,
5 },
6 test: {
7 port: process.env.PORT || 3000,
8 },
9 };

10 module.exports = env => config[env] || config.development;

Now we will require the configuration module twice in the same code to validate the module is not loaded again in the second require.

1  // test.js
2  const assert = require('assert');

3 process.env.PORT = 5000;
4 const devConfig = require('./config')('development');

5 assert.equal(devConfig.port, 5000, 'not 5000'); // 1st test

6 process.env.PORT = 6000;
7 const testConfig = require('./config')('test');

8 assert.equal(devConfig.port, 5000, 'not 5000'); // 2nd test
9 assert.equal(testConfig.port, 5000, 'not 5000'); // 3rd test
10 assert.equal(testConfig.port, 6000, 'not 6000'); // 4th test

The 4th test fail. The result of executing test.js is shown below.

Foos-MacBook-Pro:foo$ node test.js
assert.js:81
throw new assert.AssertionError({
^
AssertionError: not 6000
at Object.<anonymous> (/Users/foo/Nodejs/test.js:10:8)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:504:3

What happened is, Node.js module system loads the configuration module at line 4 and keeps its copy inside the require function cache. When the same module is required for a second time at line 7, instead of loading the configuration module; the cached version gets returned. That is why the 3rd test is passing, while the 4th test fails.

What if the module was loaded again at line 7, the 4th test will pass.

Delete cache

We can delete a cached version of a modul as shown below in reload.js

1  // reload.js
2  const assert = require('assert');

3 process.env.PORT = 5000;
4 const devConfig = require('./config')('development');

5 assert.equal(devConfig.port, 5000, 'not 5000'); // 1st test

6 process.env.PORT = 6000;
7 delete require.cache[require.resolve('./config')];
8 const testConfig = require('./config')('test');

9 assert.equal(devConfig.port, 5000, 'not 5000'); // 2nd test
10 assert.equal(testConfig.port, 6000, 'not 6000'); // 3rd test

Now, all three tests pass.

Deleting cache could be required for testing or other reasons. For example inside the Node.js source tree deleting module is used for testing, see here test/pummel/test-crypto-timing-safe-equal-benchmarks.js.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.