📕 JS 모듈을 내보내는 방식은 두가지가 있다.
- 📌 모듈이란? 여러 기능들에 관한 코드가 모여있는 하나의 파일
- 첫번째는 module.exports로 모듈을 내보내고 require()로 접근하는 CJS(CommonJS)
- 두번째는 export로 모듈을 내보내고 import로 접근하는 ESM(ES Modules)가 있다.
//CJS
modules.exports = { ... } //모듈 내보낼때
const utils = requires('utils'); //모듈 가져올 때
// ESM 방법
export.default = () => {... }; //모듈을 내보낼 때
import utils from 'utils'; // 모듈 가져올 때
✨차이점
1. CJS 방식
- require로 모듈을 접근하고 module.exports로 모듈을 내보내는 ESM 방식
- Node.js에서 지원하는 모듈 방식으로 초기 Node 버전부터 사용
- 별도의 설정이 없다면 CJS가 기본값
1) 모듈에 접근할 때 require()
- 외부 모듈에 접근할때는 require()을 사용
2) 내보낼 때는 module.exports
- named exports, default exports 두가지 방식이 있음
- named export는 export 대상을 명명하여 내보내는 방식
module.exports.add = (a, b) => a + b;
module.export.sub = (a, b) => a - b;
또는,
const calculator = require("./calculator.js");
const { add } = require("./calculator.js");
3) 특징
- require()는 즉시 스크립트를 실행하는 구조
- top-level await이 불가능하므로 동기적으로 작동
- 동기로 작동하므로 promise를 리턴하지 않고, module.exports에 설정된 값만을 리턴
- import 순서에 따라 스크립트를 실행
📌 top-level await 이란?
ES2022에서 나온 기능으로, 모듈의 최상위 스코프에서 비동기 동작을 await하여 사용할 수 있다.
이전에는 async 키워드가 있는 스코프내에서만 await를 통해 해당 스코프에서 비동기 동작이 완료되기까지 블로킹할 수 있었는데
모듈 단위에서 await를 통해 특정 비동기 함수의 동작이 완료되기까지 하위 모듈의 동작을 막을 수 있다.
💻 예시 코드
//a.js
import fetch from "node-fetch";
let users;
export default (async () => {
const resp = await fetch('https://jsonplaceholder.typicode.com/users');
users = resp.json();
})();
export { users };
//b.js
import promise, {users} from './a.js';
promise.then(() => {
console.log('All users:', users);
});
- a 모듈을 b 모듈에서 사용할 때 a 모듈의 비동기 처리가 완료된 후 사용을 보장하기 위해 위와 같이 처리해야 했음
//a.js
const resp = await fetch('https://jsonplaceholder.typicode.com/users');
const users = resp.json();
export { users};
//b.js
import { users } from './a.js';
console.log(users);
console.log('In usingAwait module');
- 이렇게 간결하게 비동기 처리 가능
2. ESM
- import로 모듈을 접근하고 export로 모듈을 내보내는 ESM 방식
- ESMAScript에 지원하는 방식
- Node14에서는 CJS, MJS(ES Modules)이 공존하는데, 두개를 동시에 사용하기 위해 별도의 처리가 필요하다.
- 모듈 시스템을 CJS(기본값)에서 ESM으로 변경할 시, JS 일부 동작이 변경된다.
1. 사용방법
- ESM 방식을 사용하기 위해서는 package.json에 'type:'module'을 설정해야 한다.
// package.json
{
"type": "module",
}
2. 문법
- 모듈 접근할 때는 import()
- 모듈 내보낼 때는 export()
3. 특징
- top-level await를 지원하므로 module loader가 비동기 환경에서 실행된다.
- 그러므로 CJS처럼 스크립트를 바로 실행하지 않고 import, export 구문을 찾아 스크립트를 파싱한다.
- 파싱단계에서 import, export 에러를 감지할 수 있다.
- 모듈을 병렬로 다운로드하지만, 실행은 순차적으로 한다.
- import, export를 지원하지 않는 브라우저가 있어 ESM 사용을 위해 번들러가 필요하다.
'자바스크립트의 정석 🟡' 카테고리의 다른 글
[자바스크립트] 콜백, Promise, async/await (0) | 2024.08.12 |
---|---|
[자바스크립트] callback 정리 ✨ (0) | 2024.01.28 |
[자바스크립트] 프로토타입 정리 ✨ (0) | 2024.01.26 |
[자바스크립트] closure 정리 ✨ (0) | 2024.01.24 |
[자바스크립트] this 정리 ✨ (1) | 2024.01.23 |