“之后如何卸下模块”;要求;在node.js中?

“之后如何卸下模块”;要求;在node.js中?,node.js,module,require,Node.js,Module,Require,比如说,在我需要一个模块并执行以下操作后: var b = require('./b.js'); --- do something with b --- 然后我想带走模块b(即清理缓存)。我怎么能做到 原因是我希望在不重新启动节点服务器的情况下动态加载/删除或更新模块。有什么想法吗 -------更多-------- 根据删除require.cache的建议,它仍然不起作用 what I did are few things: 1) delete require.cache[require.r

比如说,在我需要一个模块并执行以下操作后:

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.resolve()
将计算出用作缓存键的
/b.js
的完整路径。

我发现处理缓存无效的最简单方法实际上是重置公开的缓存对象。当从缓存中删除单个条目时,子依赖项迭代起来会有点麻烦

require.cache={}最简单的方法之一(虽然在性能方面不是最好的,因为即使是不相关的模块的缓存也会被清除),就是简单地清除缓存中的每个模块

请注意,清除
*.node
文件(本机模块)的缓存可能会导致未定义的行为,因此不受支持(),因此需要有一个if语句来确保这些文件不会从缓存中删除

    for (const path in require.cache) {
      if (path.endsWith('.js')) { // only clear *.js, not *.node
        delete require.cache[path]
      }
    }

我发现这对于客户端应用程序很有用。我想在需要时导入代码,然后在完成时对其进行垃圾收集。这似乎奏效了。我不确定缓存是否正确,但一旦不再引用
模块
容器,它应该会被垃圾收集。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

});

花了一些时间试图清除Vuex商店的缓存测试,但运气不佳。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");
});

两个存储区将是不同的模块。

Oh。。让我试试。那么完整路径将是module.filename?请尝试。我认为这比删除更复杂。执行删除操作以删除顶级缓存。但是,因为b.js是a.js的子级,所以它也作为子级缓存在a.js中。因此,我认为我还需要删除a.js的子项注意,您可能还需要删除
/b.js
所需的所有内容。根据您的用例,核选项可能是合适的:
.each(uu.keys(require.cache)、function(key){delete require.cache[key];})
分配给
require('./b')
的结果的变量不会被删除,
delete
操作只允许您第二次需要一个文件,而不需要获取缓存版本,但这样做时变量不会神奇地更新。是的。。你说得对。。这是我发现的。。。(请参阅我的版本)根据更改缓存对象,可能的重复不会产生任何作用,您需要删除其密钥。这是错误的,仅删除密钥实际上会删除缓存模块。
let store;

it("1", () => {
   process.env.something = true;
   store = require("@/src/store.index");
});

it("2", () => {
   process.env.something = false;
   store = require("@/src/store.index");
});