Node.js双重调用require()

时间:2013-10-10 18:44:39

标签: javascript node.js

//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将输出: 333 333

但我需要输出: 222 333

换句话说,opt必须对变量lib和变量lib2唯一。如何实现?

5 个答案:

答案 0 :(得分:5)

这是因为通常nodejs会缓存通过 require 获取的模块。您可以使用以下帮助程序:

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

以及帮助者的用法:

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

请记住,这种方法被视为不良做法,不应使用。我建议将你的逻辑包装成一个函数,需要模块并调用函数。所以,每次你得到一个新的实例。

答案 1 :(得分:4)

require不会多次加载脚本,但总会产生相同的实例。

如果您需要不同的环境,请使您的模块成为允许多次实例化的构造函数。将opt存储在每个对象上而不是(全局)模块范围中。

// 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()

答案 2 :(得分:1)

NodeJS模块系统的工作方式,输出正确,您的期望与此处的设计原则相矛盾。

每个模块只加载一次,后来对require的调用只返回对预先存在的模块的引用。

也许您需要做的是创建一个类,您可以创建一个或多个实例而不是使用模块级全局变量。

答案 3 :(得分:1)

添加到Bergi的答案,您也可以尝试

// 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)
      }
    }

};

答案 4 :(得分:0)

将此行添加为lib.js

的第一行
delete require.cache[__filename]

现在,每次需要时,您的模块都会在一个单独的命名空间中。