How does node module cache work with factory function?

I am confused about how Node require cache works with factory function.

Suppose that I have two files, moduleA.js contains a Express route:

const express = require('express');
const router = express.Router();
const { test, sideEffectA } = require('./moduleB.js');

router.get('/', async (req, res, next) => {
module.exports = router;


let sideEffectA = 1;
const test = () => {
  let sideEffectB = 42;
  sideEffectA = sideEffectA + 1;
  sideEffectB = sideEffectB + 1;
  return {
    a: sideEffectA,

module.exports = {
  test, sideEffectA

After I send three GET request to / I get the following results:

{ a: 2, sideEffectB: 43 }
{ a: 3, sideEffectB: 43 }
{ a: 4, sideEffectB: 43 }

The result of sideEffectB makes sense to me, because it is a factory function. But I don’t understand why is a increasing with each request while console.log(sideEffectA) always get the same result 1.
What exactly is happening when the router function is executed? Where does those two values a and console.log(sideEffectA) come from?


One more closely related question: if an async function is exported, will it only execute once with an resolved or rejected promise cached? Is there any diffence between

const foo = (input) => new Promise((resolve, reject) => {
  // Resolve or reject

module.exports = foo;


const bar = async (input) => {
  // Something here

module.exports = bar;



sideEffectA in the module.exports statement is a primitive value, referenced by its variable name during import []. When imported, a primitive JS number is assigned to sideEffectA in moduleA.js – a different variable to the closure in moduleB.js – which is why moduleB.js has incrementing sideEffectA values not mirrored in moduleA.js.

Leave a Reply

Your email address will not be published. Required fields are marked *