如何在 node.js 中的“require”之后删除模块?
Posted
技术标签:
【中文标题】如何在 node.js 中的“require”之后删除模块?【英文标题】:How to remove module after "require" in node.js? 【发布时间】:2013-03-17 23:09:02 【问题描述】:假设我需要一个模块并执行以下操作:
var b = require('./b.js');
--- do something with b ---
然后我想带走模块 b(即清理缓存)。我该怎么做?
原因是我想在不重新启动节点服务器的情况下动态加载/删除或更新模块。有什么想法吗?
------- 更多 -------- 根据删除require.cache的建议,还是不行……
what I did are few things:
1) delete require.cache[require.resolve('./b.js')];
2) loop for every require.cache's children and remove any child who is b.js
3) delete b
但是,当我调用 b 时,它仍然存在!它仍然可以访问。除非我这样做:
b = ;
不确定这是否是处理该问题的好方法。 因为如果以后,我需要 ('./b.js') 在 b.js 已被修改时再次。它需要旧的缓存 b.js(我试图删除)还是新的?
-----------更多发现--------------
好的。我做了更多的测试和代码玩弄..这是我发现的:
1) delete require.cache[] is essential. Only if it is deleted,
then the next time I load a new b.js will take effect.
2) looping through require.cache[] and delete any entry in the
children with the full filename of b.js doesn't take any effect. i.e.
u can delete or leave it. However, I'm unsure if there is any side
effect. I think it is a good idea to keep it clean and delete it if
there is no performance impact.
3) of course, assign b= doesn't really necessary, but i think it is
useful to also keep it clean.
【问题讨论】:
您将require('./b')
的结果分配给的变量不会被删除,delete
操作将只允许您第二次请求文件而不会获得缓存版本,但变量会赢当你更新时不会神奇地更新。
是的..你是对的..这是我发现的......(见我的版本)
node.js require() cache - possible to invalidate? 的可能重复项
【参考方案1】:
花了一些时间尝试在 Vuex 商店的 Jest 测试中清除缓存,但没有成功。似乎 Jest 有自己的机制,不需要手动调用来删除 require.cache。
beforeEach(() =>
jest.resetModules();
);
和测试:
let store;
it("1", () =>
process.env.something = true;
store = require("@/src/store.index");
);
it("2", () =>
process.env.something = false;
store = require("@/src/store.index");
);
两个商店将是不同的模块。
【讨论】:
【参考方案2】:我发现这对客户端应用程序很有用。我想根据需要导入代码,然后在完成后将其垃圾收集。这似乎有效。我不确定缓存,但一旦不再引用 module
和 CONTAINER.sayHello
已被删除,它应该会被垃圾收集。
/* my-module.js */
function sayHello console.log("hello");
export sayHello ;
/* somewhere-else.js */
const CONTAINER = ;
import("my-module.js").then(module =>
CONTAINER.sayHello = module.sayHello;
CONTAINER.sayHello(); // hello
delete CONTAINER.sayHello;
console.log(CONTAINER.sayHello); // undefined
);
【讨论】:
【参考方案3】:最简单的方法之一(尽管在性能方面不是最好的,因为即使是不相关的模块的缓存也会被清除)是简单地清除缓存中的每个模块
请注意,清除 *.node
文件(本机模块)的缓存可能会导致未定义的行为,因此不受支持 (https://github.com/nodejs/node/commit/5c14d695d2c1f924cf06af6ae896027569993a5c),因此需要一个 if 语句来确保不会从缓存也是。
for (const path in require.cache)
if (path.endsWith('.js')) // only clear *.js, not *.node
delete require.cache[path]
【讨论】:
【参考方案4】:我发现处理使缓存失效的最简单方法实际上是重置暴露的缓存对象。从缓存中删除单个条目时,子依赖项的迭代变得有点麻烦。
require.cache = ;
【讨论】:
根据this answer 更改缓存对象没有任何作用,您需要删除其键 这是错误的,只删除key实际上是删除了缓存的模块。【参考方案5】:您可以使用它来删除它在缓存中的条目:
delete require.cache[require.resolve('./b.js')]
require.resolve()
会计算出./b.js
的完整路径,用作缓存键。
【讨论】:
哦..让我试试。所以完整路径是 module.filename? 试试吧。我认为这比仅仅删除更复杂。做删除删除***缓存。但是,因为b.js是a.js的一个child,所以它也作为一个child缓存在a.js中。所以,我想我还需要删除 a.js 的孩子 请注意,您可能还需要删除./b.js
所需的所有内容。根据您的用例,核选项可能是合适的:_.each(_.keys(require.cache), function (key) delete require.cache[key];)
我想这就是我需要的。我的 js 没有在浏览器中执行,并且热重载没有更新它。我在哪里以及如何输入这个delete require.cache[require.resolve('./b.js')]
?
@Krys 这是专门为 Node.js 设计的以上是关于如何在 node.js 中的“require”之后删除模块?的主要内容,如果未能解决你的问题,请参考以下文章
node.js 中的 module.parent 有啥用?如何引用 require()ing 模块?
node.js 中的 require('dotenv').config()