Node.js와 브라우저 환경의 자바스크립트와 가장 큰 차이점 중 하나를 꼽자면 바로 모듈일 것입니다.
이번 포스팅에서는 Node.js의 모듈을 주제로 포스팅 해보겠습니다.
모듈이란?
쉽게 어떤 기능을 하는 함수 / 변수의 집합을 말합니다.
정보통신기술용어해설에는 모듈을 소프트웨어 묶음을 만들고 네임스페이스로써 구분하는 매커니즘으로 소개하고 있습니다.
이런 모듈을 사용하면 수정이 용이하고 재사용성이 증가하며 유지관리에 큰 장점을 가집니다.
모듈화는 다음과 같은 원칙이 있습니다.
- 개별 기능별로 하나의 완결된 구조를 가져야한다.
- 각 모듈별로 독립성을 가진다.
- 각 모듈은 반드시 입구 / 출구가 존재해야한다.
정보통신기술용어해설 참고 : http://www.ktword.co.kr/abbr_view.php?m_temp1=2226
Node.js에서 모듈은 모듈이 될 파일과모듈을 사용할 파일이
필요합니다.
이때 사용하게 되는 키워드는 바로 module.exports와 exports 입니다. exports가 module.exports를 call by reference로 참조하는 구조로 되어 있습니다. 아래는 그 관계를 코드로 나타낸 예시입니다.
var module = { exports: {} }; var exports = module.exports; return module.exports;
위와 같은 구조로 exports는 module.exports를 참조하고 있으므로 결국 exports에 값을 추가하면 module.exports에도 값이 추가되는 것이다.
참고로 해당 파일에서 모듈로 최종 return 되는 것은 module.exports 입니다.
> 예시
1 2 3 4 5 6 | // test.js const test2 = require("./test2") test2.test1() test2.test2() test2.test3() | cs |
1 2 3 4 5 6 7 8 9 10 | // test2.js exports.test1 = () => { console.log("hello test!"); }; exports.test2 = () => { console.log("hello test2!"); }; exports.test3 = () => { console.log("hello test3!"); }; | cs |
같은 폴더 내부에 test.js와 test2.js가 있다고 가정하겠습니다. 위 test.js가 아래 test2.js를 가져와 사용한다고 할 때 test2의 module.exports에 정의한 객체 또는 함수를 가져와 사용하게 됩니다.
아래 test2.js에서는 module.exports를 가르키는 exports에 값들을 추가하여 모듈화하였습니다. 그 결과, test.js에서 test2..js에서 exports의 변수로 줬던 test1, test2, test3 함수를 사용할 수 있게 되었습니다.
그 결과로 다음과 같이 나옵니다.
위 예시의 test2.js는 다음의 표현과도 같습니다.
1 2 3 4 5 6 7 8 9 10 11 | module.exports = { test1(){ console.log("hello test!"); }, test2(){ console.log("hello test2!"); }, test3(){ console.log("hello test3!"); } }; | cs |
위와 같은 이유는 앞서 언급한 것과 같이 exports가 module.exports를 가르키기 때문입니다. 때문에 exports에 변수를 새로 할당하는 것과 객체로 메서드를 module.exports에 할당하는 것과 같은 효과가 나타나는 것입니다.
이외에도 module.exports에 함수 하나를 할당하여 다음과 같이 사용할 수도 있습니다. 보통 하나의 함수만을 외부에서 접근할 수 잇도록 만드는 방법입니다. (대부분의 경우 이와 같이 사용하는 것 같습니다.)
1 2 3 4 | // test.js const test2 = require("./test2") test2(); | cs |
1 2 3 4 | // test2.js module.exports = () => { console.log("hello module.exports!"); }; | cs |
위와 같이 test2.js에서 함수 하나릉 module.exports로 할당하였으므로 require를 하면 test2.js에서 정의한 익명함수가 할당되게 됩니다. (test.js에서는 test2 변수에 할당됨)
이를 통해 test2()를 사용하는 것입니다. 그 결과로 hello module.exports!가 콘솔에 찍힐 것입니다.
참고로 위 test.js를 node cli로 실행할 때 확장자 명(.js)을 빼고 실행하였습니다. 확장자 명을 빼고 실행하게되면 node.js는 다음과 같이 파일을 찾아 실행하게 됩니다.
- 먼저, 해당 경로에 test.js 파일을 찾습니다.
- 만약 해당 경로에 test.js 파일이 없다면 폴더를 찾고 폴더 내부에 index.js를 찾아 실행합니다
- 이 두 경우에 해당하지 않는다면 오류가 납니다!