Rileva se chiamato tramite richiede o direttamente dalla riga di comando


Risposte:


471
if (require.main === module) {
    console.log('called directly');
} else {
    console.log('required as a module');
}

Consulta la documentazione qui: https://nodejs.org/docs/latest/api/modules.html#modules_accessing_the_main_module


3
C'è un modo per aggirarlo? Ho un codice (di cui non ho il controllo) che lo fa, ma ho bisogno di richiederlo () e farlo agire come se fosse chiamato direttamente. Fondamentalmente, ho bisogno di ingannare qualcosa che usa quel test nel pensare che fosse chiamato direttamente.
Kevin,

2
@Kevin Non so come farlo require(), ma potresti farlo con l'importazione del file e poi l'esecuzione evalsu di esso, oppure eseguendorequire('child_process').exec('node the_file.js')
MalcolmOcean

Quando si utilizzano moduli ES con Node.js, è possibile utilizzare il es-mainpacchetto per verificare se un modulo è stato eseguito direttamente.
Tim Schaub,

91

C'è un altro modo leggermente più breve (non delineato nei documenti menzionati).

var runningAsScript = !module.parent;

Ho delineato maggiori dettagli su come tutto questo funziona sotto il cofano in questo post del blog .


+1, mi piace di più, ma esiterò prima di cambiare le risposte accettate. :)
Bryan Field

8
Come ho indicato, il modo ufficiale che è documentato è quello delineato @nicolaskruchten. Questa è solo un'alternativa, non è necessario cambiare la risposta accettata. Entrambi funzionano.
Thorsten Lorenz,

10
Ho dovuto usare questo piuttosto che il modo documentato - il modo documentato funziona per es. node script.jsma no cat script.js | node. In questo modo funziona per entrambi.
Tim Malone,

9

Ero un po 'confuso dalla terminologia usata nelle spiegazioni. Quindi ho dovuto fare un paio di test rapidi.

Ho scoperto che questi producono gli stessi risultati:

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

E per le altre persone confuse (e per rispondere direttamente alla domanda):

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

5

Proprio come in Python, mi trovo sempre a cercare di ricordare come scrivere questo dannato snippet di codice. Così ho deciso di creare un modulo semplice per questo. Mi ci è voluto un po 'di sviluppo poiché l'accesso alle informazioni sul modulo del chiamante non è semplice, ma è stato divertente vedere come si potesse fare.

Quindi l'idea è di chiamare un modulo e chiedergli se il modulo chiamante è quello principale. Dobbiamo capire il modulo della funzione chiamante. Il mio primo approccio è stato una variazione della risposta accettata:

module.exports = function () {
    return require.main === module.parent;
};

Ma questo non è garantito per funzionare. module.parentindica il modulo che ci ha caricato in memoria, non quello che ci chiama. Se è stato il modulo chiamante a caricare questo modulo di supporto in memoria, va bene. Ma se non lo fosse, saremmo indifesi. Quindi dobbiamo provare qualcos'altro. La mia soluzione era quella di generare una traccia dello stack e ottenere il nome del modulo del chiamante da lì:

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;
};

Ora possiamo fare:

if (require("./is-main-module")()) {  // notice the `()` at the end
    // do something
} else {
    // do something else
}

O più leggibile:

const isMainModule = require("./is-main-module");

if (isMainModule()) {
    // do something
} else {
    // do something else
}

Impossibile da dimenticare :-)


2
Molto bello. Mi piace quando gli snippet di codice comuni sono abbreviati in un singolo nome. Piccolo aggiustamento:return require.main /*this is undefined if we started node interactively*/ && require.main.filename === callerModuleName;
masterxilo,

4

Prova questo se stai usando i moduli ES6:

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

2
merda, il mio process.mainModuleèundefined
datdinhquoc,

1
GHOSHHHH, devo controllare questo nel mio file
.mjs
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.