Logo

자바스크립트 ES 모듈 내보내기/불러오기 (import)

자바스크립트로 개발하다보면 requireimport 키워드를 통해 외부 라이브러리를 불러오는 코드를 자주 보게 됩니다. require는 Node.js에서 예전부터 사용되고 있는 CommonJS의 키워드이고, import는 ES6(ES2015)에서 새롭게 도입되어 현재 자바스크립트 생태계에서 표준이 되어가고 있는 키워드입니다. 두 개의 키워드 모두 하나의 파일에서 다른 파일의 코드를 불러온다는 동일한 목적을 가지고 있지만, 비슷한듯 약간씩 다른 문법 때문에 개발자들을 혼란스럽게 하기도 하죠.

const express = require("express");

const app = express();
import express from "express";

const app = express();

예를 들어, 위 두 코드는 ExpressJS 라이브러리를 불러와서 서버 객체를 생성하는 동일한 작업을 수행하고 있습니다. CommonJS 방식을 따른 첫 번째 코드는 Ruby 언어처럼 require 키워드를 사용하여 여타 다른 변수를 할당하듯이 모듈을 불러오는 반면에, ES Module 방식을 따른 두 번째 코드는 Java나 Python 언어처럼 import 키워드를 사용하여 좀 더 명시적으로 모듈을 불러오고 있습니다.

이번 포스팅에서는 이 중 두 번째 방식인 ES6 기반 모듈 내보내기/불러오기 방법에 대해서 알아보겠습니다.

첫 번째 방식인 CommonJS 기반 모듈 내보내기/불러오기에 대해서는 관련 포스팅를 참고 바랍니다.

ES6 모듈 시스템의 이점

아무래도 ES6 모듈 시스템이 좀 더 최신 스팩이다 보니 CommonJS 방식 대비 여러 가지 이점들이 있습니다. 우선 import, from, export, default처럼 모듈 관리 전용 키워드를 사용하기 때문에 가독성이 좋습니다. 또한 비동기 방식으로 작동하고 모듈에서 실제로 쓰이는 부분만 불러오기 때문에 성능과 메모리 부분에서 유리한 측면이 있습니다. 뿐만 아니라 앞으로 다룰 Named Parameter와 같이 CommonJS에서는 지원하지 않는 기능들이 있습니다.

복수 객체 내보내기

먼저 하나의 자바스크립트 모듈 파일에서 여러 개의 객체를 내보내고 불러오는 방법을 알아보도록 하겠습니다.

CommonJS에서는 내보낼 복수 객체들을 exports 변수의 속성으로 할당하는 방식을 썼었는데, ES6에서는 import 키워드의 짝꿍인 export 키워드를 사용해서 명시적으로 선언해줍니다. 이 때 내보내는 변수나 함수의 이름이 그대로 불러낼 때 사용하게 되는 이름이 되기 때문에 이를 Named Exports라고 일겉습니다.

아래는 미국과 캐나다 달러를 상호 변환해주는 자바스크립트 예제 코드입니다. 이 파일에는 3개의 함수가 있는데 아래 2개의 함수만 다른 파일에서 접근할 수 있도록 내보내기를 하였습니다. 첫번째 방법처럼 선언과 동시에 내보낼 수도 있고, 두번째 방법처럼 선언 후에 별도로 내보낼 수도 있습니다.

currency-functions.js
const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기 1
export function canadianToUs(canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
}

// 내보내기 2
const usToCanadian = function (us) {
  return roundTwoDecimals(us / exchangeRate);
};
export { usToCanadian };

복수 객체 불러오기

여러 객체(Named Exports)를 불러올 때는 ES6의 Destructuring 문법을 사용해서 필요한 객체만 선택적으로 전역에서 사용하거나, 모든 객체에 별명을 붙이고 그 별명을 통해서 접근할 수도 있습니다.

test-currency-functions.js
// Destructuring
import { canadianToUs } from "./currency-functions";

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(canadianToUs(50));

// Alias
import * as currency from "./currency-functions";

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));
  • 실행 결과
50 Canadian dollars equals this amount of US dollars:
45.5
30 US dollars equals this amount of Canadian dollars:
32.97

단일 객체 내보내기

다음으로 하나의 자바스크립트 모듈 파일에서 단 하나의 객체를 내보내고 불러오는 방법을 알아보겠습니다.

CommonJS에서는 내보낼 단일 객체를 module.exports 변수에 할당하는 방식을 썼었는데, ES6에서는 그 대신 export default 키워드를 사용해서 명시적으로 선언해줍니다. 하나의 모듈에서 하나의 객체만 내보내기 때문에 이를 Default Export라고 일겉습니다.

이번에는 예제 코드를 살짝 수정하여 아래 두 개 함수를 객체로 묶어서 내보내기를 하였습니다. (객체 내에서 첫 번째 함수는 ES6 문법을 사용하였습니다) 이름이 필요없기 때문에 별도로 변수 할당 없이 바로 객체를 내보내기를 할 수 있습니다. 내보낼 때 어떤 이름도 지정하기 않기 때문에 불러올 때도 아무 이름이나 사용할 수 있습니다.

currency-object.js
const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기
export default {
  canadianToUs(canadian) {
    return roundTwoDecimals(canadian * exchangeRate);
  },

  usToCanadian: function (us) {
    return roundTwoDecimals(us / exchangeRate);
  },
};

굳이 꼭 변수에 할당하고 내보내기를 하고 싶다면 다음과 같이 작성할 수도 있습니다. 하지만 불러내는 쪽에서 반드시 이 obj라는 변수 이름을 사용하도록 강제되지는 않습니다.

currency-object.js
const obj = {
  canadianToUs(canadian) {
    return roundTwoDecimals(canadian * exchangeRate);
  },
};

obj.usToCanadian = function (us) {
  return roundTwoDecimals(us / exchangeRate);
};

export default obj;

단일 객체 불러오기

하나의 객체(Default Export)를 불러올 때는 간단하게 import 키워드를 사용해서 아무 이름이나 원하는 이름을 주고 해당 객체를 통해 속성에 접근하면 됩니다.

test-currency-object.js
import currency from "./currency-object";

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(currency.canadianToUs(50));

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));
  • 실행 결과
50 Canadian dollars equals this amount of US dollars:
45.5
30 US dollars equals this amount of Canadian dollars:
32.97

마치면서

이상으로 ES6에서 모듈을 내보내고 불러내는 두 가지 방법인 Named Exports와 Default Export에 대해서 알아보았습니다.

한 가지 주의하실 점은 Babel 없이 순수하게 Node.js 최신 버전으로 ES 모듈을 사용하고 계시다면, import를 사용할 때 .js 확장자를 붙여주서야 합니다. 자세한 내용은 아래 관련 포스팅를 참고 바라겠습니다.