在node.js文档中:
模块在第一次加载后被缓存。这意味着(除其他外)每次调用require('foo')都会得到完全相同的返回对象,如果它将解析到相同的文件。
是否有一种方法使这个缓存无效?例如,对于单元测试,我希望每个测试都在一个新鲜的对象上工作。
在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');
其他回答
有一个简单模块(带测试)
我们在测试代码时遇到了这个问题(删除缓存模块,以便它们可以在新鲜状态下重新使用),所以我们审查了人们在各种StackOverflow问答上的所有建议,并将一个简单的node.js模块(带测试)放在一起:
https://www.npmjs.com/package/decache
如你所料,它既适用于已发布的npm包,也适用于本地定义的模块。Windows, Mac, Linux等等。
怎么做?(使用)
用法非常简单:
安装
从npm安装模块:
NPM安装decache——save-dev
在你的代码中使用它:
// require the decache module:
const decache = require('decache');
// require a module that you wrote"
let mymod = require('./mymodule.js');
// use your module the way you need to:
console.log(mymod.count()); // 0 (the initial state for our counter is zero)
console.log(mymod.incrementRunCount()); // 1
// delete the cached module:
decache('./mymodule.js');
//
mymod = require('./mymodule.js'); // fresh start
console.log(mymod.count()); // 0 (back to initial state ... zero)
如果你有任何问题或需要更多的例子,请创建一个GitHub问题: https://github.com/dwyl/decache/issues
我将在luff的答案中再添加一行并更改参数名称:
function requireCached(_module){
var l = module.children.length;
for (var i = 0; i < l; i++)
{
if (module.children[i].id === require.resolve(_module))
{
module.children.splice(i, 1);
break;
}
}
delete require.cache[require.resolve(_module)];
return require(_module)
}
如果你总是想重新加载你的模块,你可以添加这个函数:
function requireUncached(module) {
delete require.cache[require.resolve(module)];
return require(module);
}
然后使用requireUncached('./myModule')而不是require。
以下两步程序对我来说非常有效。
在动态更改模型文件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();