Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unloading code/modules

Tags:

node.js

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?

like image 703
rob Avatar asked Jul 13 '11 09:07

rob


People also ask

What is module unloading?

Modules can be removed using the rmmod command but demand loaded modules are automatically removed from the system by kerneld when they are no longer being used.

What is a module in IntelliJ?

Modules allow you to combine several technologies and frameworks in one application. In IntelliJ IDEA, you can create several modules for a project and each of them can be responsible for its own framework. For more information, refer to Add frameworks (facets).

How do I close a package in IntelliJ?

Right click in the "Project" view. Select "Load/Unload modules" Select modules to load/unload and click OK button.


2 Answers

Yes, it is possible to access the module cache directly:

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

Note that if your code carries a reference to whatever was exposed by these modules you want to get rid of, it won't be cleaned up.

(As an aside: Underneath the surface, require.resolve and require.cache are just proxies to Module._resolveFilename and Module._cache respectively, with Module being the core module loader, i.e. require('module').)

like image 68
chjj Avatar answered Oct 19 '22 16:10

chjj


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.

like image 6
cSn Avatar answered Oct 19 '22 17:10

cSn