Logo

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

자바스크립트 개발을 하다보면 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 키워드를 사용하여 좀 더 명시적으로 모듈을 불러오고 있습니다.

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

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

CommonJS 모듈 시스템의 필요성

많은 프로젝트에서 ES6 모듈 시스템을 점점 더 널리 사용되고 있는 추세이기는 하지만, 안타깝게도 아직까지 항상 import 키워드를 사용해서 코딩을 할 수 있는 것은 아닙니다. <script> 태그를 사용하는 브라우저 환경에서는 물론이고, Node.js에서도 ES Module을 지원하기 시작했지만, 여전히 하위 호환성을 위해서 CommonJS를 기본 모듈 시스템으로 채택하고 있기 때문에, Babel과 같은 ES6 코드를 변환(transpile)해주는 도구를 사용할 수 없는 상황에서는 좋든 싫든 require 키워드를 사용해야 합니다. 따라서 CommonJS 사용 방법도 어느 정도 숙지하고 있는 것이 도움이 됩니다.

개발자들이 실행 환경에 구애받지 않고 항상 최신 문법의 자바스크립트로 코딩할 수 있도록 도와주는 유용한 도구인 바벨(Babel)에 대해서는 별도 포스팅을 참고바랍니다.

주의 사항

CommonJS 방식으로 모듈을 내보낼 때는 ES6처럼 명시적으로 선언하는 것이 아니라 특정 변수나 그 변수의 속성으로 내보낼 객체를 세팅해줘야 합니다. 특히, 제일 햇갈리는 부분이 바로 유사해보이는 exports 변수와 module.exports 변수를 상황에 맞게 잘 사용해야 한다는 점입니다. 기본적으로 다음 2가지 규칙만 기억하시면 됩니다.

  1. 여러 개의 객체를 내보낼 경우, exports 변수의 속성으로 할당한다.
  2. 딱 하나의 객체를 내보낼 경우, module.exports 변수 자체에 할당한다.

복수 객체 내보내기

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

아래는 미국과 캐나다 달러를 상호 변환해주는 자바스크립트 예제 코드입니다. 이 파일에는 3개의 함수가 있는데 아래 2개의 함수만 다른 파일에서 접근할 수 있도록 내보내기를 하였습니다. exports 변수의 속성으로 내보낼 함수들을 세팅합니다.

currency-functions.js
const exchangeRate = 0.91;

function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

const canadianToUs = function (canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
};

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

exports.canadianToUs = canadianToUs; // 내보내기 1
exports.usToCanadian = usToCanadian; // 내보내기 2

복수 객체 불러오기

위에서 내보낸 여러 개의 객체는 require 키워드를 통해 한 번에 불러와 변수에 할당할 수 있으면, 그 변수를 통해서 내보낸 객체에 접근할 수 있습니다.

test-currency-functions.js
const currency = require("./currency-functions");

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

단일 객체 내보내기

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

이번에는 예제 코드를 살짝 수정하여 아래 두 개 함수를 객체로 묶어서 내보내기를 하였습니다. 내보낼 객체를 module.exports 변수에 할당해주면 됩니다.

currency-class.js
const exchangeRate = 0.91;

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

// 내보내기
const obj = {};
obj.canadianToUs = function (canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
};
obj.usToCanadian = function (us) {
  return roundTwoDecimals(us / exchangeRate);
};
module.exports = obj;

단일 객체 불러내기

위에서 내보낸 하나의 객체는 require 키워드를 통해 변수에 할당할 수 있으며, 그 변수를 통해서 일반 객체에 접근하는 것 처럼 속성에 세팅되어있는 함수에 접근할 수 있습니다.

test-currency-object.js
const currency = require("./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

마치면서

이상으로 CommonJS로 모듈을 내보내고 불러내는 기본적인 방법에 대해서 알아보았습니다.