ES6 Module : import, export
javascript에 드디어 추가된 모듈화 기능
javascript에서는 모듈화와 관련된 기능을 제공하지 않았다. 물론 모듈화를 위한 다양한 라이브러리나 도구가 존재하지만 javascript 언어 레벨에서 모듈화 기능을 제공하지 않는다는 점은 javascript가 가진 단점 중 하나였다. 그런데 ECMAScript에서 반가운 소식이 들려왔다. ES6부터는 모듈화 기능을 추가된다는 것이다.
javascript는 원래 언어 차원에서 모듈화를 위한 기능을 제공하지 않았다. 그래서 개발자가 기능별로 나누어둔 모듈을 사용하거나 다른 개발자가 구현한 라이브러리를 사용할떄에는 아래처럼 직접 의존성에 신경쓰며 순서대로 스크립트를 불러와야했다.
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
이에 많은 javascript 개발자를 불만을 가져왔으며 결국 모듈화 표준을 정하기 위해서 CommonJS나 AMD가 등장하기에 이르렀다. 아래는 AMD를 스팩을 구현한 RequireJS를 사용한 코드이다.
define([
'module1'
], function(module1) {
'use strict';
console.log(module1.text);
});
이를 통해 더 이상 개발자가 번거롭게 <script>
태그를 넣을 필요도 없고, 의존 관계를 설정해주기만 하면 자동으로 순서에 맞추어 javascript 코드들을 로딩할 수 있다.
이외에도 Webpack과 같은 빌드툴을 이용해서 모듈별로 나뉘어진 javascript를 배포할때에는 하나의 js파일로 minify해서 배포하는 방법도 있다.
하지만 여전히 javascript 언어 차원에서 모듈화 기능을 제공하는 것이 아니니 여전히 불편한 점을 가지고 있고 불만을 가진 개발자도 많았다. 그런데 마침 javascript 진영에서 좋은 소식이 들려왔다. ES6부터는 이제 javascript 언어 차원에서 모듈화 기능을 제공한다는 것이다. 안타깝게도 현재 import와 같은 ES6의 모듈화와 관련된 기능을 구현한 브라우저는 없지만, babel 같은 javascript 컴파일러나 ES6를 구현한 transpiler를 사용해서 얼마든지 사용할 수 있다. ES6를 포함하고 있는 Typescript 역시 모듈화 기능을 구현하고 있다.
ES6의모듈화 기능
ES6부터는 import와 export 키워드를 제공한다. 먼저 import부터 알아보자.
import
import는 java나 python 같은 다른 언어에서도 많이 보이는 키워드인데 기능 역시 비슷하다. 외부의 모듈을 불러오는 기능을 하며 그 문법은 python과 비슷하다. javascript에서는 import 다음에 바인딩할 이름이 오거나 멤버를 지정할 수 있으며, from 다음에는 해당 모듈의 경로가 문자열로 들어가게 된다. 아래는 javascript에서 import를 수행하는 예제이다.
import * as myModule from 'module1.js'
위 예제는 module1.js로부터 모든 클래스 및 함수 등을 현재 영역의 myModule에 바인딩하겠다는 의미이다. 원한다는 전체가 아닌 원하는 멤버가 가져올 수도 있다.
import {func1} from 'module1.js'
import {func1, func2, class1} from 'module1.js'
import {longNameField as myField} from 'module1.js'
import 'module1.js'
위 예제처럼 원하는 멤버가 가져올 수 있다. 오직 하나만 가져오는게 아니라 2개 이상의 멤버도 가져올 수 있으며, as를 사용해서 가져온 멤버를 원하는 이름으로 별명을 지어줄 수 있다. 바인딩은 필수가 아닌 선택이다. 원한다면 바인딩을 하지않고 모듈만 로딩할 수 있다.
import myDefault from 'module1.js'
위 코드와 같이 중괄호({})가 없는 겅우에는 module1으로부터 기본값만을 가져온다. 기본값이 무엇을 말하는지는 다음에 설명할 export를 보면 알 수 있을 것이다.
export
import로 외부에서 A모듈을 가져온다면 해당하는 A모듈은 어떤 모듈을 외부에 제공할지 정해야한다. 이때 사용되는 것이 export이며 아래의 코드는 export의 사용예이다.
export {myFunction};
export const kb = Math.pow(2, 10);
export의 사용법도 간단한다. export할 함수나 클래스를 export 키워드 옆에 작성해주면 된다. 또한 const를 함께 작성하면 상수로서 사용할 수 있다. 또 export를 처음부터 함수나 클래스를 선언할때 함께 사용할 수도 있다.
export function foo(x) {
return x + x;
}
위 예제처럼 함수나 클래스를 선언하기 전에 export라고 먼저 선언하고 정의하면 됩니다. 이외에도 export에는 기본값을 제공하는 default 기능이 있습니다.
export default foo;
export default를 사용하면 이 모듈의 사용자가 어떤 멤버도 지정하지 않았을때 기본적으로 제공할 값(또는 객체, 함수 등)을 정의할 수 있습니다. import 부분의 마지막에 설명했던 기본값 import가 이 값을 가져옵니다.
전체적인 예제
ES6에 새롭게 추가된 import와 export를 사용해서 이제 javascript에서도 이제 변하게 모듈별로 나누어서 개발을 할 수 있습니다!(아직은 완전히 지원하는 브라우저가 없어서 추가적인 도구가 필요하지만요ㅠㅠ)
// module1.js
export function foo(x) {
return x + x;
}
// module2.js
import {foo} from 'module1.js';
console.log(foo(10));