unloading code/modules

Viewed 19986

I'm curious if there is any good way to unload a module after using it. I have some cases where I need to use modules that bring in a lot of code, but they are used rarely (say as an admin tool), but I hesitate to use them because afterwards they'll presumably just waste memory that could be better used elsewhere. Is there any way to unload them, either explicitly or by allowing the system to do so when they haven't been used for a while?

2 Answers

You can do something like this to "unload" a node module:

/**
 * 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];
  }
}

"Unloading" a node module means that you're "deleting" its entry from node require cache. The snippet above transitively deletes one node module from the cache and all the associated modules (children modules).

In my case I was requiring "index.js" that, at the same time, was requiring "/lib/.js". I wanted to test initialization of "index.js" (and therefore the only other module being required in there which was /lib/.js). Deleting "index.js" from the cache was not enough because the cache maintained a separate reference to "/lib/.js" and that caused the module "/lib/.js" to not be loaded again from its file.

The code above might certainly delete from the cache other modules this module depends on (this is actually what I wanted BUT you might not want to do this for other modules like "fs", "path" or even "underscore").

You can always extend this method to accept a list of modules you don't want to delete or a filter you could apply to the "path" of the resolved module. You can say: don't delete core node modules (a list of core node modules names is available as a npm package: https://www.npmjs.com/package/node-core-module-names) or don't delete any of the packages under node_modules, etc etc.. This could be a filter inside the function but it's the same logic.

Related