[ES6] Module

sangminnn·2020년 4월 10일
0

글로 정리하는 ES6

목록 보기
8/11

개념

먼저 모듈(Module) 이란 무엇일까 ? 왜 나타나게 되었을까 ?

일단 개념부터 알아보자면, 모듈이란 애플리케이션을 구성하는 개별적 요소로서 재사용 가능한 코드 조각을 말한다.

일반적으로 모듈은 파일 단위로 분리되어 있으며, 애플리케이션은 필요에 따라서 모듈을 로드하여 재사용한다.

사실 다른 언어에는 이러한 모듈기능을 다 가지고 있는 반면, Javascript는 태생 자체가 웹페이지의 보조적 기능을 수행하기 위해 만들어졌기 때문에 한계가 있었다.

이것은 script 태그를 통해서 js 파일을 받아올 수는 있었지만, 이렇게해서 여러개의 파일을 받아올 경우 이 파일들이 모두 하나의 전역 객체를 공유하기때문에, 같은 이름의 변수나 method가 존재할 경우 문제가 발생하게된다.

자바스크립트는 기본적으로 Client Side 에서 사용하기 위해 만들어진 개념으로 이전 챕터에서 언급했던것과 같이 자바스크립트는 스크립트 언어로서 이를 해석해주는 해석기가 존재해야하고, 브라우저에 있는 Javascript Engine에 의해서 해석이 되어 동작하는 것이다.

하지만 자바스크립트를 Client Side에만 국한하지 않고 범용적으로 사용하려는 움직임이 생기면서(Node.js) 이를 해결하려는 방법으로 CommonJS와 AMD(Asynchronous Module Definition)라는 라이브러리가 나타났다.

( 이에 관한 자세한 글은 https://d2.naver.com/helloworld/12864 에 자세히 나와있으니 읽어보시는 것을 추천드립니다. )

이후 라이브러리를 사용하는 것이 아니라, Javascript 자체에 모듈 기능을 수행할 수 있는 기능을 만들었는데, 이것이 ES6에서 등장한 module 개념이다.

ES6 모듈은 파일 자체의 스코프를 제공한다. 즉, ES6 모듈은 독자적인 모듈 스코프를 갖기 때문에, 하나의 전역 객체에서 중복되는 일을 걱정할 필요가 없다.

사용 방법

먼저, 기존의 CommonJS의 경우와 ES6에서 새로 도입된 module 의 사용방법을 코드로 보고 확인해보자.

// ES5 + CommonJS

// import
var hello = require('./hello.js');

// export
module.exports = hello;


// ES6 Module

// import
import hello from './hello.js';

// export
export default hello;

간단하게 둘의 import와 export 동작을 구분해보면 이렇게 되겠다.

이번 글은 ES6의 import/export에 관한 글이기 때문에, 비교는 여기까지하고 import/export의 여러가지 방법에 대해 알아보자.

1. 하나의 변수 혹은 함수를 외부로 보낼 경우


// hello.js

export default function hello() {
  	console.log("hello, everyone!");
}

// index.js

import hello from './hello';

위의 경우와 같이 default 를 사용하여 export 하는 경우에는 해당 파일을 import할 경우 기본적으로 받아오는 변수, 함수를 지정할 때 사용한다.

즉, import문을 통해 해당 파일을 받아오면서 해당 파일의 default 값을 받아오는 것이기 때문에 하나의 파일에는 하나의 default 값만이 존재 해야한다.

또한 위의 코드에서 본것과 같이 import를 통해 불러오는 구문에서 import 뒤에는 default 값을 받아올 명칭을 마음대로 정해줄 수 있다.

예를 들자면, 아래와 같이도 선언이 가능한 것이다.

import myCustomHello from './hello';

2. 변수나 함수를 외부로 보낼 경우

1번의 경우는 default 값을 통해서 값을 외부로 보냈다면, default를 사용하지 않고도 변수와 함수를 보낼 수 있는 방법이 있지 않을까 ?

당연히 방법이 있다.

이번에도 먼저 코드를 보고 가보자.


// hello.js
export default function hello() {
    console.log("hello, everyone!");
};
export let variable = "variable plus!";
                
                
// index.js
import myCustomHello, { variable } from './hello';

위에 코드와 같이 default한 값이 아니라 해당 변수나 함수를 가지고 올 경우에는 그 변수나 함수 명을 그대로 적어주어야 한다.

하지만 이 경우는 해당 모듈에서 값을 가지고와서 현재 애플리케이션에 선언해주는 개념이기 때문에 각자 다른 모듈에서 값을 가지고 오더라도 동일한 이름의 값을 가지고 올 수는 없다.

import { variable } from './hello';
import { variable } from './bye';

// 이렇게 될 경우 Duplicate declaration Error 발생.

추가적으로 이렇게 가지고 온 변수는 기본적으로 Read-Only 속성이 적용되어 있기 때문에 이 값에 대해서 재정의하려고 한다면 Syntax Error가 발생한다.

import myCustomHello, { variable } from './hello';
myCustomHello(); // hello, everyone!
console.log(variable); // variable plus!

varialbe = "variable reset!" // SyntaxError

3. 가지고 온 변수, 함수의 이름 정해주기

그렇다면 위와 같이 동일한 이름을 가진 변수, 함수는 가지고 올 수 없는 것일까 ?

이것 역시도 당연히 해결 방법이 있다.

그 해결 방법으로는 as 를 사용하는 것인데, 여기서의 as는 alias 의 줄임말로 해당 변수, 함수에 별칭을 지어주는 것이다.

아래의 예시를 보자.

import { variable as var1 } from './hello';
import { variable as var2 } from './bye';

위와 같이 코드를 as 를 사용하여 별칭을 정해줄 경우, 각각 다른 모듈에서 가져온 동일한 이름의 변수, 함수라도 가지고 올 수 있게된다.

4. 여러가지 변수, 함수 한번에 가지고오기

지금까지 배운 내용을 바탕으로 생각해보았을 때, 만약 해당 모듈에서 굉장히 많은 변수와 함수가 있고, 이들중 다수의 변수, 함수를 가지고 와야 하는 경우가 생긴다면 하나씩 다 import로 불러줘야만 할까 ?

아니다. 기본적으로 프로그래밍 세계에서는 이러한 반복 작업은 지양된다.

그에 따라 해당 모듈에 있는 모든 변수와 함수를 한번에 가지고 올 수 있는 방법도 있는데, 이는 * 키워드를 사용하는 것이다.

* 키워드는 흔히 Wild card 라고 하는데, 원래 정규 표현식에서 모든 값을 가지고 오는데 사용하는 키워드로

이 개념이 확장되어서 이곳저곳에서 사용되기 때문에, 보통은 해당 대상의 모든 값을 가지고 온다고 알고있으면 좋다.

그러면 이제 예시를 보자.

import * as hello from './hello';
import * as bye from './bye';

console.log(hello.variable);
console.log(bye.variable);

이렇게 사용할 수 있게된다.

마치며

이 모듈 시스템은 실제 코딩에서도 굉장히 많이 사용하기 때문에

이번 포스팅을 통해 알고있던 개념에 대해서 더 확실하게 알 수 있는 좋은 시간이였다.

++) 오늘 글도 JBee 님의

https://jaeyeophan.github.io/2017/05/04/ES6-11-Modulization/

와 poiemaweb 의

https://poiemaweb.com/es6-module

를 보고 공부한 내용을 토대로 정리한 내용입니다.

profile
생각하며 코딩하려고 노력하는 개발자가 되겠습니다.

0개의 댓글