[JS] ES모듈

Yuno·2021년 6월 7일
0

모던JS

목록 보기
10/16
post-thumbnail

개발하는 애플리케이션이 커지면 파일을 분할하여 작성해야 합니다.
이런 파일을 모듈이라 하는데,
클래스 하나 혹은 특정 목적을 가진 여러 함수로 구성된 라이브러리 하나로 구성됩니다.

자바스크립트도 스크립트의 크기가 커지고, 기능이 복잡해지자
커뮤니티는 라이브러리를 만들어, 모듈시스템을 구현했습니다.

  • AMD, CommonJS, UMD

이러한 모듈 시스템은 요즘엔 잘 쓰이지 않습니다.

ES모듈 시스템은 2015년에 표준으로 등재되어, 주요 브라우저나 Node.js에서도 지원합니다.

ES모듈

모듈은 파일 하나입니다.

모듈에 지시자 export, import를 적용하면 다른 모듈을 불러와 모듈의 함수를 호출하는 등
기능 공유가 가능합니다.

export 지시자를 사용해 내보냅니다.

export function sayHi(currentUser) {
    alert(`hi ${currentUser}`);
}

import 지시자를 사용해 불러옵니다.

//다른파일
import {sayHi} from './hello.js';
`
sayHi(currentUser);

모듈은 특수한 키워드와 함께 사용되므로, 속성을 설정하여
해당 스크립트가 모듈이라는걸 브라우저가 알게 해야 합니다.

<script type='module'>
  import {sayHi} from './hello.js';
  
  sayHi();
</script>

모듈은 로컬파일에서 동작하지 않습니다.
file:// 프로토콜로 페이지를 열면 import export지시자가 동작하지 않습니다.

모듈의 핵심 기능

엄격모드로 실행

모듈은 항상 엄격모드 use strict입니다.
선언되지 않은 변수에 값을 할당하는 등의 코드는 에러를 일으킵니다.

모듈 레벨 스코프

모듈은 자신만의 스코프가 있습니다.
모듈 내부에서 정의한 변수나 함수는 다른 스크립트에서 접근할 수 없습니다.

전역변수를 대신하여, hello.jsuser.js를 불러와 필요한 기능을 얻을 수 있습니다.

브라우저 환경에서도 type=module을 통해 모듈을 만들면, 독립적인 스코프가 생깁니다.

<script type='module'>
  let user = 'aa'
</script>

<script type='module'>
  alert(user); // error
</script>

한 번만 평가됨

동일 모듈이 여러 곳에서 사용되어도, 모듈은 최초 호출 한번만 실행됩니다.
실행 후 결과는 모듈을 가져가려는 모든 곳에 보내집니다.

객체를 내보내는 모듈을 만들어봅시다.

export let user = {
	name : 'john',
}

이 모듈을 사용하려는 객체가 많아도, 한 번만 평가됩니다.
그 때, user객체가 만들어지고 모든 모듈에 객체가 전달됩니다.

즉, 모두 같은 객체가 전달됩니다.

//1.js 
import {user} from './user.js';
user.name = 'yuno';

//2.js
import {user} from './user.js';
alert(user.name) // yuno

이런 특징을 사용하면 모듈 설정을 쉽게 할 수 있습니다.
최초로 실행되는 모듈의 프로퍼티를 설정하면, 다른 모듈에서 이 설정을 그대로 사용할 수 있습니다.

init.js라는 처음 실행되는 스크립트에서 설정해주면,
다른 스크립트에서도 저장된 정보를 확인할 수 있습니다.

내보내고 불러오는 방법들

선언부 앞에 export 붙히기

변수, 함수, 클래스를 선언할 때 앞에 export를 붙히면 내보낼 수 있습니다.

export function init() {...}

export let id = 5;

export class User {...}                        

한번에 export

선언을 먼저하고, 한번에 export할 수 있습니다.

function init() {...}
let id = 5;
                 
export {init,id}; // init과 id를 내보냄

import

모듈에서 가져올 때는 import {...}를 적으면 됩니다.

import {init, id} from './user.js'; // init과 id를 가져옵니다.

import *

import * as user from './user.js'; // user.js에서 내보낸 모든것을 가져옵니다.

다만, import *은 웹팩과 같은 빌드 툴의 최적화에 방해가 될 수 있습니다.
빌드 툴은 사용하지 않는 함수를 파악해, 최종 번들링에 포함하지 않습니다.

as

as 키워드를 사용해 이름을 바꿔 가져올 수 있습니다.
export에도 사용하여, 내보낼 이름을 지정할 수 있습니다.

//user.js
export {sayHi as hi};

// main.js
import {hi as alertHi} from './user.js';

default

모듈은 2가지로 나뉠 수 있습니다.

  1. 복수의 함수가 있는 라이브러리 형태
  2. 개체 하나만 선언되어있는 모듈 ( class User )

모듈에 개체가 하나만 선언되어 있을 때, default로 하나만 선언되었음을 나타낼 수 있습니다.

export default class User {...}

이렇게 하면 중괄호 없이 모듈을 가져올 수 있습니다.

import User from './user.js';

default 모듈은 하나의 모듈이 정해졌기 때문에, 이름이 다르더라도 가져올 수 있습니다.
또한 defualt export의 개체는 이름이 없어도 괜찮습니다.

한 파일엔 보통 default exportnamed export중 하나만 사용합니다.

profile
web frontend developer

0개의 댓글