Node.JS: обнаружение, если вызывается через require или напрямую из командной строки - PullRequest
259 голосов
/ 18 июня 2011

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

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

Ответы [ 5 ]

401 голосов
/ 18 июня 2011
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

79 голосов
/ 03 марта 2013

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

var runningAsScript = !module.parent;

Я обрисовал более подробно, как все это работает под капотом в этот пост .

4 голосов
/ 03 марта 2017

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

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

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

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

var isCLI = require.main === module;
var wasRequired = !isCLI;
3 голосов
/ 10 октября 2018

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

if (process.mainModule.filename === __filename) {
  console.log('running as main module')
}
2 голосов
/ 26 октября 2017

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

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

...