如何检测我的Node.JS文件是否使用SH:node path-to-file
或JS 调用require('path-to-file')
?
这是Node.JS等同于我在Perl中的上一个问题:如果它没有加载require,我怎么能运行我的Perl脚本?
nic*_*ten 429
if (require.main === module) {
console.log('called directly');
} else {
console.log('required as a module');
}
Run Code Online (Sandbox Code Playgroud)
请参阅此处的文档:https://nodejs.org/docs/latest/api/modules.html#modules_accessing_the_main_module
Tho*_*enz 84
还有另一种略短的方法(在上述文档中没有概述).
var runningAsScript = !module.parent;
我在这篇博客文章中概述了有关这一切是如何工作的更多细节.
我总是发现自己在回想如何编写这个该死的代码片段,所以我决定为它创建一个简单的模块。因为访问调用者的模块信息并不简单,所以我花了一点时间让它工作,但是看看它是如何完成的很有趣。
所以这个想法是调用一个模块并询问它是否调用者模块是主要的。我们必须弄清楚调用者函数的模块。我的第一种方法是接受答案的变体:
module.exports = function () {
return require.main === module.parent;
};
Run Code Online (Sandbox Code Playgroud)
但这并不能保证有效。module.parent
指向将我们加载到内存中的模块,而不是调用我们的模块。如果是调用者模块将这个辅助模块加载到内存中,我们就很好。但如果不是,它就行不通。所以我们需要尝试其他的东西。我的解决方案是生成堆栈跟踪并从那里获取调用者的模块名称:
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;
};
Run Code Online (Sandbox Code Playgroud)
将其另存为is-main-module.js
,现在您可以执行以下操作:
const isMainModule = require("./is-main-module");
if (isMainModule()) {
console.info("called directly");
} else {
console.info("required as a module");
}
Run Code Online (Sandbox Code Playgroud)
哪个更容易记住。
小智 8
如果你使用 ES6 模块,试试这个:
if (process.mainModule.filename === __filename) {
console.log('running as main module')
}
Run Code Online (Sandbox Code Playgroud)
我对解释中使用的术语感到有些困惑。所以我不得不做一些快速测试。
我发现它们产生相同的结果:
var isCLI = !module.parent;
var isCLI = require.main === module;
Run Code Online (Sandbox Code Playgroud)
对于其他困惑的人(并直接回答问题):
var isCLI = require.main === module;
var wasRequired = !isCLI;
Run Code Online (Sandbox Code Playgroud)
小智 5
对于使用 ES 模块(和 Node 10.12+)的用户,您可以使用import.meta.url
:
import { fileURLToPath } from 'url'
const isRunningDirectlyViaCLI = process.argv[1] === fileURLToPath(import.meta.url)
Run Code Online (Sandbox Code Playgroud)
诸如require.main
,module.parent
和__dirname
/之类的东西__filename
在 ESM 中不可用。
注意:如果使用 ESLint,它可能会阻塞在这种语法上,在这种情况下,您需要更新到 ESLint
^7.2.0
并将您的ecmaVersion
上调到11
(2020
)。
更多信息:process.argv
,import.meta.url
归档时间: |
|
查看次数: |
37186 次 |
最近记录: |