본문으로 바로가기
mark-lab

웹팩의 등장배경 모듈시스템

01. 웹팩의 등장배경 모듈시스템

1. 배경

모듈에 대해 이야기 해보자. 문법 수준에서 모듈을 지원하기 시작한 것은 ES2015부터다. import/export 구문이 없었던 모듈 이전 상황을 살펴보는 것이 웹팩 등장 배경을 설명하는데 수월 할 것이다.

// math.js
function sum(a, b) {
  return a + b
} // 전역 공간에 sum이 노출
 
// app.js
sum(1, 2) //3

해당 코드를 실행 후 브라우저에서 sum = 1 이라고 할당하고 sum 함수를 다시 실행하면 sum is not a function이라고 에러가 나온다. 이러한 이유는 빌드 타임이 없기 때문에 이러한 문제를 해결하기위해 IIFE방식의 모듈이 등장했다.

1.1 IIFE 방식의 모듈

모듈시스템이 나오기 전에는 불안정한 코드가 되기 쉬우나, IIFE를 사용하게 되면 좀 더 안전하게 전역 네임스페이스를 오염 시키지 않을 수 있다.

=> 이러한 문제를 예방하기 위해 스코프를 사용한다.

함수 스코프를 만들어 외부에서 안으로 접근하지 못하도록 공간을 격리하는 것이다. 스코프 안에서는 자신만의 이름 공간이 존재하므로 스코프 외부와 이름 충돌을 막을 수 있다.

// math.js
var math = math || {} // math 네임스페이스
 
;(function () {
  function sum(a, b) {
    return a + b
  }
  math.sum = sum // 네이스페이스에 추가
})()

1.2 다양한 모듈 스펙

이러한 방식으로 자바스크립트 모듈을 구현하는 대표적인 명세가 AMDCommonJS다.

CommonJS는 자바스크립트를 사용하는 모든 환경에서 모듈을 하는 것이 목표다.
exports키워드로 모듈을 만들고 require() 함수로 불러 들이는 방식이다. 대표적으로 서버사이드플랫폼인 nodejs에서 사용한다.

// math.js
exports function sum(a, b) { return a + b; }
 
// app.js
const math = require("./math.js")
math.sum(1, 2) // 3

AMD(Asynchronous Module Definition) 는 비동기로 로딩되는 환경에서 모듈을 사용하는 것이 목표다. 주로 브라우져 환경이다.

UMD(Universal Module Definition) 는 AMD기반으로 CommonJS 방식까지 지원하는 통합 형태다.

이렇게 각 커뮤니티에서 각자의 스펙을 제안하다가 ES2015에서 표준 모듈 시스템 을 내 놓았다. 지금은 바벨과 웹팩을 이용해 모듈 시스템을 사용하는 것이 일반적이다. ES2015 모듈 시스템의 모습을 살펴보자.

// math.js
export function sum(a, b) {
  return a + b
}
 
// app.js
import * as math from './math.js'
math.sum(1, 2) // 3

1.3 브라우저의 모듈 지원

모든 브라우저에서 모듈 시스템을 지원하지 않는다. 브라우저 script태그로 로딩할 때 type="text/javascript 대신 type="module"을 사용한다. app.js는 모듈을 사용할 수 있다.

그러나 우리는 브라우저에 무관하게 모듈을 사용하고 싶다. 웹팩의 등장!

웹팩은 이러한 모듈 시스템을 지원해준다. 개발자가 모듈 시스템 안에서 개발할수 있도록 지원해주고, 웹팩이 만들어내 코드는 모듈을 지원하지 않는 브라우저가 어플리케이션을 동작하게끔 코드를 변화시켜 준다.