Node.js - 检查模块是否安装而不实际需要

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15302618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:47:58  来源:igfitidea点击:

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

node.jsmodulerequire

提问by AndreyM

I need to check whether "mocha" is installed, before running it. I came up with the following code:

在运行它之前,我需要检查是否安装了“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);
}

I dont like the idea to catch an exception. Is there a better way?

我不喜欢捕捉异常的想法。有没有更好的办法?

回答by user568109

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

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

See the documentation for require.resolve

请参阅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.

如果没有找到模块,require.resolve() 会抛出错误,所以你必须处理它。

回答by Jan ?wi?cki

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

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

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.pathsis not in the API
  • Documentation statesthat you can add paths that will be scanned by requirebut I couldn't make it work (I'm on Windows XP).
  • module.paths不在API 中
  • 文档说明您可以添加将被扫描的路径,require但我无法使其工作(我使用的是 Windows XP)。

回答by Stormherz

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.

我想你可以在这里耍花招。就 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);
    }
});