재사용 가능한 코드 조각
모듈은 기본적으로 캡슐화되어 자신만의 스코프를 가지고 애플리케이션과 분리되어 존재한다. 그래서 공개가 필요한 자산에 한정해서 명시적으로 선택적 공개를 한다.(export)
모듈 사용자는 모듈이 공개한 자산 중 일부 또는 전체를 선택해 자신의 스코프 내로 불러들여 재사용할 수 있다.(import)
클라이언트 사이드 자바스크립트는 script 태그를 사용하여 외부의 자바스크립트 파일을 로드할 수는 있지만 파일마다 독립적인 파일 스코프를 갖지 않는다. 즉, script 태그로 로드해도 분리된 자바스크립트 파일들은 하나의 자바스크립트 파일 내에서 있는 것처럼 동작한다.
자바스크립트를 브라우저 환경에 국한하지 않고 범용적으로 사용하려고 CommonJS와 AMD가 제안되었다.
ESM은 독자적인 모듈 스코프를 갖는다.
// foo.js
// x 변수는 전역 변수다.
var x = 'foo';
console.log(window.x); // foo
// bar.js
// x 변수는 전역 변수다. foo.js에서 선언한 전역 변수 x와 중복된 선언이다.
var x = 'bar';
// foo.js에서 선언한 전역 변수 x의 값이 재할당되었다.
console.log(window.x); // bar
<!DOCTYPE html>
<html>
<body>
<script src="foo.js"></script>
<script src="bar.js"></script>
</body>
</html>
HTML에서 script 태그로 분리해서 로드된 2개의 자바스크립트 파일은 하나의 자바스크립트 파일 내에 있는 것처럼 동작한다. 따라서, x변수가 중복 선언되며 의도치 않게 x 변수 값이 덮어써진다.
ESM 내에서 var로 선언된 변수는 더는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다. 또한, 모듈 내에서 선언한 식별자는 모듈 외부에서 참조할 수 없다. 모듈 스코프가 다르기 때문이다.
// foo.mjs
// x 변수는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.
var x = 'foo';
console.log(x); // foo
console.log(window.x); // undefined
// bar.mjs
console.log(x); // ReferenceError: x is not defined
모듈 내부에서 선언한 식별자를 외부에 공개하여 다른 모듈들이 재사용할 수 있게 하려면 export 키워드를 사용한다.
대상이 여러개라면 export 할 대상을 하나의 객체로 구성하여 한 번에 export할 수도 있다.
다른 모듈에서 공개한 식별자를 자신의 모듈 스코프 내부로 로드하려면 import 키워드를 사용한다.