web-dev-qa-db-ja.com

Node.JS:requireを介して呼び出されたか、コマンドラインで直接呼び出されたかを検出

Node.JSファイルがSH:node path-to-fileまたはJS:require('path-to-file')を使用して呼び出されたかどうかを検出するにはどうすればよいですか?

これは、Perlでの以前の質問と同等のNode.JSです: requireでロードされていない場合にのみPerlスクリプトを実行するにはどうすればよいですか?

267
Bryan Field
if (require.main === module) {
    console.log('called directly');
} else {
    console.log('required as a module');
}

こちらのドキュメントを参照してください: https://nodejs.org/docs/latest/api/modules.html#modules_accessing_the_main_module

410
nicolaskruchten

もう1つ、少し短い方法があります(言及されたドキュメントには記載されていません)。

var runningAsScript = !module.parent;

このブログ投稿 で、これらすべてが内部でどのように機能するかについての詳細を概説しました。

80
Thorsten Lorenz

説明で使用される用語に少し混乱しました。そのため、いくつかの簡単なテストを行う必要がありました。

これらの結果は同じであることがわかりました。

var isCLI = !module.parent;
var isCLI = require.main === module;

そして、他の混乱した人々のために(そして質問に直接答えるために):

var isCLI = require.main === module;
var wasRequired = !isCLI;
4
bob

ES6モジュールを使用している場合は、これを試してください。

if (process.mainModule.filename === __filename) {
  console.log('running as main module')
}
3
Kebot

Pythonと同じように、私はいつもこのひどいコードスニペットの書き方を思い出そうとしています。それで、私はそれのために簡単なモジュールを作成することにしました。呼び出し元のモジュール情報にアクセスするのは簡単ではないため、開発には少し時間がかかりましたが、それがどのように行われるかを見るのは楽しかったです。

そのため、モジュールを呼び出して、呼び出し元モジュールがメインモジュールであるかどうかを確認します。呼び出し元関数のモジュールを把握する必要があります。私の最初のアプローチは、受け入れられた答えのバリエーションでした:

module.exports = function () {
    return require.main === module.parent;
};

しかし、それが機能するとは限りません。 module.parentは、私たちを呼び出しているモジュールではなく、メモリにロードするモジュールを指します。このヘルパーモジュールをメモリにロードしたのが呼び出し元モジュールである場合は、問題ありません。しかし、そうでなければ、私たちは無力です。だから私たちは何か他のものを試す必要があります。私の解決策は、スタックトレースを生成し、そこから呼び出し元のモジュール名を取得することでした。

module.exports = function () {
    // generate a stack trace
    const stack = (new Error()).stack;
    // the third line refers to our caller
    const stackLine = stack.split("\n")[2];
    // extract the module name from that line
    const callerModuleName = /\((.*):\d+:\d+\)$/.exec(stackLine)[1];

    return require.main.filename === callerModuleName;
};

できるようになりました:

if (require("./is-main-module")()) {  // notice the `()` at the end
    // do something
} else {
    // do something else
}

またはより読みやすい:

const isMainModule = require("./is-main-module");

if (isMainModule()) {
    // do something
} else {
    // do something else
}

忘れられない :-)

2
Lucio Paiva