1

Say for example I have two files A.js and B.js that both do this :

var some_package = require('some_package');

I call A.doSomething() and B.doSomething(), in both files, the same instance is used - therefore altering states inside "some_package" - I didn't want that to happen.

What I want to do is create a separate instance of some_package in A and B. is that possible despite the module caching of node.js?

Jekk
  • 577
  • 8
  • 27
  • Can you change `some_package`? Or wrap it in your own module that uses `some_package` in such a way that it has no such issues (e.g. create instance by invoking a constructor?) – Xeon Jul 16 '15 at 22:21
  • Yes I can. But in our company conventions, we are discouraged to create object styled modules. Plus, it's also great to find out if this truly is possible (disabling the cache for one module to create a separate instance) – Jekk Jul 16 '15 at 22:59

1 Answers1

1

A.doSomething() and B.doSomething() will only affect the required module's state if the function doSomething accesses an internal module scope variable. e.g.

// some_package.js
var moduleScopeVariable = 0;  // acts like a global for this module

exports.doSomething = function() {
  return ++moduleScopeVariable; // will change moduleScopeVariable for everyone
};

One way around this is to expose a constructor function instead, put the state in the instance object, and make sure not to access any module scope vars in doSomething.

// some_package.js
exports.Doer = function() {
  this.objectScopeVariable = 0;
  this.doSomething = function() {
    return ++this.objectScopeVariable;
  }
}

// test
var A = require("some_package.js");
var doer = new A.Doer();
doer.doSomething();

One other way is just keep state control within the module and tie the state to the function

// A.js and B.js
var somePackage = require("some_package.js");
var myContext = {
   localState: 0
};

// change doSomething to accept the context
somePackage.doSomething(myContext);

// or use bind to bind the context to a new function
var myDoSomething =  somePackage.doSomething.bind(myContext);

Lastly, its possible to invalidate the require cache but its not a good idea. See node.js require() cache - possible to invalidate?

Community
  • 1
  • 1
longplay
  • 206
  • 3
  • 7
  • Agreed to do solution #1 as compromisory work. For the sake of science, also tried solution B. Both patterns work fine. :) – Jekk Jul 20 '15 at 01:03