Node.JS:检测是否通过require调用或直接通过命令行

如何检测我的Node.JS文件是使用SH: node path-to-file还是JS: require('path-to-file')调用的?

这是Node.JS相当于我在Perl中的前一个问题: 我如何才能运行我的Perl脚本只有当它没有加载require?

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

请参阅此处的文档: https : //nodejs.org/docs/latest/api/all.html#modules_accessing_the_main_module

还有另外一个稍微短一点的方法(在所提到的文档中没有概述)。

var runningAsScript = !module.parent;

我在这篇博客文章中详细介绍了这一切是如何运作的 。

我对解释中使用的术语有些困惑。 所以我不得不做几个快速testing。

我发现这些产生了相同的结果:

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

对于其他困惑的人(并直接回答这个问题):

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

就像在Python中,我总是发现自己试图记住如何编写这个该死的代码片段。 所以我决定为它创build一个简单的模块。 由于访问调用者的模块信息并不直接,所以我花了一点时间去开发,但看到如何完成它却很有趣。

所以这个想法是调用一个模块,并询问调用者模块是否是主模块。 我们必须弄清楚调用者函数的模块。 我的第一个方法是接受的答案的变化:

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

但是这并不能保证工作。 module.parent指向将我们加载到内存中的模块,而不是指向我们的模块。 如果是将这个辅助模块加载到内存中的调用者模块,那很好。 但如果不是的话,我们是无奈的。 所以我们需要尝试别的。 我的解决scheme是生成一个堆栈跟踪,并从那里得到调用者的模块名称:

 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 } 

不可能忘记 :-)