[Node.js] 09 - CommonJS & ECMAScripts Module
모듈
✅ 노드는 자바스크립트 코드를 모듈로 만들 수 있다.
- 모듈: 특정한 기능을 하는 함수나 변수들의 집합
- 모듈로 만들면 여러 프로그램에서 재사용 가능
CommonJS 모듈
✅ JS 표준 모듈이 있기 전부터 노드에서 사용해 온 방식
- 같은 폴더 내에 var.js, fun.js, index.js 만들기
- 파일 끝에 module.exports로 모듈로 만들 값을 지정
- 다른 파일에서 require(파일경로)로 그 모듈의 내용을 가져올 수 있음
// var.js
const odd = 'Odd'
const even = 'Even'
module.exports = {
odd,
even,
};
// func.js
const {odd, even} = require('./var.js')
function checkOddOrEven(num) {
if (num%2) {
return odd;
}
return even;
}
module.exports = checkOddOrEven;
// index.js
const {odd,even} = require('./var.js')
const {checkNumber} = require('./func.js')
function checkStringOddOrEven(str) {
if (str.length%2) {
return odd
}
return event;
}
console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));
// <출력 결과>
// Even
// Odd
✅ module, exports 대신 exports로도 모듈을 만들 수 있음
- exports는 module.exports의 참조값을 가지는 참조 변수이기 때문
- 모듈 예제의 var.js에서 exports로 바꾼 후 실행해도 동일하게 동작
- but, exports에 객체 속성이 아닌 다른 값을 대입하면 참조 관계가 깨지므로 주의해야 함
- exports는 객체 모듈에 대해서만 사용 가능
✅ 함수를 대입할 때는 module.exports만 사용해야 함
✅ 노드에서의 this 사용 시 주의점
- 최상위 스코프의 this는 module.exports를 가리킴
- 함수 선언문 내부의 this는 global(전역) 객체를 가리킴
- 그 외에는 브라우저의 자바스크립트와 동일
✅ 두 개의 모듈이 서로를 require하는 순환참조가 나오지 않도록 해야 함
ECMAScript 모듈
✅ 공식적인 자바스크립트 자체 모듈
- mjs 확장자를 사용하거나, package.json에 'type" : "module"을 추가해서 사용
- package.json에 추가하면 .js를 사용하면서 import from 사용 가능. 추가 안 하면 import문이 뭔지 몰라 에러 발생!
✅ export: 모듈 내보내기(내보낼 때는 export. exports 아님!!)
- 변수, 함수, 클래스 앞에 export를 붙여서 각가의 이름으로 내보내면 내보낸 이름과 동일 이름을 사용해야 여러 개 내보내기 가능하다.
- export default로 하나의 모듈만 내보내기. 어떤 이름으로도 가져올 수 있다.
// var.js
const odd = 'Odd'
const even = 'Even'
export {odd,even};
// func.js
import {odd,even} from './var.js';
function checkOddOrEven(num) {
if (num%2) {
return odd;
}
return even;
}
// 모듈 하나만 내보내기
export default checkOddOrEven;
// index.js
import {odd,even} from './var.js';
import checkNumber from './func.js';
function checkStringOddOrEven(str) {
if (str.length%2) {
return odd
}
return event;
}
console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));
// <출력 결과>
// Even
// Odd
✅ dynamic import(동적 불러오기): 조건부로 모듈을 불러오는 것
- CommonJS 모듈에서는 if문 안에서 require가 가능
- ES 모듈에서는 if문 안에서 import가 불가능
// dynamic.js
if (true) {
const ok = require('./dynamic-m');
console.log(ok);
} else {
console.log('ok 없음');
}
// dynamic-m.js
module.exports.ok = 'Ok! Success!';
$ node dynamic
{ ok: 'Ok! Success!' }
✅ ECMAScript JS에서는 dynamic import를 위해 import 함수를 이용
- import 함수는 Promise를 반환하므로 await나 then을 붙여서 사용
// dynamic2.mjs
if (true) {
import ok = import('./dynamic-m.js');
console.log(ok);
} else {
console.log('ok 없음');
}
// dynamic-m.js
module.exports.ok = 'Ok! Success!';
$ node dynamic2.mjs
[Module: null prototype]
{default: { ok: 'Ok! Success!' }, ok: 'Ok! Success!'}
__fiilename, __dirname
✅ __filename: 현재 파일 경로
✅ __dirname: 현재 폴더 경로
✅ ECMA 모듈에서는 import.meta.url로 현재 파일 경로 표시
// filename.mjs
console.log(import.meta.url);