在node.js文档中:

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

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


当前回答

文件说:

当需要模块时,模块缓存在这个对象中。通过从该对象中删除键值,下一个require将重新加载该模块。这不适用于本机插件,因为重新加载将导致错误。

其他回答

文件说:

当需要模块时,模块缓存在这个对象中。通过从该对象中删除键值,下一个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;
 }

}

如果你总是想重新加载你的模块,你可以添加这个函数:

function requireUncached(module) {
    delete require.cache[require.resolve(module)];
    return require(module);
}

然后使用requireUncached('./myModule')而不是require。

对于任何使用Jest的人来说,因为Jest有自己的模块缓存,所以有一个内置的函数-只要确保Jest。resetModules运行eg。每次测试后:

afterEach( function() {
  jest.resetModules();
});

在尝试使用decache后发现了这一点,就像另一个答案建议的那样。感谢安东尼·加文。

函数文档在这里。