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 }
不可能忘记 :-)