ES6 Modules(모듈)

Daye Kang·2020년 5월 3일
0

Q. 왜 '모듈화'를 하게 되었을까?


  이전의 자바스크립트는 스크립트를 나눌 필요없을 정도로 작업의 크기가 크지 않았다. 하지만 웹 프로그래밍이 발전하고 프로젝트의 크기가 커지면서 자바스크립트의 스크립트를 더 작은 단위로 나눠야 할 필요성이 제기되었다. 어떤 '효율성'의 측면에서 스크립트를 '모듈화'할 필요가 생긴 것이다.

  서버사이드 자바스크립트 런타임 환경인 NodeJS에서는 더 일찍 '모듈화'에 대한 시도가 이루어졌고, CommonJs와 RequireJS와 같은 라이브러리와 프레임워크가 만들어졌다. NodeJS에서는 표준은 아니지만 모듈이 지원되며, 모듈 별로 독립적인 스코프인 '모듈 스코프'를 갖는다.

  이러한 상황에서 ES6에서는 클라이언트 사이드 자바스크립트에서도 동작하는 모듈 기능이 추가 되었다. 하지만 몇 가지 이슈로 인하여 브라우저가 지원하는 ES6 모듈 기능보다는 Webpack, Babel 등의 모듈 번들러를 사용하는 것이 일반적이다.


'모듈', export

모듈화를 하는 첫 번째 특징은 export를 이용해 재사용할 스크립트를 외부에서 이용할 수 있게 하는 것.

// app.js

export const name = "jenny";

export function sum (a, b) {
  
    let total = a + b;
    
    return total;
}

function, var, let, const, 그리고 class까지 export 가능하며, 선언 전에 위치해야 함.
함수 내부에서 이용할 수 없다.

더 간단한 방법은 {} 안에 다 넣고 export 하는 것!

export { name, sum };  

'모듈', import

모듈화의 두 번째 특징은 외부의 스크립트에서 export한 스크립트를 import를 이용해 외부의 스크립트의 내부에서 이용하게 하는 것.

// main.js

import { name, sum } from './app.js';  

console.log(name); // jenny
console.log(sum(1, -5)); // -4

const sayHi = (name) => {
  
  let greeting = "Hello, " + name;
  
  return greeting; // "Hello, jenny"
}
  

import로 가져온 외부 스크립트는 내부 스크립트에서 선언된 것처럼 이용할 수 있다.

+ import 구문의 'from' 뒤 모듈이 라이브러리인 경우 경로를 지정해주지 않아도 되지만, 직접 생성해준 모듈일 경우 파일 경로를 지정해야 함.

import axios from 'axios'; // 라이브러리인 경우 경로 지정이 따로 없음

import something from '현재 파일을 기준으로 경로/모듈이름'

선언과 동시에 export

변수명을 선언하는 구문 앞에 바로 export를 붙여주면 선언과 export를 한 번에 할 수 있다.

// app.js

export const name = "haily";

export const age = "20";

export function greeting(name) {
  
  let sayHi = "Hello, " + name + "!";
  
  return sayHi;
}

export class Person {
  // ...
}

// main.js

import { name, age, greeting, Person } from "./app.js";

export default와 import

export default는 모듈에서 하나만을 지정할 때 사용.

// app.js

export default function boring(name) {
   return "you are so boring!, " + name;
  
// main.js
import Boring from "./app.js";
  // export default 로 가져온 모듈은 중괄호를 사용하지 않고 임의의 이름으로 가져올 수 있다.
}

하지만 let, var, const는 export default로 내보낼 수 없다.

export default () => {};
// => OK

export default const foo = () => {};
// => SyntaxError: Unexpected token 'const'

import 구문에서는 export defaultnamed export 모듈 모두를 함께 불러올 수 있다.

// `export default`로 선언된 모듈은 중괄호 없이, `named export`로 선언된 모듈은 {} 안에

import React, { Component, Fragment } from "react";

다른 이름으로 export & import

  각각의 모듈에서 같은 변수명으로 선언했을 경우 모듈 스코프에 의해 충돌이 발생하지 않는다. 하지만 한 파일에서 각각 다른 모듈의 '변수명이 같은 변수'를 export하면 import한 파일에서는 충돌이 발생할 수 밖에 없다. 이를 피하고자 export 혹은 import하는 이름의 뒤에 'as'를 붙여 다른 이름으로 변수명을 대체한다.
흡사 '다른 이름으로 저장하기'와 같음.

exportimport 할 때 지정해주면 ok!

// export 할 때

// module.js
export {
  func1 as newFunction,
  func2 as anotherNewFunction
};

// main.js
import { newFunction, anotherNewFunction } from './module.js';
// import 할 때

// module.js
export { func1, func2 };

// main.js
import { func1 as newFunction,
         func2 as anotherNewFunction } from './module.js';

그렇다면,

이렇게 스크립트를 작게 나눠서 모듈화를 하면 뭐가 좋을까?

  • 자주 사용되는 코드를 별도의 파일로 만들어 필요할 때마다 재사용 가능.
  • 코드 수정 시, 필요한 로직을 빠르게 찾을 수 있고, 그 모듈을 사용하는 애플리케이션의 동작의 개선이 이루어짐.
  • 필요한 로직만을 로드해서 메모리의 낭비를 줄일 수 있음.
  • 한번 다운로드된 모듈은 웹브라우저에 의해 저장되므로 동일한 로직을 로드 할 때,
    시간과 네트워크 트래픽을 절약 가능. (브라우저에서만 해당)




더 많은 내용을 알고 싶다면!
==> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

profile
뭐든 하자

0개의 댓글