在node.js文档中:

模块在第一次加载后被缓存。这意味着(除其他外)每次调用require('foo')都会得到完全相同的返回对象,如果它将解析到相同的文件。

是否有一种方法使这个缓存无效?例如,对于单元测试,我希望每个测试都在一个新鲜的对象上工作。


当前回答

以下两步程序对我来说非常有效。

在动态更改模型文件i-e 'mymodule.js'后,你需要先删除预编译的模型,然后使用require-reload重新加载它

Example:
        // Delete mongoose model
        delete mongoose.connection.models[thisObject.singular('mymodule')]

        // Reload model
        var reload = require('require-reload')(require);
        var entityModel = reload('./mymodule.js');

其他回答

您总是可以安全地删除require中的条目。缓存没有问题,即使有循环依赖。因为当你删除时,你只是删除了缓存的模块对象的引用,而不是模块对象本身,模块对象不会被GCed,因为在循环依赖的情况下,仍然有一个对象引用这个模块对象。

假设你有:

脚本a.js:

var b=require('./b.js').b;
exports.a='a from a.js';
exports.b=b;

和脚本b.js:

var a=require('./a.js').a;
exports.b='b from b.js';
exports.a=a;

当你这样做时:

var a=require('./a.js')
var b=require('./b.js')

你会得到:

> a
{ a: 'a from a.js', b: 'b from b.js' }
> b
{ b: 'b from b.js', a: undefined }

现在如果你编辑你的b.js:

var a=require('./a.js').a;
exports.b='b from b.js. changed value';
exports.a=a;

和做的事:

delete require.cache[require.resolve('./b.js')]
b=require('./b.js')

你会得到:

> a
{ a: 'a from a.js', b: 'b from b.js' }
> b
{ b: 'b from b.js. changed value',
  a: 'a from a.js' }

===

如果直接运行node.js,上述语句有效。然而,如果使用的工具有自己的模块缓存系统,比如jest,正确的语句应该是:

jest.resetModules();

以下两步程序对我来说非常有效。

在动态更改模型文件i-e 'mymodule.js'后,你需要先删除预编译的模型,然后使用require-reload重新加载它

Example:
        // Delete mongoose model
        delete mongoose.connection.models[thisObject.singular('mymodule')]

        // Reload model
        var reload = require('require-reload')(require);
        var entityModel = reload('./mymodule.js');

如果你想让一个模块永远不被缓存(有时对开发有用,但记得在完成时删除它!),你可以把delete require.cache[module.id];在模块内部。

我不是100%确定你说的“invalidate”是什么意思,但你可以在require语句上面添加以下语句来清除缓存:

Object.keys(require.cache).forEach(function(key) { delete require.cache[key] })

摘自@Dancrumb的评论

解决方法是:

delete require.cache[require.resolve(<path of your script>)]

对于那些像我一样在这方面有点新手的人,这里有一些基本的解释:

假设你在根目录下有一个虚拟example.js文件:

exports.message = "hi";
exports.say = function () {
  console.log(message);
}

然后像这样要求():

$ node
> require('./example.js')
{ message: 'hi', say: [Function] }

如果你在example.js中添加如下一行:

exports.message = "hi";
exports.say = function () {
  console.log(message);
}

exports.farewell = "bye!";      // this line is added later on

并在控制台中继续,该模块没有更新:

> require('./example.js')
{ message: 'hi', say: [Function] }

这时你可以使用delete require.cache[require.resolve()]在luff的回答中指出:

> delete require.cache[require.resolve('./example.js')]
true
> require('./example.js')
{ message: 'hi', say: [Function], farewell: 'bye!' }

因此缓存被清理,require()再次捕获文件的内容,加载所有当前值。