Play it Again, Sam: Reloading Node.js modules

Reloading modules in Node.js can be a bit tricky. After initially importing a module, subsequent calls to require have no effect. Looking for something along the lines of Python’s reload command I’ve arrived at this solution that allows modules to be reloaded (as well as imported the first time) with the following require.reload command.


// Import a module
var mymodule = require('./mymodule')
// After making some changes to the module, reload it
mymodule = require.reload('./mymodule')

Reloading is accomplished by searching the cache for a specific module using require.searchCache and removing that module and its children with require.uncache. The real heavy lifting is done by the call to delete require.cache[mod.id]. Below is the script for starting a modified repl that includes the additional require commands by default.


var myrepl = require("repl").start({});

/**
 * Removes a module from the cache.
 */
myrepl.context.require.uncache = function (moduleName) {
    // Run over the cache looking for the files
    // loaded by the specified module name
    myrepl.context.require.searchCache(moduleName, function (mod) {
        delete require.cache[mod.id];
    });
};

/**
 * Runs over the cache to search for all the cached files.
 */
myrepl.context.require.searchCache = function (moduleName, callback) {
    // Resolve the module identified by the specified name
    var mod = require.resolve(moduleName);

    // Check if the module has been resolved and found within
    // the cache
    if (mod && ((mod = require.cache[mod]) !== undefined)) {
        // Recursively go over the results
        (function run(mod) {
            // Go over each of the module's children and
            // run over it
            mod.children.forEach(function (child) {
                run(child);
            });

            // Call the specified callback providing the
            // found module
            callback(mod);
        })(mod);
    }
};

/*
 * Load a module, clearing it from the cache if necessary.
 */
myrepl.context.require.reload = function(moduleName) {
    myrepl.context.require.uncache(moduleName);
    return myrepl.context.require(moduleName);
};

It is worth noting that modules which start timers or initialize lazy objects might not be completely removed with the require.reload command. However, for quick hacks in non-production environments this code is a real time saver. For the full script with some additional hints check out the github gist.