Как определить, был ли вызван мой файл Node.JS с использованием SH: node path-to-file
или JS: require('path-to-file')
?
Это Node.JS, эквивалентный моему предыдущему вопросу в Perl: Как я могу запустить свой Perl script, только если он не был загружен с требованием?
Ответ 1
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
Ответ 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
}
Невозможно забыть: -)