ECMAScript 2015
by jbee
[ES6] 11. Modulization
ES6에서추가된import/export 구문을9가지Case로나누어정리해봤습니
다.
Module in Javascript
Module pattern이라고 들어보셨나요? ES5에서는기본적으로global에변
수가 할당되기 때문에, Namespace pattern, module pattern 등등의기법
들이필요했습니다. 또한CommonJS, AMD처럼같은언어에서환경에따라
다른방식으로소스코드를가져와사용해야했습니다. 이에대한부분은
JavaScript 표준을위한움직임: CommonJS와AMD를참고하시면될것 같
습니다.
ES6에서는이러한문제점을인식하고  import 라는구문을통해
Modulization을제공합니다. 하지만아쉽게도Safari를제외한다른브라우
저에서는아직지원을하지않습니다. 그렇기 때문에Webpack과 babel의도
움을받아테스트해볼수있습니다.
import & export
Case 1
함수를다른자바스크립트파일에서불러와실행해야하는경우에대한예제
코드입니다.
export function hello() {
console.log(`module1`);
}
import { hello } from './module1';
hello(); //module1
외부의자바스크립트파일에서다른자바스크립트파일에존재하는함수를문
제없이사용할수있게 되었습니다:)
 { ... } 는ES6의 destructuring 문법을사용한것입니다.
 module1.js 파일에서export가 붙은함수를import하는데그 중
 hello 라는함수를import하겠다는의미입니다. 이와같은방법으로여러함
수또는변수를export하고 import할수있습니다. 다른방법도살펴보겠습니
다.
Case 2
export default function hello() {
console.log(`module1`);
}
import module1 from './module1';
module1();// module1
 default 라는키워드가 보이시나요?  export 키워드를사용하여함수를
외부로노출시킬때,  default 라는키워드를붙여주면해당파일이import
되는경우기본적으로지정된함수또는변수를노출시키겠다라는의미입니다.
주로파일에서하나의함수또는변수를노출시킬경우에사용합니다.
 default 키워드를사용하게 되면특정함수나변수를import하는것이아
니므로import하는곳에서변수명또는함수명을임의로지정할수있습니다.
이번예제에서는 hello 라는함수이름을그대로사용하지않고
 module1 이라는이름을지정하여함수를호출했습니다.
Case 3
한파일에서default export는하나만가능합니다.  export default 로이
미export를한후에다른함수나변수를export하기 위해서는import할때
다음과 같은방법을사용해야합니다.
export default function hello() {
console.log(`module1`);
}
export let name = "jbee";
import module1, { name } from './module1';
module1();// module1
console.log(name);// jbee
 name 이라는변수를import하는경우에는반드시 name 이라는변수명으로
import해야겠죠? 다음의경우에는어떻게 될까요?
Case 3‑1
import module1, { name } from './module1';
module1();// module1
console.log(name);// jbee
name = "newName"; //SyntaxError!
import한name을다시정의하려고 하면SyntaxError가 발생합니다. import
된 name 이란변수는 read-only 속성이적용되기 때문입니다. 만약에다
음과 같은경우는어떻게 해야할까요?
Case 3‑2
export const name = "jbee";
export const name = "newName";
다른자바스크립트파일에서같은변수명을사용한경우입니다. 기존의방식대
로import를해볼까요?
import { name } from './module1';
import { name } from './module2';
default로export되지않은함수또는변수에대해서는반드시그 이름을지정
해야했습니다. 이럴경우에는 Duplicate declaration 에러가 발생합니
다.
Case 4
위에서발생한문제를해결하기 위한첫번째방법입니다.
import { name as module1Name} from './module1';
import { name as module2Name} from './module2';
console.log(module1Name);
console.log(module2Name);
 as 라는키워드가 등장했습니다.  alias 의줄임으로import한변수또는함
수에대해별명을지정할수있습니다. 이렇게 import를하면변수명끼리충돌
이일어나지않습니다:) 그러나변수명이점점많아지게 되면계속해서새로운
변수명을지정해줘야하는문제점이발생하게 됩니다.
Case 5
위의문제를조금 더개선해보겠습니다:)
import * as Module1 from './module1';
import * as Module2 from './module2';
console.log(Module1.name);
console.log(Module2.name);
 as 키워드를사용함과 동시에 * 이등장했습니다.  * 은import하고자하는
자바스크립트파일에서 export 키워드가 붙어있는모든함수, 변수를
import할때사용합니다. 그리고  as 키워드를통해서 namespace 를지정
해줘야합니다. 이렇게 import가 되면 Module1 이라는객체의프로퍼티로
import한변수또는함수에접근할수있습니다.
Case 6
export const obj = {
name: "Jbee",
age: 25
};
import { obj } from './module1';
console.log(obj.name);// Jbee
obj.name = "newName";
console.log(obj.name);// newName
위예제로부터Object를import하는경우에, Object의프로퍼티까지보호할
수없다는것을알수있습니다.
Case 7
여태까지정의함과 동시에export를할지말지결정했는데요, 자바스크립트
코드의마지막에서이를정의해줄수있습니다.
const obj = {
name: "Jbee",
age: 25
};
export { obj };
import { obj } from './module1';
console.log(obj.name);// Jbee
Case 8
Object를export하는경우 default 키워드를붙일수없습니다. 대신다른
방법이존재합니다.
const obj = {
name: "Jbee",
age: 25
};
export { obj as default };
import obj from './module1';
console.log(obj.name);// Jbee
 as default 라는키워드를붙여export할수있습니다. 이는함수또는변
수에도적용가능합니다.
Case 9
import 구문을class에도물론적용할수있습니다.
export default class Component {
constructor() {
console.log(`create component!`);
}
}
import Component from './module1';
new Component();
//create component!
import/export 5 convention from Airbnb ES6 Convention
여러가지방법으로import, export가 가능해졌기 때문에그 방식이개발자마
다달라서convention이필요해졌는데요, 그 중Airbnb가 제시하는바람직한
import/export convention을정리해봤습니다.
1) Wildcard( * ) 사용을자제하세요!
// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';
// good
import AirbnbStyleGuide from './AirbnbStyleGuide';
2) import함과 동시에export를하지말고 코드의마지막에서따로
export하세요!
// bad
// filename es6.js
export { es6 as default } from './airbnbStyleGuide';
// good
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;
3) 동일한path를import하는경우에는한줄에서모두import하세요!
// bad
import foo from 'foo';
// … some other imports … //
import { named1, named2 } from 'foo';
// good
import foo, { named1, named2 } from 'foo';
4) import 구문은호이스팅됩니다. 그러므로import문은모두상단에위
치시키세요!
// bad
import foo from 'foo';
foo.init();
import bar from 'bar';
// good
import foo from 'foo';
import bar from 'bar';
foo.init();
5) 하나만export하는경우에는default 키워드를붙여주세요!
// bad
export function foo() {}
// good
export default function foo() {}
마무리
이상9가지의case로ES6의import와export를정리해봤습니다:D
11. end

[ES6] 11. Modularization, import와 export

  • 1.
  • 2.
    [ES6] 11. Modulization ES6에서추가된import/export구문을9가지Case로나누어정리해봤습니 다.
  • 3.
    Module in Javascript Modulepattern이라고 들어보셨나요? ES5에서는기본적으로global에변 수가 할당되기 때문에, Namespace pattern, module pattern 등등의기법 들이필요했습니다. 또한CommonJS, AMD처럼같은언어에서환경에따라 다른방식으로소스코드를가져와사용해야했습니다. 이에대한부분은 JavaScript 표준을위한움직임: CommonJS와AMD를참고하시면될것 같 습니다.
  • 4.
  • 5.
  • 6.
    Case 1 함수를다른자바스크립트파일에서불러와실행해야하는경우에대한예제 코드입니다. export functionhello() { console.log(`module1`); } import { hello } from './module1'; hello(); //module1 외부의자바스크립트파일에서다른자바스크립트파일에존재하는함수를문 제없이사용할수있게 되었습니다:)  { ... } 는ES6의 destructuring 문법을사용한것입니다.  module1.js 파일에서export가 붙은함수를import하는데그 중  hello 라는함수를import하겠다는의미입니다. 이와같은방법으로여러함 수또는변수를export하고 import할수있습니다. 다른방법도살펴보겠습니 다.
  • 7.
    Case 2 export defaultfunction hello() { console.log(`module1`); } import module1 from './module1'; module1();// module1  default 라는키워드가 보이시나요?  export 키워드를사용하여함수를 외부로노출시킬때,  default 라는키워드를붙여주면해당파일이import 되는경우기본적으로지정된함수또는변수를노출시키겠다라는의미입니다. 주로파일에서하나의함수또는변수를노출시킬경우에사용합니다.  default 키워드를사용하게 되면특정함수나변수를import하는것이아 니므로import하는곳에서변수명또는함수명을임의로지정할수있습니다. 이번예제에서는 hello 라는함수이름을그대로사용하지않고  module1 이라는이름을지정하여함수를호출했습니다.
  • 8.
    Case 3 한파일에서default export는하나만가능합니다. export default 로이 미export를한후에다른함수나변수를export하기 위해서는import할때 다음과 같은방법을사용해야합니다. export default function hello() { console.log(`module1`); } export let name = "jbee"; import module1, { name } from './module1'; module1();// module1 console.log(name);// jbee  name 이라는변수를import하는경우에는반드시 name 이라는변수명으로 import해야겠죠? 다음의경우에는어떻게 될까요?
  • 9.
    Case 3‑1 import module1,{ name } from './module1'; module1();// module1 console.log(name);// jbee name = "newName"; //SyntaxError! import한name을다시정의하려고 하면SyntaxError가 발생합니다. import 된 name 이란변수는 read-only 속성이적용되기 때문입니다. 만약에다 음과 같은경우는어떻게 해야할까요?
  • 10.
    Case 3‑2 export constname = "jbee"; export const name = "newName"; 다른자바스크립트파일에서같은변수명을사용한경우입니다. 기존의방식대 로import를해볼까요? import { name } from './module1'; import { name } from './module2'; default로export되지않은함수또는변수에대해서는반드시그 이름을지정 해야했습니다. 이럴경우에는 Duplicate declaration 에러가 발생합니 다.
  • 11.
    Case 4 위에서발생한문제를해결하기 위한첫번째방법입니다. import{ name as module1Name} from './module1'; import { name as module2Name} from './module2'; console.log(module1Name); console.log(module2Name);  as 라는키워드가 등장했습니다.  alias 의줄임으로import한변수또는함 수에대해별명을지정할수있습니다. 이렇게 import를하면변수명끼리충돌 이일어나지않습니다:) 그러나변수명이점점많아지게 되면계속해서새로운 변수명을지정해줘야하는문제점이발생하게 됩니다.
  • 12.
    Case 5 위의문제를조금 더개선해보겠습니다:) import* as Module1 from './module1'; import * as Module2 from './module2'; console.log(Module1.name); console.log(Module2.name);  as 키워드를사용함과 동시에 * 이등장했습니다.  * 은import하고자하는 자바스크립트파일에서 export 키워드가 붙어있는모든함수, 변수를 import할때사용합니다. 그리고  as 키워드를통해서 namespace 를지정 해줘야합니다. 이렇게 import가 되면 Module1 이라는객체의프로퍼티로 import한변수또는함수에접근할수있습니다.
  • 13.
    Case 6 export constobj = { name: "Jbee", age: 25 }; import { obj } from './module1'; console.log(obj.name);// Jbee obj.name = "newName"; console.log(obj.name);// newName 위예제로부터Object를import하는경우에, Object의프로퍼티까지보호할 수없다는것을알수있습니다.
  • 14.
    Case 7 여태까지정의함과 동시에export를할지말지결정했는데요,자바스크립트 코드의마지막에서이를정의해줄수있습니다. const obj = { name: "Jbee", age: 25 }; export { obj }; import { obj } from './module1'; console.log(obj.name);// Jbee
  • 15.
    Case 8 Object를export하는경우 default 키워드를붙일수없습니다. 대신다른 방법이존재합니다. constobj = { name: "Jbee", age: 25 }; export { obj as default }; import obj from './module1'; console.log(obj.name);// Jbee  as default 라는키워드를붙여export할수있습니다. 이는함수또는변 수에도적용가능합니다.
  • 16.
    Case 9 import 구문을class에도물론적용할수있습니다. exportdefault class Component { constructor() { console.log(`create component!`); } } import Component from './module1'; new Component(); //create component!
  • 17.
    import/export 5 conventionfrom Airbnb ES6 Convention 여러가지방법으로import, export가 가능해졌기 때문에그 방식이개발자마 다달라서convention이필요해졌는데요, 그 중Airbnb가 제시하는바람직한 import/export convention을정리해봤습니다.
  • 18.
    1) Wildcard( * ) 사용을자제하세요! //bad import * as AirbnbStyleGuide from './AirbnbStyleGuide'; // good import AirbnbStyleGuide from './AirbnbStyleGuide';
  • 19.
    2) import함과 동시에export를하지말고코드의마지막에서따로 export하세요! // bad // filename es6.js export { es6 as default } from './airbnbStyleGuide'; // good // filename es6.js import { es6 } from './AirbnbStyleGuide'; export default es6;
  • 20.
    3) 동일한path를import하는경우에는한줄에서모두import하세요! // bad importfoo from 'foo'; // … some other imports … // import { named1, named2 } from 'foo'; // good import foo, { named1, named2 } from 'foo';
  • 21.
    4) import 구문은호이스팅됩니다.그러므로import문은모두상단에위 치시키세요! // bad import foo from 'foo'; foo.init(); import bar from 'bar'; // good import foo from 'foo'; import bar from 'bar'; foo.init();
  • 22.
    5) 하나만export하는경우에는default 키워드를붙여주세요! //bad export function foo() {} // good export default function foo() {}
  • 23.
  • 24.