티스토리 뷰
안녕하세요! 오늘은 NodeJS의 두가지 형식의 모듈에 대해 알아보려합니다.
각각의 모듈을 알아보기 전에, 모듈의 정의부터 알아보겠습니다!
1. 모듈이란?
모듈이란 특정한 기능을 하는 함수나 변수들의 집합입니다. 모듈은 자체로도 하나의 프로그램으로 사용할 수 있고, 다른 프로그램의 부품으로도 사용할 수 있습니다.
< 장점 >
- 여러 프로그램에서 만들어놓은 모듈을 재사용할 수 있다.
- 파일별로 코드를 모듈화하며 정리할 수 있다.
노드에서는 크게 두 가지 형식의 모듈을 사용합니다. CommonJS모듈과, ECMAScript 모듈에 대해서 알아보겠습니다.
2. CommonJS 모듈
CommonJS 모듈은 NodeJS에서 가장 널리 쓰이는 모듈입니다. CommonJS에서 원하는 기능을 실행하는 모듈을 어떤 파일에서 내보내면, 다른 파일이 그 기능을 불러와서 사용합니다. module.exports는 최하단에 위치할 필요가 없습니다.
여러 개의 객체를 내보낼 경우, exports 변수의 속성으로 할당합니다. 여러 개가 아니라 하나의 객체만 내보낼 경우, module.exports 변수 자체에 할당합니다.
- 여러 개 내보낼 때 : exports
- 한 개 내보낼 때 : module.exports
1. 내보내기
- exports
//여러 개 내보내기
//num.js
const one=1;
const two=2;
function add(x,y){
return x+y;
}
exports.one=one;
exports.two=two;
exports.add=add;
- module.exports
// 한 개 내보내기
// math.js
module.exports = {
add: function(a, b) {
return a + b;
},
multiply: function(a, b) {
return a * b;
}
};
⚠️ exports 객체 사용 시 유의사항 ⚠️
exports 객체는 module.exports를 참조합니다. 따라서, exports 객체를 사용할 때 module.exports와의 참조 관계가 깨지면 안됩니다. 따라서, exports 객체에는 꼭 객체처럼 속성명과 속성값을 대입해야합니다. 또한, exports와 module.exports를 함께 쓰지 말고 둘 중 하나만 골라 쓰는 편이 좋습니다.
2. 불러오기
앞의 예제에서 exports와 module.exports를 써서 num.js와 math.js 파일을 만들었습니다. 다른 파일인 test.js에서 num.js와 math.js의 모듈을 사용해보도록 하겠습니다. 어떤 파일에서 다른 파일의 모듈을 사용하는 것이 불러오기입니다. require 함수를 사용해서 불러올 수 있습니다. require은 최상단에 오지 않아도 됩니다.
- exports
//exports 모듈 불러오기
const num=require("./num"); //num 객체에 불러오기
console.log(num.one); //1
console.log(num.two); //2
console.log(num.add(num.one,num.two)); //3
- module.exports
//불러오기
const math = require('./math');
console.log(math.add(2, 3)); // 5
< require 함수의 속성 >
- require.cache
- 예전에 불러왔던 파일(ex : num.js, math.js) 에 관련된 정보를 갖고있음.
- 한번 require한 파일은 require.cache에 저장되므로 다음 번에 불러올때는 새로 불러오지 않고 require.cache에 있는 정보를 재사용
- require.main
- 노드 실행 시 첫 모듈을 가리킴
- 현재 파일이 첫 모듈인지 확인하는 방법 => (require.main===module)
✔️ 첫 모듈의 이름을 알려면 require.main.filename으로 알아보기!
3. ECMAScript 모듈
ECMAScript모듈은 ES 모듈이라고도 불리며, 공식적인 자바스크립트 모듈 형식입니다. 브라우저에서도 ES 모듈을 사용할 수 있어서 브라우저와 노드 모두에 같은 형식을 사용할 수 있습니다. ES 모듈도 파일 단위로 구성됩니다. CommonJS와 모듈을 내보내고 불러오는 방식은 비슷합니다. 앞에서 다루었던 CommonJS 예제를 ES 모듈 형식으로 바꿔보겠습니다.
1. 내보내기
CommonJS 모듈과 달리, ES 모듈을 사용할때는 둘 중 하나를 꼭 해줘야합니다.
- pakage.json 파일에 "type": "module" 을 추가
- 파일 확장자를 mjs 로 변경
- export
//여러 개 내보내기
//num.mjs
export const one=1;
export const two=2;
export function add(x,y){
return x+y;
}
/*
묶어서 내보낸다면 앞에 export 붙일 필요 없이 다음과 같이 한 줄 쓰면 됨
export {one,two,add};
*/
- export defalut : 파일 내에서 한개만 내보내거나, 대표로 내보낼 것이 있을때 사용
2. 불러오기
불러올때도 내보낼때와 마찬가지로 pakage.json에 "type":"module"을 추가하거나 확장자를 .mjs로 해줘야합니다. 또한 불러올때 반드시 파일명에 확장자를 포함해서 불러와야합니다.
- exports
//import로 불러오기
import {one,two,add} from "./num.js"
console.log(one); //1
console.log(two); //2
console.log(add(one,two)); //3
4. CommonJS와 ECMAScript의 차이점
CommonJS 모듈은 동기적으로 로드됩니다. 모듈이 필요한 경우, 해당 모듈의 파일을 동기적으로 로드하고 모듈 객체를 반환합니다. 이것은 서버 사이드 JavaScript 환경에서 특히 유용합니다. 그러나 브라우저 환경에서는 이러한 방식으로 모듈을 로드하면 다른 작업이 블로킹될 수 있습니다.
*서버 사이드(server-side) : 네트워크의 한 방식인 클라이언트-서버 구조의 서버 쪽에서 행해지는 처리
//다이내믹 임포트
if(true){
require(./file.js);
}
반면에 ECMAScript 모듈은 비동기적으로 로드됩니다. 모듈이 필요한 경우, 브라우저는 해당 모듈이 포함된 스크립트 파일을 다운로드하고 실행합니다. 이는 브라우저 환경에서 더 효율적이며 블로킹 문제를 해결합니다.
//ES모듈은 다이내믹 임포트 불가능
if(true){
import './file.mjs'; //에러발생
}
//await, then 사용 -> import는 프로미스를 반환
if(true){
const m1=await import('./file.mjs'); //성공
}
차이점 | CommonJS | ECMAScript |
문법 | require('./file'); module.exports=A: const A=require('./file); exports.C=D; const E=F; exports.E=E; const {C,E}=require(./file2); |
import './file.mjs'; export default A; import A from './file.mjs'; export const C=D; const E=F; export {E}; import {C,E} from './file2.mjs'; |
확장자 | js cjs |
js(package.json에 "type":"module" 추가) mjs |
확장자 생략 | 가능 | 불가능 |
다이내믹 임포트 | 가능 | 불가능 |
인덱스(index) 생략 | 가능 | 불가능 |
top level await | 불가능 | 가능 |
__filename, __dirname, require, module.exports, exports | 가능 | 불가능 (__filename -> import.meta.url 가능) |
서로 간의 호출 | 가능 |
5. 순환 참조
순환 참조(Circular dependency)란 두 가지 이상의 객체가 서로에 대한 참조를 하는 경우를 말합니다. 순환참조가 있을 경우에는 순환 차조되는 대상을 빈 객체로 만듭니다. 이때 에러가 아니라 Warning이 발생합니다. 빈 객체때문에 예상치못한 결과가 나올 수 있으니 주의해야합니다.
//module1.js
const m1=require('./module2.js');
console.log(m1);
module.exports=()=>{
console.log('module1');
};
//module2.js
const m2=require('./module1.js');
console.log(m2);
module.exports=()=>{
console.log('module2');
};
//app.js
const m1=require('./module1.js');
const m2=require('./module2.js');
m1();
m2();
module1.js과 module2.js이 서로 참조하기때문에 순환참조가 발생합니다. app.js를 실행하면 순환참조에 관한 Warning이 나타납니다.
이상으로 NodeJS의 모듈에 대해서 알아보았습니다. 감사합니다!
'Back_end > NodeJS' 카테고리의 다른 글
[NodeJS] 노드 내장 객체 타이머 (setTimeout, setInterval, setImmediate) (0) | 2023.04.18 |
---|---|
[NodeJS] 내장 객체 console (0) | 2023.04.15 |
[NodeJS] 내장 객체 - global (0) | 2023.04.14 |
[NodeJS] REPL이란? (0) | 2023.04.13 |
[NodeJS 에러 해결] EADDRINUSE (0) | 2023.04.03 |
- Total
- Today
- Yesterday
- 혼공학습단
- Signal
- 개발
- 혼공단
- 프로젝트
- 스페인
- 리눅스
- AWS
- JS
- 깃 예제
- MySQL
- 백엔드 개발
- Process
- C++
- nodejs
- 운영체제
- googleapis
- 교환학생
- 혼공단 SQL
- 스페인 교환학생
- 개발일지
- 혼공
- 혼공단 9기
- 자바스크립트
- 백준
- JavaScript
- SQL
- 공룡책
- 해커톤
- Linux
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |