명령 줄을 통해 요구를 통해 또는 직접 호출되는지 감지


답변:


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

여기에 대한 설명서를 참조하십시오 : https://nodejs.org/docs/latest/api/modules.html#modules_accessing_the_main_module


3
이 문제를 해결할 방법이 있습니까? 이 작업을 수행하는 코드 (제어 권한이 없음)가 있지만 require ()해야하고 직접 호출 된 것처럼 작동해야합니다. 기본적으로 테스트를 사용하여 직접 호출되었다고 생각하는 것을 속일 필요가 있습니다.
케빈

2
@Kevin 나는이 작업을 수행하는 방법에 대해 잘 모르지만 require()파일을 가져온 다음 실행 eval하거나 다음을 실행하여 파일을 수행 할 수있다.require('child_process').exec('node the_file.js')
MalcolmOcean

Node.js와 함께 ES 모듈을 사용하는 경우 es-main패키지를 사용하여 모듈이 직접 실행되었는지 확인할 수 있습니다.
Tim Schaub

91

약간 더 짧은 또 다른 방법이 있습니다 (언급 된 문서에는 설명되어 있지 않음).

var runningAsScript = !module.parent;

이 모든 것이 어떻게 작동하는지에 대한 자세한 내용을 설명했습니다. 이 블로그 게시물에서이 기능이 했습니다 .


+1, 나는 이것을 더 좋아하지만 수락 된 답변을 전환하기 전에 주저 할 것입니다. :)
Bryan Field

8
내가 지적했듯이, 문서화 된 공식적인 방법은 @nicolaskruchten이 설명한 것입니다. 이것은 대안 일 뿐이며 허용되는 답변을 바꿀 필요가 없습니다. 둘 다 작동합니다.
Thorsten Lorenz

10
나는 문서화 된 방식보다는 이것을 사용해야했습니다. 문서화 된 방식은 예를 들어 효과적입니다. node script.js그러나 아닙니다 cat script.js | node. 이 방법은 둘 다 작동합니다.
Tim Malone

9

나는 설명에 사용 된 용어에 약간 혼란 스러웠다. 그래서 몇 가지 빠른 테스트를해야했습니다.

나는 이것들이 동일한 결과를 산출한다는 것을 발견했다.

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

그리고 다른 혼란스러운 사람들에게 (그리고 질문에 직접 대답하기 위해) :

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

5

파이썬에서와 마찬가지로, 나는이 빌어 먹을 코드 스 니펫을 작성하는 방법을 항상 기억하고있다. 그래서 간단한 모듈을 만들기로 결정했습니다. 호출자의 모듈 정보에 액세스하는 것이 쉽지는 않지만 개발하는 데 약간의 시간이 걸렸지 만 어떻게 수행 할 수 있는지 보는 것이 재미있었습니다.

따라서 아이디어는 모듈을 호출하고 호출자 모듈이 기본 모듈인지 묻는 것입니다. 호출자 함수의 모듈을 파악해야합니다. 첫 번째 접근 방식은 허용되는 답변의 변형이었습니다.

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

그러나 이것이 작동한다고 보장되지는 않습니다. 우리를 호출 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;
};

이제 우리는 할 수 있습니다 :

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
}

잊을 수 없다 :-)


2
매우 시원합니다. 일반적인 코드 스 니펫이 단일 이름으로 축약 될 때 나는 그것을 좋아합니다. 작은 조정 :return require.main /*this is undefined if we started node interactively*/ && require.main.filename === callerModuleName;
masterxilo

4

ES6 모듈을 사용하는 경우 다음을 시도하십시오.

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

2
쓰레기, 내 process.mainModuleISundefined
datdinhquoc

1
GHOSHHHH, 내 .mjs 파일에서 이것을 확인해야합니다
datdinhquoc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.