Node.JS: Обнаруживать, если вызов через require или напрямую по командной строке

Как определить, был ли вызван мой файл Node.JS с использованием SH: node path-to-file или JS: require('path-to-file')?

Это Node.JS, эквивалентный моему предыдущему вопросу в Perl: Как я могу запустить свой Perl script, только если он не был загружен с требованием?

Ответ 2

Существует другой, немного более короткий путь (не упомянутый в указанных документах).

var runningAsScript = !module.parent;

Я рассказал о более подробной информации о том, как все это работает под капотом в этом сообщении в блоге.

Ответ 3

Я был немного смущен терминологией, используемой в объяснении (-ях). Поэтому мне пришлось сделать пару быстрых тестов.

Я обнаружил, что они дают одинаковые результаты:

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

И для других смущенных людей (и для ответа на вопрос напрямую):

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

Ответ 4

Попробуйте, если вы используете модули ES6:

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

Ответ 5

Как и в 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
}

Невозможно забыть: -)