节点。通过require或命令行直接检测调用

时间:2021-01-06 20:53:53

How can I detect whether my Node.JS file was called using SH:node path-to-file or JS:require('path-to-file')?

如何检测我的节点。使用SH:node path-to-file或JS:require(“pathto -file”)调用JS文件?

This is the Node.JS equivalent to my previous question in Perl: How can I run my Perl script only if it wasn't loaded with require?

这是一个节点。JS相当于我之前在Perl中的问题:如果Perl脚本没有装载require,我如何才能运行它?

4 个解决方案

#1


322  

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

See documentation for this here: https://nodejs.org/docs/latest/api/all.html#modules_accessing_the_main_module

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

#2


62  

There is another, slightly shorter way (not outlined in the mentioned docs).

还有另一种稍短的方法(在提到的文档中没有提到)。

var runningAsScript = !module.parent;

var runningAsScript = ! module.parent;

I outlined more details about how this all works under the hood in this blog post.

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

#3


3  

I was a little confused by the terminology used in the explanation(s). So I had to do a couple quick tests.

我对解释中使用的术语有点困惑。所以我必须做一些快速测试。

I found that these produce the same results:

我发现这些结果是一样的:

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

And for the other confused people (and to answer the question directly):

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

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

#4


2  

Just like in Python, I always find myself trying to remember how to write this goddamn code snippet. So I decided to create a simple module for it. It took me a bit to develop since accessing caller's module information isn't straighforward, but it was fun to see how it could be done.

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

So the idea is to call a module and ask it if the caller module is the main one. We have to figure out the module of the caller function. My first approach was a variation of the accepted answer:

我们的想法是调用一个模块,问它调用者模块是否是主要的。我们必须找出调用函数的模块。我的第一个方法是对公认答案的一种变体:

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

But that is not guaranteed to work. module.parent points to the module which loaded us into memory, not the one calling us. If it was the caller module which loaded this helper module into memory, that's fine. But if it wasn't, we're helpless. So we need to try something else. My solution was to generate a stack trace and get the caller's module name from there:

但这并不能保证行得通。模块。父节点指向装入内存的模块,而不是调用我们的模块。如果是调用程序模块将这个辅助模块加载到内存中,那就没问题了。但如果不是这样,我们就无能为力了。所以我们需要尝试别的东西。我的解决方案是生成堆栈跟踪并从那里获取调用者的模块名称:

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

Now we can do:

现在我们能做的:

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

Or more readable:

或可读性更强:

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

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

Impossible to forget :-)

无法忘记的:-)

#1


322  

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

See documentation for this here: https://nodejs.org/docs/latest/api/all.html#modules_accessing_the_main_module

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

#2


62  

There is another, slightly shorter way (not outlined in the mentioned docs).

还有另一种稍短的方法(在提到的文档中没有提到)。

var runningAsScript = !module.parent;

var runningAsScript = ! module.parent;

I outlined more details about how this all works under the hood in this blog post.

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

#3


3  

I was a little confused by the terminology used in the explanation(s). So I had to do a couple quick tests.

我对解释中使用的术语有点困惑。所以我必须做一些快速测试。

I found that these produce the same results:

我发现这些结果是一样的:

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

And for the other confused people (and to answer the question directly):

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

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

#4


2  

Just like in Python, I always find myself trying to remember how to write this goddamn code snippet. So I decided to create a simple module for it. It took me a bit to develop since accessing caller's module information isn't straighforward, but it was fun to see how it could be done.

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

So the idea is to call a module and ask it if the caller module is the main one. We have to figure out the module of the caller function. My first approach was a variation of the accepted answer:

我们的想法是调用一个模块,问它调用者模块是否是主要的。我们必须找出调用函数的模块。我的第一个方法是对公认答案的一种变体:

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

But that is not guaranteed to work. module.parent points to the module which loaded us into memory, not the one calling us. If it was the caller module which loaded this helper module into memory, that's fine. But if it wasn't, we're helpless. So we need to try something else. My solution was to generate a stack trace and get the caller's module name from there:

但这并不能保证行得通。模块。父节点指向装入内存的模块,而不是调用我们的模块。如果是调用程序模块将这个辅助模块加载到内存中,那就没问题了。但如果不是这样,我们就无能为力了。所以我们需要尝试别的东西。我的解决方案是生成堆栈跟踪并从那里获取调用者的模块名称:

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

Now we can do:

现在我们能做的:

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

Or more readable:

或可读性更强:

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

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

Impossible to forget :-)

无法忘记的:-)