web-dev-qa-db-ja.com

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

例外をキャッチするという考えは好きではありません。もっと良い方法はありますか?

42
AndreyM

require.resolve()の代わりにrequire()を使用する必要があります。 requireは、見つかったライブラリをロードしますが、require.resolve()はロードしません。モジュールのファイル名を返します。

require.resolveのドキュメント を参照してください

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

require.resolve()は、モジュールが見つからない場合にエラーをスローするため、処理する必要があります。

66
user568109

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 [〜#〜] にはありません
  • ドキュメント statesrequireによってスキャンされるパスを追加できるが、それを機能させることができなかった(Windows XPを使用しています)。
1
Jan Święcki