본문 바로가기

개발 공부/nodejs

[섹션 2-1] 노드 기본 기능 살피기

모듈

노드는 자바스크립트 코드를 모듈로 만들 수가 있다. 모듈이 어렵다면 그냥 쪼갠 코드라고 보면 좋을 것 같다. 보통은 기능 별로 쪼갠다. 사실 말이 다를 뿐이지 리액트의 컴포넌트도 비슷한 역할을 한다고 본다.

 

 

노드에서는 노드만의 CommonJS 모듈 시스템 을 쓴다고 하는데 요즘은 ES 모듈로 갈아타고 있는 추세라고 한다.

 

 

기본적인 사용 방법은 아래 코드와 같다.

 

module.exports = checkFunc;
module.exports = {odd, even}; //여러개 한꺼번에 보낼 때
exports.odd = "홀수"; //module.export 대신 exports만 씀

 

기본적으로 1번째 줄 처럼 작성을 하고, 여러개일 때는 2번째 줄처럼 작성한다.

 

특이하게 module이라는 것을 생략할 수 있는데 노드에서 module.exports와 exports가 참조 관계이기 때문에 동일하게 동작을 한다.

 

module.exports === exports === {}

 

주의할 점은 exports를 썼다면 계속 exports를 써야한다는 것이다. exports 뒤에 새롭게 module.exports ={} 라고 새로운 객체를 선언해버리면 참조가 끊겨서 exports.뭐시기 한 값이 다 사라진다고 한다.

 

그리고 이렇게 export 한 모듈들은 require("뭐시기")로 가지고 올 수 있다.

 

const {odd, even}= require("./var"); //구조분해 할당, 확장자 생략 가능

require("뭐시기"); //export한 값을 쓰지 않고 그 코드를 중간에 쏙 넣고 싶을 떄

 

 

 

this

사실 이제는 this가 뭐하는 녀석인지도 알고, 코드에서 잘 쓰이지도 않기 때문에 거부감은 없다. 그런데 이상하게 this 이름만 들으면 파블로프의 개 마냥 반응하는 두려움이 있다.

 

노드에서의 this는 최상위 스코프에서의 this, 함수 선언문 내부의 this가 있는데 주목할 포인트는 최상위 스코프에서의 this이다.

 

노드에서 최상위 스코프 this를 출력해보면 {} 가 출력된다.

 

위에서 module.exports === {} 라고 했는데 이렇게 따지면 module.exports === this 인 것일까? 맞다. 그래서 exports.even을 this.even 이런식으로 써도 된다.

 

그런데 사실 이건 가독성도 안좋고 직관적이지도 않아서 아예 안쓸 것 같다.

 

 

 

순환참조

모듈 A가 B를 참조하고, B가 A를 참조하는 경우를 순환참조라고 한다. 이러면 무한루프에 빠지면서 큰 에러가 날 수도 있는데 노드에서는 무한 반복을 막기 위해 순환 참조 대상이 빈 객체가 된다고 한다.

 

 

 

ES 모듈

자바스크립트 자체의 모듈 시스템 import와 export를 사용한다 react를 하면서 수도 없이 썼다. CommonJS 모듈과 완전히 매칭되는 것은 아니고 약간씩 다른 것들이 있다.

 

파일명: mjs 확장자를 쓴다 뭔가 어색하고 실수를 많이 할 거 같아서 벌써부터 쓰기 싫어지는데 package.json에 "type: module"을 적어주면 된다고 한다. 그리고 import할 때 뒤에 확장자를 생략할 수 없다. 사실 이건 요즘 에디터에서 알아서 해줘서 걱정은 없다.

 

top level await: es 모듈에서는 최상위 스코프에서 async 없이 await를 쓸 수 있다. 그런데 나는 async를 붙이는 게 마음 편하긴 하다.

 

다이나믹 임포트: 코드 중간에 require를 할 수 있다. import는 안되지만 함수형으로 import()를 해서 가져오면 된다.

 

__filename, __dirname: commonJS에서는 되고 es 모듈에서는 안된다.