[Node.js] 내장 객체 module.exports, exports 그리고 this

슈퍼만쓰·2022년 5월 20일
0
post-thumbnail

들어가며

저번에 자바스크립트에서 모듈화하는 방법에 대해 간단하게 작성한 포스트를 작성한 적이 있다. 그런데, node.js 교과서를 읽던 중, 옛날 문법인줄로만 알았던 module.exports, exports 그리고 최상위 스코프의 this에 대해 새롭게 알게 된 사실과 추가적으로 reuiqre을 정리하려 한다.

module.exports, exports 객체

module.exports와 exports는 하나의 객체를 참조한다. 좀 더 정확히 말하면 exports -> module.exports -> {}의 관계를 가지고 있다. console.log(exports === module.exports)를 하면 true가 나온다.

console.log(exports === module.exports) // true

최상위 스코프의 this

이뿐만이 아니다. 최상위 스코프에서 this는 exports, module.exports와 같은 객체를 가리킨다. 즉, console.log(this === module.exports), console.log(this === exports)는 모두 true를 출력한다.

console.log(this === module.exports) // true
console.log(this === exports) // true

함수 스코프의 this

함수 스코프에서 this는 node.js 내장 객체인 global을 가리킨다.

function test() {
	console.log(this === exports) // false
  	console.log(this === global) // true
}

require

어떤 방법으로든 exports를 시켰으면 해당 값을 가져다 써야할 것이다. 결국 이러한 작업은 모듈화를 위한 것이기 때문이다. 최신 문법으로는 import를 사용하지만 원래는 require()을 사용했다. 이것에 대해 알아보자.

require() 모양을 보고 눈치챌 수 있겠지만, 이것은 함수다. 그리고 js에서 함수는 객체다.

따라서 reuiqre 함수 내부에는 몇 가지 객체로서 속성을 가지고 있는데 그 중, cache와 main을 보자.

cache

cache에는 파일 이름이 속성명으로 들어 있다. 그리고 그 값으로 각 파일의 모듈 객체가 들어 있다. 그리고 한 번 require된 파일은 cache에 저장해서 다음 번에 같은 걸 require 할 때, 새로 불러오지 않고 바로 재사용이 가능하다.

cache를 제거해서 새로 require 가능하지만, 동작이 꼬일 수 있으므로 추천하지 않는다.

main

main은 노드 실행 시 첫 모듈을 가리킨다. terminal에서 node test로 실행하면 test가 main이 되는 것이다. 만약 현재 모듈이 메인인지 확인하고 싶으면 require.main === module을 체크해보면 된다.

모듈 사용 시, 주의사항

만약 서로가 서로를 계속 참조하는 구조로 작성이 되면 어떤 결과를 얻을까?

// test1.js
const test2 = require('./test2.js');

console.log('test2', test2);

module.exports = () => {
	console.log('test2', test2)
}

// test2.js
const test1 = require('./test1.js');

console.log('test1', test1);

module.exports = () => {
	console.log('test1', test1)
}

// main.js
const test1 = require('./test1.js');
const test2 = require('./test2.js');

test1();
test2();

test1의 module.exports가 함수가 아니라 빈 객체로 표시된다. 이런 상황을 순환 참조라고 부른다. 이때, 에러를 던지는 것이 아니라 빈 객체로 처리되므로, 원하지 않는 결과를 낼 수 있으므로, 조심하자.

마무리

돌이켜 생각해보면, 모듈화를 할 때, 어떻게 보내고 얻는 것인지 이해하려 한 적이 없다. 그런데 이번 공부를 하면서 느낀 것은 당연한 건데 왜 지금껏 몰랐지?! 하고 머리를 맞은 기분이었다. node에서 공통적으로 참조할 수 있는 객체를 만들고 그 안에 값을 집어 넣는다. 그리고 그것을 꺼내 쓴다는 단순한 개념으로 우리의 프로젝트를 기능별로 나누어 관리할 수 있는 짜릿함을 제공하는 것이었다.

역시 공부엔 왕도가 없고 알면 알 수록 재밌다.

참고자료

node.js 교과서


혼자 공부하며 알게된 것을 정리한 글입니다. 다소 부족하거나 틀린 부분이 있을 수 있습니다.

profile
https://mahns.oopy.io/ 블로그 이전

0개의 댓글