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

↘锁芯ラ 提交于 2019-11-29 23:34:02
user568109

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.

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).

I think you can make a trick here. As far as node.js can works with shell commands, use "npm list --global" to list all intalled modules and check if needed one is presented.

var sys = require('sys')
var exec = require('child_process').exec;
var child;

// execute command
child = exec("npm list --global", function (error, stdout, stderr) {
    // TODO: search in stdout
    if (error !== null) {
        console.log('exec error: ' + error);
    }
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!