在node.js文档中:

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

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


当前回答

有一个简单模块(带测试)

我们在测试代码时遇到了这个问题(删除缓存模块,以便它们可以在新鲜状态下重新使用),所以我们审查了人们在各种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。

解决方法是:

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()再次捕获文件的内容,加载所有当前值。

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

在动态更改模型文件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');

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

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

摘自@Dancrumb的评论