admin管理员组

文章数量:1336631

//lib.js
var opt = 0

exports.set = function(arg) {
   opt = arg
}

exports.prn = function() {
   console.log(opt)
}


///prog.js
var lib = require('./lib')
var lib2 = require('./lib')
lib.set(222)
lib2.set(333)
lib.prn()
lib2.prn()

prog.js will output: 333 333

but I need it to output: 222 333

In ohter words, opt must be unique to variable lib and to variable lib2. How to achieve that?

//lib.js
var opt = 0

exports.set = function(arg) {
   opt = arg
}

exports.prn = function() {
   console.log(opt)
}


///prog.js
var lib = require('./lib')
var lib2 = require('./lib')
lib.set(222)
lib2.set(333)
lib.prn()
lib2.prn()

prog.js will output: 333 333

but I need it to output: 222 333

In ohter words, opt must be unique to variable lib and to variable lib2. How to achieve that?

Share Improve this question asked Oct 10, 2013 at 18:44 exebookexebook 34k42 gold badges152 silver badges241 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5

That's because normally nodejs caches its modules which are got via require. You may use the following helper:

// RequireUncached.js
module.exports = function(module) {
    delete require.cache[require.resolve(module)]
    return require(module);
}

and the usage of the helper:

var requireUncached = require('RequireUncached.js');
requireUncached("./lib"); 

Have in mind that this approach is considered as bad practice and should not be used. I'll suggest to wrap your logic into a function, require the module and call the function. So, every time you get a new instance.

require will not load scripts multiple times, but always yield the same instance.

If you need different environments, make your module a constructor function that allows to be instantiated multiple times. Store opt on each object for that instead of in the (global) module scope.

// lib.js
module.exports = function constr() {
    var opt = 0
    this.set = function(arg) {
       opt = arg
    };
    this.print = function() {
       console.log(opt)
    };
};

// prog.js
var lib = require('./lib'),
    inst1 = new lib(),
    inst2 = new lib();
/* or short:
var inst1 = new require('./lib')(),
    inst2 = new require('./lib')(); */
inst1.set(222)
inst2.set(333)
inst1.print()
inst2.print()

The way the NodeJS module system works, the output is correct and your expectations contradict the design principle here.

Each module is loaded once and only once, and subsequent calls to require simply return the reference to the pre-existing module.

Maybe what you need to do is create a class you can create one or more instances of instead of using module-level globals.

Adding to Bergi's answer, You may also try it like

// prog.js
var lib = require('./lib')(),
lib2 = require('./lib')();
lib.set(222)
lib2.set(333)
lib.print()
lib2.print()

// lib.js
module.exports = function constr() {
    var opt = 0

    return { set : function(arg) {
       opt = arg
      },
      print : function() {
       console.log(opt)
      }
    }

};

Add this line as first line of your lib.js

delete require.cache[__filename]

now your module bees in a separate namespace each time you require it.

本文标签: javascriptNodejs double call to require()Stack Overflow