在node.js文档中:
模块在第一次加载后被缓存。这意味着(除其他外)每次调用require('foo')都会得到完全相同的返回对象,如果它将解析到相同的文件。
是否有一种方法使这个缓存无效?例如,对于单元测试,我希望每个测试都在一个新鲜的对象上工作。
在node.js文档中:
模块在第一次加载后被缓存。这意味着(除其他外)每次调用require('foo')都会得到完全相同的返回对象,如果它将解析到相同的文件。
是否有一种方法使这个缓存无效?例如,对于单元测试,我希望每个测试都在一个新鲜的对象上工作。
当前回答
如果是用于单元测试,另一个可以使用的好工具是proxyquire。每次你代理模块时,它都会使模块缓存失效,并缓存一个新的模块。它还允许您修改正在测试的文件所需的模块。
其他回答
是的,您可以使缓存无效。
缓存存储在一个名为require的对象中。你可以根据文件名直接访问的缓存(例如- /projects/app/home/index.js而不是你会在require('./home')语句中使用的。/home)。
delete require.cache['/projects/app/home/index.js'];
我们的团队发现以下模块很有用。使某些模块组无效。
https://www.npmjs.com/package/node-resource
我不是100%确定你说的“invalidate”是什么意思,但你可以在require语句上面添加以下语句来清除缓存:
Object.keys(require.cache).forEach(function(key) { delete require.cache[key] })
摘自@Dancrumb的评论
我做了一个小模块来删除加载后缓存中的模块。这将强制在下次需要该模块时重新计算它。参见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/
我不能在回答的注释中整齐地添加代码。但我会使用@Ben Barkay的答案,然后将其添加到require中。uncache函数。
// see https://github.com/joyent/node/issues/8266
// use in it in @Ben Barkay's require.uncache function or along with it. whatever
Object.keys(module.constructor._pathCache).forEach(function(cacheKey) {
if ( cacheKey.indexOf(moduleName) > -1 ) {
delete module.constructor._pathCache[ cacheKey ];
}
});
假设您需要一个模块,然后卸载它,然后重新安装相同的模块,但使用了不同的版本,其包中有不同的主脚本。json,下一个require将失败,因为主脚本不存在,因为它缓存在Module._pathCache中
下面是我对这个问题的回答,它处理如果文件有(例如)语法错误就不加载的问题
function reacquire(module) {
const fullpath = require.resolve(module);
const backup = require.cache[fullpath];
delete require.cache[fullpath];
try {
const newcopy = require(module);
console.log("reqcquired:",module,typeof newcopy);
return newcopy;
} catch (e) {
console.log("Can't reqcquire",module,":",e.message);
require.cache[fullpath] = backup;
return backup;
}
}