상세 컨텐츠

본문 제목

module / module.exports / exports 를 알아보자!

백엔드/NodeJS

by 짱의 조건 2022. 12. 8. 14:39

본문

변수를 다른 js 파일에서도 사용하고 싶어서 export와 import 기능을 알아보고 이를 제 코드에 적용했습니다.

그런데 자꾸만 에러가 뜹니다.

 

볼 때마다 ㅉㅏ릿해! 늘 새로워,,!

 

자세히는 모르겠지만 이미 저의 js 파일에 module.exports가 있는데, 또 exports를 사용해서 생긴 오류인 것 같았습니다.

오류를 해결하기 위해 여러가지 해결방법들을 적용해봤지만, 그래도 실패...

 

이참에 module.exports와 그냥 exports의 차이를 알아보기로 했습니다.

그래야 제가 하고 싶은 대로 변수를 다른 파일로 보낼 수 있을 것 같거든요.

 

 

* 모듈 module

노드는 코드를 모듈로 만들 수 있다는 점에서 브라우저의 자바스크립트와 다릅니다.  Node.JS에서 모듈은 특정한 기능을 하는 함수나 변수들의 집합입니다. 모율은 자체로도 하나의 프로그램이면서 다른 프로그램의 부품으로 사용이 가능합니다.  (<Node.js 교과서>, 조현영, 92쪽) 코드의 길이를 줄이고, 코드의 유지보수에도 좋다는 장점이 있습니다.

 

* module.exports와 exports의 차이?

많은 블로그에서는 이 둘의 차이를 이렇게 설명합니다.

 

exports와 module.exports는 동일하며(exports의 객체와 module.exports의 객체는 동일하다), exports가 module.expots의 객체를 call by reference 방식으로 바라보고 있다. 최종적으로 리턴값은 module.exports이다.

 

저는 화가 많습니다. 저게 무슨 말인지 모르겠어서 화가 납니다.

침착하게 무슨 말인지 이해해보았습니다.

 

- exports와 module.expots가 같다?

확인하기 위해 console.log를 이용해봅시다.

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

콘솔에 true 라고 나옵니다. == 이 아닌, ===을 사용했는데도 같다고 하니 둘은 똑같은 게 맞습니다!

 

 

* exports

하나씩 눈으로 확인해봅시다. 먼저 jjang.js 에서 jjang을 하나 만들어줍니다.

const jjang = {
	name : "짱의 조건",
	desc : "화가 많다."
	}
exports = jjang;

 

다른파일 main.js로 넘어가 require()을 이용해 exports를 가져옵시다. require()은 메소드로 exports의 객체를 리턴해줍니다. require() 메소드에 대해서도 다음에 한 번 짚고 넘어가야 할 것 같네요. 😩

 

const jjang = require("./jjang");
console.log(jjang);

 

실행 결과가 {} 로 나옵니다. 왜? 왜 때문에?

블로그를 열심히 찾아봤는데, exports를 사용했을 때, 원하는 값을 얻기 위해서는 프로퍼티에 접근하는 형태로 사용해야한다고 합니다.

오...... 다음 블로그 글 주제가 바로 나왔죠 ? 🥳 저는 모르는 게 많아서 참 좋네요. 배울 게 많으니까요~ 행복하다~

 

 

프로퍼티에 접근하는 방법(?)으로 코드를 수정합니다.

const jjang = {
	name : "짱의 조건",
	desc : "화가 많다."
	}
exports.person = jjang;

생각보다 간단합니다! .person 을 붙여주면 끝입니다. 그러면 다른 파일에서 불러올 때도, 똑같이 해줍니다.

const jjang = require("./exports");
console.log(jjang.person);

그러면 원하던 값이 나옵니다.  { name: '짱의 조건', decs: '화가 많다.' }

음... exports가 어떤건지 눈으로 확인했으니, 이번엔 module.exports로 똑같이 해봅시다.

 

 

* module.exports

 

jjang.js에 똑같이 적어줍니다.

const jjang = {
	name: "jjang",
	decs: "화가 많다."
		}
module.exports = jjang;

main.js로 와서 require()로 exports를 가져옵니다.

const jjang = require("./jjang");
console.log(jjang);

 

결과는 ??

 

아까랑 똑같은 사진 아닙니다...

프로퍼티 값이 접근하거나 한 게 아닌데, 우리가 원하는 것을 바로 보여줍니다. exports 때와는 다르네요!

근데 왜 exports와 module.exports는 같은 걸까요 ? Call by Reference라는 말이 뭔지 안다면...?

 

 

* Call by Reference

 

Call by Reference는 데이터가 있는 공간(주소: 메모리의 위치)가 참조되는 것을 말합니다.

JS에서 객체는 Call by reference가 일어납니다.

 

음 ...... 그러니까 exports가 module.exports의 객체를 call by reference 방식으로 바라보고 있다, 는 말은 exports를 그냥 사용했을 때는 module.exports처럼 작동하려고 하긴 하지만 잘 안되서 '{}' 같은 결과를 보여주나봅니다. exports를 제대로 사용하려면 프로퍼티값에 접근할 수 있도록 설정을 해줘야만 합니다. module.exports는 완전판(?)이므로 따로 뭔가 더 해주지 않더라도 프로퍼티 값에 알아서 접근 할 수 있습니다! 둘 다 리턴 값도 module.exports로 똑같습니다.

 

* 프로퍼티에 접근!

exports의 프로퍼티에 접근을 한다는 말은 좀 더 자세히 찾아보니 key를 준다는 말인 듯 합니다. key가 없다면 exports는 단독으로 사용하지 못한다고 합니다. 위의 말과 더해보면 제가 처음에 exports = jjang 처럼 사용한 건 exports(라는 변수) = jjang이라는 말이 되어버리기 때문에, exports가 exports의 역할을 할 수 있도록 exports.(key 넣어주기) 이렇게 사용하는가 봅니다. 그러면 exports와 module.exports는 아주 똑같은 기능을 합니다

 

아닐 시 눈물 😥

 

 

* 오늘의 결론!

exports와 module.exports의 쓰임새가 있는 것 같은데 잘 모를때는 module. exports를 쓰는 게 좋습니다. 일단 둘은 동일하고, 사용 방식에 조금 차이가 있습니다.

 

 

그럼 저는 제 문제를 해결해보겠읍니다...

제가 새롭게 알게 된 것들로... 문제를... 해결할 수 있으면... 좋겠네요,,

할 수 있 따 ! 🥹

 

 

관련글 더보기