모듈이란
js 파일을 분리 시킬 때 사용한다
여러 개의 파일로 분리하여 script 태그로 로드하여도 분리된 자바스크립트 파일들이 결국 하나의 자바스크립트 파일 내에 있는 것처럼 하나의 전역 객체를 공유한다. 따라서 분리된 자바스크립트 파일들이 하나의 전역을 갖게 되어 전역 변수가 중복되는 등의 문제가 발생할 수 있다.
script 태그에 type="module"
어트리뷰트를 추가하면 로드된 자바스크립트 파일은 모듈로서 동작한다. ES6 모듈의 파일 확장자는 모듈임을 명확히 하기 위해 mjs를 사용하도록 권장한다.
<script type="module" src="lib.js"></script>
<script type="module" src="app.js"></script>
// lib.js
var x =1;
// app.js
console.log(window.x); // 1
console.log(x); // 1 출력됨 똑같은 전역객체를 공유하기 때문
------------------------------------------------------------------------
<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>
// lib.mjs (모듈)
var x =1;
console.log(window.x); // 에러발생
console.log(x); // 1
// app.mjs (모듈)
var y = 2
console.log(x); // 에러발생
console.log(y); // 2
console.log(window.y); // 에러발생
export 키워드
모듈을 사용하면서 선언한 식별자를 외부에서도 사용하고 싶을 때 export를 사용하여 할 수 있다. 선언된 변수, 함수, 클래스 모두 export할 수 있다.
// lib.mjs
// 변수의 공개
export const pi = Math.PI;
// 함수의 공개
export function square(x) {
return x * x;
}
// 클래스의 공개
export class Person {
constructor(name) {
this.name = name;
}
}
// 앞에 export를 직접 붙이지 않고 변수, 함수 클래스를 하나의 객체로 구성하여 공개가능
export { pi, square, Person };
import 키워드
export한 식별자들을 로드할 때 사용한다.
// app.mjs
// 같은 폴더 내의 lib.mjs 모듈을 로드.
// lib.mjs 모듈이 export한 식별자로 import한다.
// ES6 모듈의 파일 확장자를 생략할 수 없다.
import { pi, square, Person } from './lib.mjs';
console.log(pi); // 3.141592653589793
console.log(square(10)); // 100
console.log(new Person('Lee')); // Person { name: 'Lee' }
//이름을 변경하여 import할 수도 있다.
// app.mjs
import { pi as PI, square as sq, Person as P } from './lib.mjs';
console.log(PI); // 3.141592653589793
console.log(sq(2)); // 4
console.log(new P('Kim')); // Person { name: 'Kim' }
모듈이 export한 식별자를 각각 지정하지 않고 하나의 이름으로 한꺼번에 import할 수도 있다. 이때 import되는 식별자는 as 뒤에 지정한 이름의 객체에 프로퍼티로 할당된다.
// app.mjs
import * as lib from './lib.mjs';
console.log(lib.pi); // 3.141592653589793
console.log(lib.square(10)); // 100
console.log(new lib.Person('Lee')); // Person { name: 'Lee' }
모듈에서 하나만을 export할 때는 default 키워드를 사용할 수 있다.
default 키워드와 함께 export한 모듈은 {} 없이 임의의 이름으로 import한다.