Tak jak w Pythonie, zawsze próbuję sobie przypomnieć, jak napisać ten cholerny fragment kodu. Postanowiłem więc stworzyć dla niego prosty moduł. Zajęło mi to trochę czasu, ponieważ dostęp do informacji o module dzwoniącym nie jest łatwy, ale fajnie było zobaczyć, jak można to zrobić.
Pomysł polega więc na wywołaniu modułu i zapytaniu go, czy moduł wywołujący jest główny. Musimy ustalić moduł funkcji dzwoniącego. Moje pierwsze podejście było odmianą przyjętej odpowiedzi:
module.exports = function () {
return require.main === module.parent;
};
Ale to nie gwarantuje, że zadziała. module.parent
wskazuje moduł, który załadował nas do pamięci, a nie ten, który nas woła. Jeśli to moduł wywołujący załadował ten moduł pomocnika do pamięci, nie ma sprawy. Ale jeśli nie, jesteśmy bezradni. Musimy więc spróbować czegoś innego. Moim rozwiązaniem było wygenerowanie śladu stosu i pobranie stąd nazwy modułu dzwoniącego:
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;
};
Teraz możemy zrobić:
if (require("./is-main-module")()) { // notice the `()` at the end
// do something
} else {
// do something else
}
Lub bardziej czytelny:
const isMainModule = require("./is-main-module");
if (isMainModule()) {
// do something
} else {
// do something else
}
Niemożliwe do zapomnienia :-)