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