¿Cómo puedo detectar si mi archivo Node.JS fue llamado usando SH: node path-to-file
o JS require('path-to-file')
:?
Este es el Node.JS equivalente a mi pregunta anterior en Perl: ¿Cómo puedo ejecutar mi script Perl solo si no se cargó con require?
¿Cómo puedo detectar si mi archivo Node.JS fue llamado usando SH: node path-to-file
o JS require('path-to-file')
:?
Este es el Node.JS equivalente a mi pregunta anterior en Perl: ¿Cómo puedo ejecutar mi script Perl solo si no se cargó con require?
Respuestas:
if (require.main === module) {
console.log('called directly');
} else {
console.log('required as a module');
}
Consulte la documentación para esto aquí: https://nodejs.org/docs/latest/api/modules.html#modules_accessing_the_main_module
require()
, pero tal vez podrías hacerlo importando el archivo y luego ejecutándolo eval
, o ejecutandorequire('child_process').exec('node the_file.js')
es-main
paquete para verificar si un módulo se ejecutó directamente.
Hay otra forma, un poco más corta (no descrita en los documentos mencionados).
var runningAsScript = !module.parent;
Esbocé más detalles sobre cómo funciona todo esto bajo el capó en esta publicación de blog .
node script.js
pero no cat script.js | node
. De esta manera funciona para ambos.
Estaba un poco confundido por la terminología utilizada en las explicaciones. Así que tuve que hacer un par de pruebas rápidas.
Descubrí que estos producen los mismos resultados:
var isCLI = !module.parent;
var isCLI = require.main === module;
Y para las otras personas confundidas (y para responder la pregunta directamente):
var isCLI = require.main === module;
var wasRequired = !isCLI;
Al igual que en Python, siempre me encuentro tratando de recordar cómo escribir este maldito fragmento de código. Entonces decidí crear un módulo simple para él. Me llevó un poco desarrollarlo ya que acceder a la información del módulo de la persona que llama no es sencillo, pero fue divertido ver cómo se podía hacer.
Entonces, la idea es llamar a un módulo y preguntarle si el módulo que llama es el principal. Tenemos que descubrir el módulo de la función de llamada. Mi primer enfoque fue una variación de la respuesta aceptada:
module.exports = function () {
return require.main === module.parent;
};
Pero eso no está garantizado para funcionar. module.parent
señala el módulo que nos cargó en la memoria, no el que nos llama. Si fue el módulo llamante el que cargó este módulo auxiliar en la memoria, está bien. Pero si no fuera así, estamos indefensos. Entonces necesitamos probar algo más. Mi solución fue generar un seguimiento de la pila y obtener el nombre del módulo de la persona que llama desde allí:
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;
};
Ahora podemos hacer:
if (require("./is-main-module")()) { // notice the `()` at the end
// do something
} else {
// do something else
}
O más legible:
const isMainModule = require("./is-main-module");
if (isMainModule()) {
// do something
} else {
// do something else
}
Imposible de olvidar :-)
return require.main /*this is undefined if we started node interactively*/ && require.main.filename === callerModuleName;
Intente esto si está utilizando módulos ES6:
if (process.mainModule.filename === __filename) {
console.log('running as main module')
}
process.mainModule
esundefined