모듈 시스템, 모듈 번들러의 등장

Janet·2024년 1월 5일
0

Web Development

목록 보기
11/19
post-thumbnail

Module


Module: 특정 기능을 하는 프로그램의 단위로써 분리된 코드 조각, 분리된 하나의 파일

개발 시, 코드의 재사용이나 유지 보수를 위해 파일을 분리하여 모듈화합니다. 즉, 개발 편의성을 위해 필요한 영역에서 재사용 가능하기 때문에 자주 사용하는 코드를 모듈화하여 관리하는 것입니다.

하지만 이러한 모듈 파일이 많아지다보면 브라우저에서 서버에 요청하는 파일의 개수도 많아지면서 네트워크 비용이 증가하게 되고, 이로 인해 페이지 로딩 시간을 길어지게 하면서 사용자 경험에 좋지 않은 영향을 줄 수 있습니다.

따라서, 개발 환경에서는 모듈을 분리하여 개발을 하고 페이지 로딩 시간도 줄이려면, 브라우저에서 서버에 요청하는 네트워크(HTTP) 요청 수를 줄여야 할 것 입니다. 그러기 위해서 웹서버에 배포하기 전에 모듈화한 자원들(HTML, CSS, JS 등)을 하나의 파일로 묶어서(bundle) 배포하는 것입니다. 이를 번들링(Bundling)이라고 합니다.

I. Module 시스템의 필요성

모듈 시스템이 아직 표준화되지 않았던 시기에는 여러 자바스크립트 파일을 단순하게 HTML에 <script> 태그로 연결하는 방식을 사용했는데, 이러한 방식은 아래와 같은 여러 문제가 있었습니다.

  1. 성능 문제:
    • 모든 스크립트를 한 번에 로드하는 경우, 페이지가 초기 로딩될 때 모든 스크립트가 다운로드되고 실행되어야 합니다. 큰 규모의 프로젝트에서는 초기 로딩 속도가 느려질 수 있습니다.
  2. 의존성 관리의 어려움:
    • 여러 개의 스크립트가 있을 때 각 스크립트 간의 의존성을 관리하기 어려울 수 있습니다. 스크립트 간의 순서를 신경쓰지 않으면 예상치 못한 오류가 발생할 수 있습니다.
  3. 전역 스코프 문제:
    • <script> 태그로 연결된 스크립트 파일은 기본적으로 전역 스코프에 추가됩니다. 이로 인해 변수 이름 충돌이나 오염이 발생할 수 있습니다.
  4. 코드 재사용의 어려움:
    • 모든 페이지에서 동일한 스크립트를 사용하는 경우, 코드의 재사용이 어려울 수 있습니다. 코드의 수정이 필요한 경우 모든 페이지에 대해 수정을 진행해야 합니다.
  5. 성능 최적화의 한계:
    • 모든 스크립트를 동기적으로 로드하면 브라우저는 페이지 렌더링을 일시 중지합니다. 이는 사용자 경험에 영향을 줄 수 있습니다. 또한, 코드를 최적화하거나 코드 스플리팅과 같은 성능 최적화 기법을 적용하기 어려울 수 있습니다.

II. Module System의 등장

위와 같은 한계점들을 개선하기 위해 CommonJS, AMD, UMD 등의 모듈 시스템이 등장했고, 2010년 이후부터 이러한 모듈 시스템을 개선하고 더욱 효율적으로 사용하기 위해 모듈 번들러(Module Bundler)가 등장했습니다.

1. CommonJS:

  • CommonJS는 2009년에 등장했습니다. 주로 서버 측 JavaScript 환경인 Node.js에서 모듈 시스템을 구현하기 위해 만들어졌습니다. CommonJS는 동기적으로 모듈을 로드하는 방식을 채택했으며, require 함수를 사용하여 모듈을 가져오는 방식이 특징입니다. CommonJS는 동기적인 동작이 가능한 서버사이드 자바스크립트 환경을 전제로 합니다. 브라우저에서 이런 방식은 필요한 모듈이 모두 다운로드할 때까지 아무것도 할 수 없는 상태가 되어 치명적인 단점이 되었습니다.
    • 모듈 가져오기 및 내보내기 키워드: require, module.exports

2. AMD (Asynchronous Module Definition):

  • AMD는 CommonJS와는 다르게 비동기적으로 모듈을 로드하는 방식을 도입한 모듈 시스템입니다. RequireJS와 함께 2011년경에 등장했으며, 주로 브라우저 환경에서 모듈을 비동기적으로 로드하기 위해 사용되었습니다. AMD는 비동기 모듈에 대한 표준안을 다루고 있습니다. AMD는 비동기적인 특징으로 클라이언트 사이드 개발에 적합합니다.
    • 모듈 정의하기 및 가져오기 키워드: define, require

3. UMD (Universal Module Definition):

  • AMD와 CommonJS 두 그룹으로 나누어지다 보니 서로 호환되지 않는 문제가 발생하게 되었습니다. 따라서 UMD는 모듈이 CommonJS, AMD, 그리고 전역 객체(Global)에 모두 대응할 수 있도록 만들어진 패턴(모듈을 작성하는 방식)입니다. 이는 모듈이 어떤 환경에서도 사용될 수 있도록 하기 위한 목적으로 나왔습니다.

4. ESM (ECMAScript Module):

  • ESM은 ES6부터 표준으로 추가된 ECMAScript에서 지원하는 자바스크립트 공식 모듈 시스템입니다. 브라우저와 Node.js 환경에서도 사용 가능합니다. 주의할 점은 아직 모든 브라우저에서 import와 export를 완벽하게 지원하지 않아 번들러를 함께 사용해야 합니다.
    • 모듈 가져오기 및 내보내기 키워드: import, export
    • 모듈 타입 지정하는 법
      • <script> 태그에 type="module"을 선언하면 자바스크립트 파일은 모듈로 동작합니다. 이때 모듈이라는 것을 명확히 알기 위해서 .mjs 확장자를 사용하도록 권장합니다.
        <!DOCTYPE html>
        <html>
        	<body>
        	  <script type="module" src="esm.mjs"></script>
        	</body>
        </html>
      • 또는 package.json에서 "type": "module"을 설정하여 모든 .js 파일이 ESM으로 처리되도록 설정할 수 있습니다.
        // package.json
        {
          "type": "module"
        }
      • type="module"을 사용하면 해당 파일에 import와 export 사용이 가능합니다. 또한 모듈마다 독립적인 스코프를 가져, 전역 객체가 서로 공유되지 않습니다.

5. 모듈 번들러의 등장:

  • 모듈 번들러는 CommonJS, AMD, UMD, ESM 등의 모듈 시스템이 갖는 각종 문제를 해결하고, 여러 모듈을 하나로 묶어서 성능을 최적화할 수 있도록 2010년대 중반 이후에 등장했습니다.
  • Webpack은 2012년에 처음 나왔으며, 모듈 번들링의 주도적 역할을 수행하면서 모듈 시스템의 발전에 큰 기여를 했습니다.
  • 이후 Parcel, Rollup 등의 모듈 번들러도 등장하여 각각의 특성에 따라 사용되고 있습니다.

III. Module Bundler

Module Bundler (분리된 코드 조각(파일)들을 하나로 묶는 도구)

번들링은 여러 파일로 분리된 소스 코드나 리소스를 하나로 묶어주는 과정이라고 하였습니다. 주로 웹 개발에서 사용되며, 프론트엔드에서는 주로 JavaScript, CSS, 이미지 등을 하나의 파일로 번들링하여 네트워크 전송량을 줄이고 성능을 향상시킵니다. 번들링은 여러 모듈 간의 의존성을 해결하고, 코드의 최적화를 수행하여 빠르게 로딩되는 웹 페이지를 만들 수 있도록 도와줍니다.

번들러는 프로젝트에서 사용하는 여러 개의 파일을 하나로 묶어주는 도구입니다. 주로 웹 개발에서 사용되며, 프론트엔드에서는 JavaScript, CSS, 이미지 등을 번들링하여 네트워크 비용을 줄이고 성능을 향상시킵니다.

번들러는 여러 모듈 간의 의존성을 해결하고, 번들링된 결과물을 최적화하는 역할을 수행합니다. 주요 기능은 다음과 같습니다:

  1. 개발 서버 지원 및 HMR(Hot Module Replacement) 기능 지원: HMR은 코드의 변경 사항을 새로고침 없이 즉시 반영 시켜주는 기능입니다.
  2. 코드 경량화(Minify): 코드를 작은 용량으로 변환해 줍니다.
  3. Tree shaking: 사용하지 않는 코드들을 제거하여 번들 크기를 최소화하는 기능입니다.
  4. 모듈 번들링(Module Bundling): 여러 파일을 하나로 묶어 하나의 파일로 만듭니다. 이는 웹페이지에서의 HTTP 요청 수를 줄여 로딩 시간을 단축시키는 데 도움이 됩니다.
  5. 의존성 해결(Dependency Resolution): 프로젝트의 모듈 간의 의존성을 자동으로 해결합니다.
  6. 코드 스플리팅(Code Splitting): 필요한 코드만 요청 시점에 동적으로 로딩할 수 있도록 코드를 분할하는 기능을 제공합니다.

인기 있는 번들러로는 Webpack, ESbuild, Rollup, Vite, Parcel, Turbopack 등이 있습니다. 이러한 도구들은 모듈 시스템을 지원하고, 번들링된 결과물을 최적화하여 성능을 향상시킵니다.

요약 정리


  1. Module: 특정 기능을 하는 프로그램의 단위로써 분리된 코드 조각, 분리된 하나의 파일을 말합니다.
  2. CommonJS: 주로 Node.js 환경에서 사용되어 서버 사이드 자바스크립트 개발을 위한 모듈 시스템으로 널리 사용됩니다.
  3. AMD (Asynchronous Module Definition): 비동기적으로 모듈을 로드하는 방식을 제공하며, 주로 브라우저 환경에서 사용되어 동적 로딩에 유용합니다.
  4. UMD (Universal Module Definition): 모듈이 CommonJS, AMD, 그리고 전역 객체에 대응할 수 있는 유니버설한 형태의 패턴으로, 브라우저 및 Node.js에서 사용 가능하여 다양한 환경에서 모듈을 사용할 수 있도록 통합하는 목적으로 사용됩니다.
  5. ESM (ECMAScript Modules): ES6부터 표준으로 도입된 자바스크립트의 공식 모듈 시스템으로, 모던 자바스크립트 환경에서 모듈을 정의하고 가져오는 표준 방식으로 사용됩니다.
  6. Module Bundler: 여러 개의 모듈 및 의존성을 하나의 파일로 번들링하여 성능 향상과 로딩 시간 감소를 도모하는 도구로, Webpack, Vite, Rollup 등이 있습니다.

Reference.

profile
😸

0개의 댓글