Node.js - check if module is installed without actually requiring it [duplicate]

Solution 1:

You should use require.resolve() instead of require(). require will load the library if found, but require.resolve() will not, it will return the file name of the module.

See the documentation for require.resolve

try {
    console.log(require.resolve("mocha"));
} catch(e) {
    console.error("Mocha is not found");
    process.exit(e.code);
}

require.resolve() does throw error if module is not found so you have to handle it.

Solution 2:

module.paths stores array of search paths for require. Search paths are relative to the current module from where require is called. So:

var fs = require("fs");

// checks if module is available to load
var isModuleAvailableSync = function(moduleName)
{
    var ret = false; // return value, boolean
    var dirSeparator = require("path").sep

    // scan each module.paths. If there exists
    // node_modules/moduleName then
    // return true. Otherwise return false.
    module.paths.forEach(function(nodeModulesPath)
    {
        if(fs.existsSync(nodeModulesPath + dirSeparator + moduleName) === true)
        {
            ret = true;
            return false; // break forEach
        }
    });

    return ret;
}

And asynchronous version:

// asynchronous version, calls callback(true) on success
// or callback(false) on failure.
var isModuleAvailable = function(moduleName, callback)
{
    var counter = 0;
    var dirSeparator = require("path").sep

    module.paths.forEach(function(nodeModulesPath)
    {
        var path = nodeModulesPath + dirSeparator + moduleName;
        fs.exists(path, function(exists)
        {
            if(exists)
            {
                callback(true);
            }
            else
            {
                counter++;

                if(counter === module.paths.length)
                {
                    callback(false);
                }
            }
        });
    });
};

Usage:

if( isModuleAvailableSync("mocha") === true )
{
    console.log("yay!");
}

Or:

isModuleAvailable("colors", function(exists)
{
    if(exists)
    {
        console.log("yay!");
    }
    else
    {
        console.log("nay:(");
    }
});

Edit: Note:

  • module.paths is not in the API
  • Documentation states that you can add paths that will be scanned by require but I couldn't make it work (I'm on Windows XP).