카테고리 없음

Javascript 모듈 내보내기/불러오기(CommonJs, ES6) 사용법

bggbr 2021. 9. 25. 17:47

ES6 문법이 도입됨에 따라 node.js에서 import/export 문법을 사용할 수 있게 됐다.

그렇다면 import/export와 require/module.exports의 차이점은 무엇일까?

 

import/export에 대해 설명하기 전에

require과 module.exports에 대해 알아보자.

ES6 문법이 도입되기 전의 모듈 시스템은 CommonJs 방식이라고 한다.

CommonJs 방식에서 모듈을 내보내는 방법은 exports와 module.exports 두 가지 방식이다.

두 가지 방식의 차이점은 없다! 공식 문서에 따르면 exports는 module 객체의 exports를 참조하는 것 뿐이다.

// test.js
exports.test = function () {
	console.log('test');
};

exports.test2 = function () {
	console.log('test2');
};
// test.js
function test() {
	console.log('test');
}

function test2() {
	console.log('test2');
}

module.exports = {
	test,
	test2,
};

위 코드와 아래 코드는 차이가 없다. 콘솔 로그를 통해 결과를 살펴보면, 

exports = { test: [Function (anonymous)], test2: [Function (anonymous)] }
module = Module {
  ...
  exports: { test: [Function (anonymous)], test2: [Function (anonymous)] },
  ...
}

exports는 module 객체의 exports를 참조하고 있고 결과는 같은 것으로 알 수 있다.

 

이렇게 외부로 보낸 모듈을 받기 위해서는 require() 함수를 사용해야 한다. require() 함수는 module.exports를 리턴한다. 이에 대해 자세하게 알고 싶으면, (https://medium.com/@chullino/require-exports-module-exports-%EA%B3%B5%EC%8B%9D%EB%AC%B8%EC%84%9C%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-1d024ec5aca3)을 읽어보길 추천한다.

 

exports 사용할 때 아무런 코드를 넣지 않고 콘솔 로그를 출력해보면, 빈 객체인 것을 확인할 수 있다. 빈 객체 안에 우리는 

export.test = function() { ... }와 같이 객체의 프로퍼티를 추가해서 외부로 보내는 것이다.

당연히 프로퍼티로서 함수가 아닌 것들(일반 변수, 객체 등)과 같은 것들을 외부로 보낼 수 있다.

exports로 감싸 보낸 코드를 index.js에서 받아 출력하면 아래와 같은 결과가 나온다.

// test.js
exports.test = function () {
	console.log('test');
};
exports.test2 = function () {
	console.log('test2');
};
exports.test3 = {};
exports.test4 = 'test4';

// index.js
const test = require('./test');
console.log(test);

// console.log
{
    test: [Function (anonymous)],
    test2: [Function (anonymous)],
    test3: {},
    test4: 'test4'
}

물론, module.exports를 이용하여 같은 결과를 출력하게 할 수 있다.

// test.js
function test() {
	console.log('test');
}

function test2() {
	console.log('test2');
}

const test3 = {};
const name = 'foo';

module.exports = {
	test,
	test2,
	test3,
	name,
};

// index.js
const test = require('./test');
console.log(test);

// console.log
{
  test: [Function: test],
  test2: [Function: test2],
  test3: {},
  name: 'foo'
}

지금까지 빈 객체에 함수, 변수, 객체 등을 감싸 모듈화하여 외부로 보내는 방법에 대해 알아보았다.

단순히 하나의 함수만을 외부로 보내기 위해서는 어떻게 해야 할까? 간단하다.

// test.js
function test() {
	console.log('test');
}

module.exports = test;

또는 

// test.js
module.exports = function () {
	console.log('test');
};

와 같이 사용하면 된다.

 


ES6 문법이 도입되고 나서 import/export 방식으로 모듈 불러오기/내보내기 방식을 사용할 수 있게 됐다.

위의 방식을 사용하기 위해서는 node.js의 package.json에서 "type":"module"을 추가해줘야 한다.

ES6의 모듈 내보내기를 할 때, CommonJs의 방식과 비슷하게 두 가지 방식이 존재한다.

1. export를 사용

2. export default를 사용

 

export 방식은 CommonJs의 exports 방식과 비슷하게 빈 객체로 감싸서 외부로 보내지게 된다.

따라서 외부에서 이를 받을 때 구조 할당 문법을 사용하거나 빈 객체에 담겨진 프로퍼티를 대표하는 객체의 이름을 명시하여 사용할 수 있다.

// test.js
export const test = function () {
	console.log('this is test');
};

export const test2 = function () {
	console.log('this is test2');
};
// index.js
import express from 'express';
const app = express();

import * as test from './test.js';
console.log(test);

// console.log
[Module: null prototype] {
  test: [Function: test],
  test2: [Function: test2]
}

// index.js
import { test, test2 } from './test.js';
console.log(test, test2);

// console.log
[Function: test] [Function: test2]

export default 또한, module.exports의 방식과 같이 빈 객체에 프로퍼티를 추가하여 보낼 수 있고,

// test.js
const test = function () {
	console.log('this is test');
};

const test2 = function () {
	console.log('this is test2');
};

export default {
	test,
	test2,
};

// index.js
import test from './test.js';
console.log(test);

// console.log
{ test: [Function: test], test2: [Function: test2] }

단순히 하나의 함수 또는 변수 등을 보낼 수도 있다.

// 하나의 함수만 외부로 보내는 예시
// test.js 
const test = function () {
	console.log('this is test');
};

export default test;

// index.js
import test from './test.js';
console.log(test);

// console.log
[Function: test]