Home 01-Bundler-등장-배경
Post
Cancel

01-Bundler-등장-배경

참고 자료

1. Node.js와 NPM

1) Node.js

Node.js란 브라우저가 아닌 환경에서 JS를 실행할 수 있도록 하는 환경이다.

  • JavsScript 런타임 환경으로 React.js 더 편리하게 사용할 수 있도록 해주는 도구를 제공해 준다.

  • 이전에는 JS가 브라우저에서만 실행할 수 있었지만 Node.js로 자바스크립트를 브라우저 밖에서도 실행할 수 있게 되었다.

  • Node.js를 설치시 NPM이라고 불리는 패키지 매니저도 자동으로 설치 된다.


2) NPM

NPM 패키지 매니저를 통해 React에 필요한 다양한 모듈을 다운, 업데이트 할 수 있도록 한다.

전 세계 자바스크립트 개발자들이 모두 자바스크립트 라이브러리를 공개된 저장소에 올려놓고 npm 명령어로 라이브러리를 다운받을 수 있다.

1
2
# NPM 프로젝트 초기화 명령 실행 (package.json 파일 생성)
$ npm init-y


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// package.json 

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": [
  ],
  "devDependencies": [ 
  ],
}
  • scripts: 해당 속성에 실행을 원하는 명령어를 설정할 수 있다.
    • npm run + 실행 이름으로 가동된다.
  • dependencies: npm install을 통해 설치되는 모듈 리스트 (애플리케이션의 로직과 관련있는 라이브러리)
    • ex) react, angular, chart 등
  • devDependencies npm install -D를 통해 설치되는 모듈 리스트 (개발 보조 라이브러리)
    • ex) webpack, js-compression, sass, eslint, imagein 등


개발용 라이브러리와 배포용 라이브러리 구분하기

NPM 지역설치를 할 때에는 해당 라이브러리가 배포용(dependencies)인지 개발용 (devDependencies)인지 꼭 구분해야 한다.

  • 배포용 라이브러리는 npm run build로 빌드를 하면 최종 애플리케이션 코드에 포함된다.
  • 개발용 라이브러리는 빌드하고 배포할 때 애플리케이션 코드에서 빠지게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
# 모듈 설치
$ npm install 모듈이름
$ npm install 모듈이름 --save-prod

# 모듈 삭제
$ npm uninstall 모듈이름

# 전역 설치 명령어
$ npm install 모듈이름 --global 

# dev 설치
$ npm install 모듈이름 -D
$ npm install 모듈이름 --save-dev
  • 지역 설치
    • node_modules 폴더가 생성되고 그 하위에 라이브러리 파일들이 설치된다.
    • package.json의 dependencies에 추가된다.
  • global 설치
    • windwo 전역 설치 경로: %USERPROFILE%\AppData\Roaming\npm\node_modules
    • mac 전역 설치 경로: /usr/local/lib/node_modules
    • 시스템 레벨에 전역으로 설치하기 위함이다.
  • dev 설치
    • node_modules 폴더가 생성되고 그 하위에 라이브러리 파일들이 설치된다.
    • package.json의 devDependencies에 추가된다.


2. Module

Module이란 여러 기능들에 관한 코드가 모여있는 하나의 파일이다.

애플리케이션의 규모가 커짐에 따라 JS코드를 여러 파일과 폴더에 나누어 작성하고 서로를 효율적으로 불러올 수 있도록 하는 시스템이 필요했고 이를 해결하기 위해 ES6부터 JS는 모듈 기능을 사용할 수 있게 되었다.

1) Module의 특징

  • 유지 보수성
    • 코드를 다시 작성하지 않고도 쉽게 의존성을 변경할 수 있다.
    • 애플리케이션을 유지 보수할 때 관련 있는 모듈만 업데이트 하면 된다.
  • 네임 스페이스
    • JS는 파일 스코프가 존재하지 않는다. 변수는 모두 전역변수를 사용하기 때문에 애플리케이션이 커질 수록 변수명이 겹치는 경우가 많아질 수 있다.
    • Module은 Module만의 네임 스페이스를 갖고 있기 때문에 위와 같은 문제를 해결할 수 있다.
  • 재 사용성
    • Module로 분리 시켜 필요할 때마다 다시 재 사용할 수 있다.


2) 번들러 등장 배경

  • 브라우저별 HTTP 요청 숫자의 제약
    • TCP 스펙에 따라 브라우저에서 한 번에 서버로 보낼 수 있는 HTTP 요청 숫자는 제약되어 있다.
    • HTTP 요청 숫자를 줄이는 것이 웹 애플리케이션의 성능을 높여줄 뿐만 아니라 사용자가 사이트를 조작하는 시간을 당길 수 있다.
    • **프로젝트 규모가 커지면서 많은 모듈을 사용하게 되었고 수 많은 모듈을 일일이 요청하는 것을 피하기 위해 번들러의 필요성이 대두되었다. **
  • 트리 쉐이킹, 코드 스플릿, 소스맵, 코드 최적화 필요성 대두 (추후 서술)


3. Bundler

1) Bundling

애플리케이션을 구성하는 수 많은 자원들을 하나의 파일로 병합 및 압축해주는 동작을 Module Budling이라고 한다.


image-20220903232054053


번들링은 웹 애플리케이션을 동작시키기 위한 자원 (HTML, CSS, JS, Images 등)들을 각각의 모듈로 보고 하나로 묶고 조합해서 하나의 정적인 결과물을 만든다.

  • 많은 자원들의 연관관계를 파악한 후, 묶고 조합한다.
  • 하나로 묶여있지 않으면, 그만큼 서버에 필요한 자원을 여러번 요청해야 하다.
  • 하나로 묶어서 경량화 시켜주면 그만큼 서버에 가하는 부하도 적어지고 로딩시간도 높일 수 있어 성능적으로 유리하다.

또한, 앱에 많은 기능이 필요해질수록 모듈 종속성의 올바른 순서를 추적하고 로드하는 번거로움이 더 커지게 된다.

  • 코드 베이스를 모듈로 분할 관리하고 묶어 주어야 한다.


2) 번들러의 부가 기능

번들러는 애플리케이션에 필요한 모든 모듈을 알아서 매핑하며 매핑된 결과를 가지고 하나 이상의 번들을 생성한다.

  • 트리 쉐이킹 (Tree Shaking)
    • 트리쉐이킹은 최종 번들에서 사용되지 않을 코드를 제거한다.
    • 애플리케이션에서 사용되지 않는 코드가 번들에 포함될 수도 있다. 사용되지 않는 코드 조각은 번들 크기를 불필요하게 키우므로 번들 과정에서 제거해야 한다. 이런 과정이 마치 나무 흔들기와 비슷해서 TreeShaking이라고 부른다.
    • JS 번들 크기를 줄여 앱의 실행 속도를 향상시킬 수 있다.
  • 코드 분할 (Code Spliting)
    • 코드 분할은 런타임 중에 나뉘어진 chunk 파일을 동적으로 불러오는 것을 말한다.
    • 즉, 사용자가 애플리케이션을 모듈이 필요해지면 번들러가 필요한 하위 번들을 처리한다. (Dinamic Loading, Lazy Loading)
    • 앱이 커지면 결국 번들 또한 사이즈가 커진다. 특히 3rd-party 라이브러리를 추가할 때 앱이 더욱 커져서 로드 시간이 길어질 수 있다.
    • 번들이 거대해지는 것을 방지하기 위해 좋은 방법은 코드를 나누는 것이다.
    • 앱의 코드 양을 줄이지 않고도 사용자가 필요하지 않은 코드를 불러오지 않게 하며 앱의 초기화 로딩에 필요한 비용을 줄여준다.
  • 코드 최적화, 소스맵 (Code Optimization, SourceMap)
    • 수많은 모듈을 번들하는 동안 수행해야 하는 코드 최적화(코드 압축)를 할 수 있다.
    • 번들 파일이 생성되면 브라우저에서 이를 해석하여 처리 하는데, 코드 최적화를 위해 주석, 공백 또는 긴 변수, 함수 이름 등을 모두 축소 또는 제거하여 파일의 크기를 크게 줄일 수 있다. 하지만, 이 코드는 압축되었기에 사람이 읽기 매우 어렵다.
    • 사람이 읽기 어려운 코드는 디버깅도 쉽지 않아 코드를 추적 가능한 소스맵을 제공하는 기능이 필요하다.
    • 즉, 소스맵은 배포할 때 성능최적화를 위해 압축한 코드를 원본 파일과 연결시켜준다.


This post is licensed under CC BY 4.0 by the author.