모듈화하는 방법에 대해 간단하게 작성한 포스트를 주제로 포스팅을 한 적이 있다.
이번 포스팅에서는 Node.js 교과서를 읽던 중 알게 된 내용으로, module.exports, exports, this 그리고 reuiqre에 대한 내용을 정리해보고자 한다.
module.exports와 exports는 하나의 객체를 참조한다. 좀 더 정확히 말하면 exports -> module.exports -> {}의 관계를 가지고 있다. console.log(exports === module.exports)
의 값은 true
이다.
console.log(exports === module.exports) // true
이뿐만이 아니다. 최상위 스코프에서 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는 node.js 내장 객체인 global을 가리킨다.
function test() {
console.log(this === exports) // false
console.log(this === global) // true
}
어떤 방법으로든 exports를 시켰으면 해당 값을 가져다 써야할 것이다. 결국 이러한 작업은 모듈화를 위한 것이기 때문이다. 최신 문법으로는 import를 사용하지만 원래는 require()을 사용했다. 이것에 대해 알아보자.
require() 모양을 보고 눈치챌 수 있겠지만, 이것은 함수다. 그리고 js에서 함수는 객체다.
따라서 reuiqre 함수 내부에는 몇 가지 객체로서 속성을 가지고 있는데 그 중, cache와 main을 보자.
cache에는 파일 이름이 속성명으로 들어 있다. 그리고 그 값으로 각 파일의 모듈 객체가 들어 있다. 그리고 한 번 require된 파일은 cache에 저장해서 다음 번에 같은 걸 require 할 때, 새로 불러오지 않고 바로 재사용이 가능하다.
cache를 제거해서 새로 require 가능하지만, 동작이 꼬일 수 있으므로 추천하지 않는다.
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에서 공통적으로 참조할 수 있는 객체를 만들고 그 안에 값을 집어 넣는다. 그리고 그것을 꺼내 쓴다는 단순한 개념으로 우리의 프로젝트를 기능별로 나누어 관리할 수 있는 짜릿함을 제공하는 것이었다.
역시 공부엔 왕도가 없고 알면 알 수록 재밌다.