Node.js - 检查是否安装了模块而没有实际需要它

时间:2013-03-08 20:20:57

标签: node.js module require

在运行之前,我需要检查是否安装了“mocha”。我想出了以下代码:

try {
    var mocha = require("mocha");
} catch(e) {
    console.error(e.message);
    console.error("Mocha is probably not found. Try running `npm install mocha`.");
    process.exit(e.code);
}

我不喜欢抓住异常的想法。还有更好的方法吗?

3 个答案:

答案 0 :(得分:65)

您应该使用require.resolve()代替require()。如果找到,require将加载库,但require.resolve()不会,它将返回模块的文件名。

请参阅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()会抛出错误,因此你必须处理它。

答案 1 :(得分:1)

module.paths存储require的搜索路径数组。搜索路径相对于调用require的当前模块。所以:

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;
}

异步版本:

// 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);
                }
            }
        });
    });
};

用法:

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

或者:

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

编辑:注意:

  • module.paths不在API
  • 文档states,您可以添加将由require扫描的路径但我无法使其正常工作(我在Windows XP上)。

答案 2 :(得分:-1)

我认为你可以在这里耍手段。至于node.js可以使用shell命令,使用“npm list --global”列出所有已安装的模块,并检查是否需要一个模块。

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);
    }
});