Node.js – 检查模块是否安装,而实际上并不需要它

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

我不喜欢这个想法来捕捉exception。 有没有更好的办法?

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

请参阅require.resolve文档

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

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

module.paths存储require的searchpath数组。 searchpath是相对于调用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版本:

 // 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中
  • 文档指出 ,你可以添加path,将按需扫描,但我不能让它工作(我在Windows XP上)。

我想你可以在这里制造一个诡计。 就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); } });