모듈 시스템: CommonJS, AMD, UMD, ES6

여러 기능에 관한 코드가 모여있는 하나의 파일

 

 

장점

  • 의존성을 줄여주기때문에 유지보수 용이
  • 모듈만의 네임스페이스 화 
  • 필요할때마다 재사용

위와 같은 이유로 모듈의 개념이 필요했고, Javascript에서는 여러가지를 시도하였다.

 

CommonJS

  • 서버사이드 및 데스크탑 어플리케이션에서 지원하기 위해 만든 방식으로 Node.js에서 사용 가능하다.
  • require, module.exports를 사용하는 방식이다. 
  • 여기서 module.exports의 module은 예약어이며 현재 모듈에 대한 정보를 가지고 있는 객체이다.
  •  
// search.js
const getWord = () => {};

module.exports = {
    getWord
};

// index.js
const searchModule = require('./search.js');
searchModule.getWord();

module.export를 exports로도 사용이 가능하며 관계를 명확히 이해해야한다.

  • module.exports빈 객체를 참조
  • exportsmodule.exports 참조
  • requiremodule.exports를 리턴받음

 

module.exports = { searchModule }; 
// module.exports는 빈객체를 잠조하므로 -> 빈객체 = { searchModule }

exports.searchModule = searchModule; 
// exports가 module.exports를 참조하므로 -> module.exports.searchModule라는 객체 = searchModule 

exports는 항상 module.eports를 참조하기 때문에 exports를 사용하면 직접 module.exports를 수정하지 않고 객체의 멤버를 만들거나 수정이 가능하다. 잠재적인 버그를 피할수 있다는데???? 추후 자세히 알아보자.

 

 

AMD(Asynchronous Module Definition)

  • 비동기 모듈에 대한 표준안.
  • 모듈 로딩이 다 될때까지 동기로 기다릴 수 없기 때문에 비동기 모듈방식이 브라우저쪽에서 더 큰 효과를 발휘한다.
  • define(), require()를 사용하는 방식이다.
  • 모듈로더로는 RequireJS를 추천한다.

HTML

<!DOCTYPE html>
<html lang="ko">
<head>
  <title>Document</title>
</head>
<body>
  <!-- data-main="require가 로드된 후 실행될 파일" src="requireJS에서 비동기로 사용할 파일" -->
  <script data-main="index.js" src="require.js"></script>
</body>
</html>

JS

// index.js
require.config({
  // 기본 경로
  baseUrl: '/',
  // 모듈에 해당하는 경로
  paths: {
    searchModule: 'searchModule',
    loaderModule: 'loaderModule',
}});

// 첫번째 인자에 해당하는 모듈이 로드되었을 경우 a로 받아서 getWord() 함수를 호출하는 콜백함수 실행.
// 의존성 모듈을 지정해주는 것
require(['searchModule'], (searchModule) => {
	searchModule.getWord();
});

// searchModule.js
// define을 통해 정의, require에서 의존성 모듈을 설정한 것처럼.. 
// 여기서도 콜백함수가 실행되기전 모듈을 지정할 수 있다.
define(() => {
  return {
  	getWord: () => 'word'
  }
});

 

 

UMD(Universal Module Definition)

  • CommonJS, AMD를 통합하기 위한 하나의 패턴.
(function (root, factory) {

    // AMD
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define([], factory);

    // CommonJS
    } else if (typeof module === 'object' && module.exports) {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();

    // Browser
    } else {
        // Browser globals (root is window)
        root.returnExports = factory();

}}(typeof self !== 'undefined' ? self : this, function () {
    // Just return a value to define the module export.
    // This example returns an object, but the module
    // can return a function as the exported value.
    return {};
}));

공식코드 출처 : https://github.com/umdjs/umd/blob/master/templates/returnExports.js

 

 

 

ES6(ES2015) 방식

  • import, export 방식을 사용한다.
  • 모든 브라우저가 지원하지 않기 때문에 Babel의 @babel/plugin-transform-modules-commonjs을 통해 컴파일한다.
  • export하는 방식에 따라 import해서 사용하는 방식이 달라진다.
// 1. export default
const getWord = () => {};
export default getWord;

// 1. import
import getWord from 'searchJS';

// 2. export {}
const getWord = () => {};
export { getWord };

// 2. import
import {getWord} from 'searchJS';

default export는 모듈내에서 한번만 사용가능하며 named export는 여러번 사용가능하다.

namex dexport로 내보내면 { }를 통해 불러오고 as 키워드를 통해 다른이름으로 사용하거나 *를 통해 한번에 불러오거나 등의 작업을 할 수 있다.

참고 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/export

 

 

 


 

모듈 시스템: CommonJS, AMD, UMD, ES6

https://github.com/baeharam/Must-Know-About-Frontend/blob/master/Notes/javascript/module.md

 

+ Recent posts