-
Common JS와 ES 모듈의 차이점자바스크립트/CS 2023. 7. 29. 06:10
// CJS 방법 module.exports = { ... } // 모듈 내보낼 때 const utils = require('utils'); // 모듈 가져올 때 // ESM 방법 export.default =()=> { ... }; // 모듈 내보낼 때 import utils from 'utils'; // 모듈 가져올 때
기존의 require는 하나의 객체에 함수나 변수를 복사하여 전역변수처럼 사용했다.
이에 import는 원본 파일을 참조하는 함수를 정의하여 export한다.
출처: https://yoeubi28.medium.com/commonjs-esm-%EB%AA%A8%EB%93%88-%EC%88%9C%ED%99%98-%EC%B0%B8%EC%A1%B0-%EC%B0%A8%EC%9D%B4-e5cd1047deaf 만약 메인함수에서 export한 변수의 값을 1초뒤에 변경하도록 하고,
이를 require/import한 함수에서 값을 변경하기 전/후로 값을 출력해보면,
CJS에선 (원본을 복사해서 왔기에) 변경된 값이 적용되지 않은 반면
ESM에선 (원본을 참조하고 있기에) 변경된 값이 실시간/비동기적으로 적용된다.
비슷한 예로 변수 a에 값 2를 넣고 export한 다음 값을 1로 바꾸면
a를 import한 ESM은 a를 출력시 1을,
a를 require한 CJS는 2출력한다.
또 변수 a를 require하면 해당 값은 복사된 값이므로 let으로 선언했으면 값 변경이 가능하지만
import한 값은 원본을 참조중이므로 무조건 상수로 취급되어 수정 불가능하게 바뀐다.
(배열이나 객체는 된다!)
이러한 차이로 인해 두 모듈이 서로 종속관계인 "순환 참조"의 경우
CJS에선 빈 값을 복사해서 오류가 발생하지 않지만
ESM에선 없는 값을 참조중이라 오류가 발생한다.
Commonjs, Esm 모듈 , 순환 참조 차이
TL;DR
yoeubi28.medium.com
자세한건 해당 글에
import * as url from 'url'; const __filename = url.fileURLToPath(import.meta.url); const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); //알파고님님님의 코드 import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); //블로그에서 찾은 코드
CJS엔 현재 파일/폴더의 절대경로가 __filename, __dirname에 자동으로 들어가지만 ESM에선 직접 선언해야한다.
왜 ESM에는 없나 인터넷을 뒤져봐도 만족스러운 답변이 없기에 ChatGPT에게 질문
그 이유는 알파고님이 말씀하시길 __dirname의 값이 비동기적으로 바뀔 수 있어서라고 한다.
참조한 글
https://velog.io/@jjunyjjuny/ES-Modules-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0
[ JavaScript ] ES Modules 정리하기
ES Modules에 대해서!
velog.io
'자바스크립트 > CS' 카테고리의 다른 글
typeof(null) (0) 2023.08.10 Observer Pattern (0) 2023.07.31 JS 주소 공간, 얕은 복사와 깊은 복사 (0) 2023.07.29 이벤트 루프 (0) 2023.07.29 얕은 복사와 깊은 복사 (0) 2023.07.25