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
Node.js - check if module is installed without actually requiring it
提问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
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:
编辑:注意:
回答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);
}
});

