ES6 Module 의 Syntax
해당 문서에선 ES6 모듈의 문법인 export, import, 그리고 type="module"을 붙인 스크립트와 그렇지 않은 스크립트의 차이점에 대해서 알아봅니다.
export
export 되는 모듈은 항상 strict mode 입니다.
export 구문은 type='module' 이 없는 embedded script 에서는 사용할 수 없습니다.
export 는 다음 두 가지 스타일의 방식이 있습니다.
- Named Exports (하나의 모듈에 0 ~ N 개의 대상을 내보낼 수 있습니다.)
- Default Exports (하나의 모듈에 1개의 대상만 내보낼 수 있습니다.)
named exports
named exports 는 모듈 내에 여러 번 사용할 수 있으며, var, let, const, function, class 를 export 할 수 있습니다. exports 는 top-level 에 있는 한 어느 위치에서든 사용할 수 있습니다.
// 선언 이전에 export 할 수 있습니다.
export { myFunction, myVariable };
export let myVariable = Math.sqrt(2);
export function myFunction() {
/* ... */
}
// 선언 이후에도 가능합니다.
// export { myFunction, myVariable };
default exports
default exports 는 모듈 내에 단 한번만 사용할 수 있습니다.
여러 번 사용하면 이전에 default 로 지정한 대상은 덮어씌워집니다.
export default function () { /* ... */ }
export default class { .. } // 이전 대상을 덮어씌웁니다.
'as' alias
as 를 사용하면 기존 식별자 대신 다른 별칭으로 대상을 export 할 수 있습니다.
export { myFunction as function1, myVariable as variable };
as alias 로 default 를 내보낼 수도 있습니다. 아래 두 구문은 같은 default export 입니다.
export { myFunction as default };
export default myFunction;
Re-exporting / Aggregating
다른 모듈에서 export 한 대상을 가져와 다시 export 하거나, 합쳐서 export 할 수 있습니다.
예를 들어, math 라는 폴더 아래에 add, divide 라는 모듈이 있다고 가정해봅시다.
~/math
ㄴ add.js
ㄴ divide.js
ㄴ index.js
index.js 에 각 모듈을 가져와 다시 export 해줌으로써 하나의 경로로 import 되게 할 수 있습니다.
// index.js
import { default as add } from './add.js';
import { default as divide } from './divide.js';
export { add, divide };
import
export 와 마찬가지로 import 되는 대상은 항상 strict mode 에 있습니다.
import 구문은 type='module' 이 없는 embedded script 에서는 사용할 수 없습니다.
만약, 해당 속성이 없는 embedded script 에서 module 을 import 해야 하는 경우, import() 사용을 고려할 수 있습니다.
ES6 에서 import 는 read-only view 입니다. 즉, 해당 값을 수정할 수 없으며 오직 read 할 수만 있습니다.
export let counter = 3;
export function add() {
counter++;
}
//------ main.js ------
import { counter, add } from './module';
console.log(counter); // 3
add();
console.log(counter); // 4
// import 된 대상은 수정할 수 없습니다.
counter++; // TypeError
ES6 에서 모듈은 singleton 이므로, 여러 번 import 하더라도 하나의 instance 만 존재합니다.
즉, 위의 예시 처럼 counter 를 변경한다 하더라도 another.js 에서 import 하는 경우 다른 counter 를 가지게 됩니다.
single, multiple importing
import { myExport } from '/modules/my-module.js';
import { foo, bar } from '/modules/my-module.js';
<script> vs <script type='module'>
ES6 로 파일을 모듈 방식으로 불러오려면 <script type='module'> 과 같이 작성해야 합니다.
이 방식을 취하면 <script> 와 아래와 같은 차이를 보입니다.
- strict mode
- 후자는
use strict같은 구문의 존재 여부와 관계 없이strict mode에 존재하게 됩니다.
- 후자는
- 변수 범위
- 전자는 top-level 에 있는 변수들이
global객체에 존재하게 됩니다. 후자는 모듈 공간에서의 top-level 로 존재하며 export 하지 않으면 다른 모듈에서 참조할 수 없습니다.
- 전자는 top-level 에 있는 변수들이
- 실행 방식
- 전자는 대상 파일을 동기적으로 실행합니다. 후자는 비동기적으로 실행합니다. 이 때문에 import 하는 대상의 load 여부를 염두하지 않고 코드를 작성할 수 있습니다.
- import, export 구문 사용 가능 여부
- 전자는
import구문을 사용할 수 없습니다. 어떤 파일을 읽어오려면import()를 사용해야 합니다.
- 전자는