卸载代码/模块

时间:2011-07-13 09:09:33

标签: node.js

我很好奇是否有任何好方法在使用后卸载模块。我有些情况下我需要使用带来大量代码的模块,但很少使用它们(比如作为管理工具),但我不愿意使用它们,因为之后它们可能只是浪费内存可能会更好用于别处。是否有任何方法可以显式地卸载它们,或者允许系统在没有使用一段时间时这样做?

2 个答案:

答案 0 :(得分:70)

是的,可以直接访问模块缓存:

var name = require.resolve('moduleName');
delete require.cache[name];

请注意,如果您的代码带有您想要删除的这些模块所公开的内容的引用,则不会将其清除。

(顺便说一句:在表面之下,require.resolverequire.cache只是Module._resolveFilenameModule._cache的代理,Module是核心模块loader,即require('module')。)

答案 1 :(得分:3)

您可以执行以下操作来“卸载”节点模块:

/**
 * Deletes a node module and all associated children
 * from node require cache
 * @param {string} moduleName The name of the module or 
 *                            absolute/relative path to it
 */
function deleteModule(moduleName) {
  var solvedName = require.resolve(moduleName),
    nodeModule = require.cache[solvedName];
  if (nodeModule) {
    for (var i = 0; i < nodeModule.children.length; i++) {
      var child = nodeModule.children[i];
      deleteModule(child.filename);
    }
    delete require.cache[solvedName];
  }
}

“卸载”节点模块意味着您从节点要求缓存中“删除”其条目。上面的代码片段可以从缓存和所有相关模块(子模块)中传递删除一个节点模块。

在我的情况下,我要求“index.js”,同时需要“/lib/.js”。我想测试“index.js”的初始化(因此其中唯一需要的其他模块是/lib/.js)。从缓存中删除“index.js”是不够的,因为缓存维护了对“/lib/.js”的单独引用,导致模块“/lib/.js”不再从其文件中加载。

上面的代码肯定会从缓存中删除此模块所依赖的其他模块(这实际上是我想要的但是你可能不想对其他模块这样做,比如“fs”,“path”甚至“下划线”) 。

您始终可以扩展此方法以接受您不想删除的模块列表,或者可以应用于已解析模块的“路径”的过滤器。您可以说:不要删除核心节点模块(核心节点模块名称列表可用作npm包:https://www.npmjs.com/package/node-core-module-names)或不删除node_modules等下的任何软件包等。这可能是函数内部的过滤器,但它是相同的逻辑。