在node.js文档中:
模块在第一次加载后被缓存。这意味着(除其他外)每次调用require('foo')都会得到完全相同的返回对象,如果它将解析到相同的文件。
是否有一种方法使这个缓存无效?例如,对于单元测试,我希望每个测试都在一个新鲜的对象上工作。
在node.js文档中:
模块在第一次加载后被缓存。这意味着(除其他外)每次调用require('foo')都会得到完全相同的返回对象,如果它将解析到相同的文件。
是否有一种方法使这个缓存无效?例如,对于单元测试,我希望每个测试都在一个新鲜的对象上工作。
当前回答
我做了一个小模块来删除加载后缓存中的模块。这将强制在下次需要该模块时重新计算它。参见https://github.com/bahmutov/require-and-forget
// random.js
module.exports = Math.random()
const forget = require('require-and-forget')
const r1 = forget('./random')
const r2 = forget('./random')
// r1 and r2 will be different
// "random.js" will not be stored in the require.cache
PS:你也可以把“自毁”放入模块本身。参见https://github.com/bahmutov/unload-me
PSS:更多的技巧与节点需要在我的https://glebbahmutov.com/blog/hacking-node-require/
其他回答
对于这个用例,重新连接非常有用,每次调用都会得到一个新实例。简单的依赖注入node.js单元测试。
Rewire为模块添加了一个特殊的setter和getter,这样您就可以修改它们的行为以进行更好的单元测试。你可能
为其他模块或全局变量(如process)注入mock 泄露私有变量 重写模块内的变量。 Rewire不会加载文件并计算内容以模拟节点的require机制。实际上,它使用节点自己的require来加载模块。因此,您的模块在测试环境中的行为与常规情况下完全相同(除了您的修改)。
对所有咖啡因成瘾者来说,这是个好消息:重新连接也适用于Coffee-Script。注意,在这种情况下CoffeeScript需要被列在你的devDependencies中。
是的,您可以使缓存无效。
缓存存储在一个名为require的对象中。你可以根据文件名直接访问的缓存(例如- /projects/app/home/index.js而不是你会在require('./home')语句中使用的。/home)。
delete require.cache['/projects/app/home/index.js'];
我们的团队发现以下模块很有用。使某些模块组无效。
https://www.npmjs.com/package/node-resource
如果你想让一个模块永远不被缓存(有时对开发有用,但记得在完成时删除它!),你可以把delete require.cache[module.id];在模块内部。
我将在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)
}
我不是100%确定你说的“invalidate”是什么意思,但你可以在require语句上面添加以下语句来清除缓存:
Object.keys(require.cache).forEach(function(key) { delete require.cache[key] })
摘自@Dancrumb的评论