자바스크립트는 웹페이지에 보조적인 기능을 수행하기 위해 한정적인 용도로 만들어졌기때문에, 다른 프로그래밍 언어와는 달리 모듈기능을 지원하지 않았다
브라우저 상에서 동작하는 Java Script는 html파일 내에 script 태그로 로드하면 여러개의 js 파일을 로드할 경우, 하나의 파일로 merge 되며, 하나의 전역을 공유하게 된다. 따라서 분리된 자바스크립트 파일들의 전역변수가 중복되는 등의 문제가 발생할수 있다.
Java Script를 client-side에 국한하지 않고 범용적으로 사용하고자 하면서 등장한것이 CommonJS와 AMD(Asynchronous Module Definition)이다. 브라우저 환경에서 모듈을 사용하기 위해서는 CommonJS나 AMD를 구현한 모듈 로더 라이브러리를 사용해야한다.
자바스크립트 런타임 환경인 Node.js는 모듈시스템의 사실상 표준인 CommonJS를 채택했고, 현재는 CommonJS 사양과 100% 동일하지는 않지만 기본적으로 CommonJS 사양을 따르고 있다. 따라서 Node.js에서는 파일별로 독립적인 모듈스코프를 갖는다.
ES6는 클라이언트사이드js에서도 동작하는 모듈기능을 추가했다.
script태그에 type="module" 어트리뷰트를 추가해주고 파일의 확장자를 mjs를 사용하게되면 자바스크립트 파일은 모듈로 동작하게 된다.
모듈은 독자적인 모듈 스코프를 갖기때문에 모듈 내부에서 선언한 모든 식별자는 기본적으로 해당 모듈내부에서만 참조할수 있다. 모듈내부에서 선언한 식별자를 외부에 공개해서 다른 모듈들이 재사용할 수 있게하려면 export 키워드를 사용한다.
다른 모듈에서 공개한 식별자를 자신의 모듈 스코프 내부로 로드하려면 import 키워드를 사용한다. 다른 모듈이 export한 식별자 이름으로 import 해야하며 ESM의 경우 파일확장자를 생략할 수 없다!