[React] 번들링과 웹팩

2023. 3. 20. 12:09코드스테이츠/코드스테이츠S4 Chapter & Unit

번들링

 

이런식으로 어떠한 제품을 묶음으로 판매하는 걸 '번들링' 이라고 한다.

 

웹 개발에서 번들링

그럼 웹 개발을 할 때 '번들링'을 한다고 하면 무슨 의미일까?
(참고로 웹 개발에서 번들링 = 빌드 라고 할 수 있다.)
사용자에게 웹 애플리케이션을 제공하기 위해 여러 코드와 프로그램들을 묶는 행위로 정의할 수 있다.
개발자는 최종적으로 번들링된 웹 애플리케이션을 만들어내고, 사용자가 웹 애플리케이션을 이용할 때는 번들링한 파일을 받아와 브라우저가 이 번들을 실행한다.

 

번들링이 없던시절 문제점은?

  • 두 개의 .js 파일에서 같은 변수를 사용하고 있어서, 변수 간 충돌이 일어났다.
  • 한 번 불러오는 프레임워크 코드가 8MB라서, 인터넷 속도가 느린 국가의 모바일 환경에서 사용자 불편함을 겪음.
  • 번들 파일 사이즈를 줄이기 위해서 파일의 공백을 모두 지웠는데, 가독성이 너무 떨어져서 코딩하기가 어렵습니다.
  • 배포 코드가 너무 읽기 쉬워 개발을 할 줄 아는 사용자가 프론트엔드 애플리케이션을 임의로 조작하는 등 보안에 취약하다.

번들링의 필요성

지금까지 HTML,CSS, JavaScript 파일을 따로 번들링 하지 않아도 작동에 문제가 없었다.

그런데 어째서 번들링을 굳이 해야할까?

 

 

파일의 크기 문제 해결

코드를 '번들링'한다는 것은 단순히 묶기만 하는 것이 아니라 컴퓨터 파일을 '압축'하는 개념과 비슷하다.
번들 파일은 번들링을 거치지 않은 원본 프로그램 파일보다 크기가 작아지고 실행 속도, 로딩 속도 또한 빨라진다. 말그대로

 

애플리케이션 임의 조작 방지

압축한 파일을 받아와 압축해제 전까지는 파일을 조작할 수 없는 것처럼, 번들링된 웹 애플리케이션도 사용자가 임의로 조작할 수 없다. 번들링되지 않은 원본 코드에 사용자가 접근할 수 있다면, 컴퓨터를 잘 아는 사용자가 이를 원하는 대로 조작할 위험이 생긴다. (ex. 강의 안듣고 들은 것처럼 만들기 라던가..)

 

파일 단위의 js 모듈 관리의 필요성

Javascript에서 변수는 기본적으로 '전역 범위'를 가지기 때문에 하나의 프로젝프 폴더에서 여러 개의 .js 파일이 있더라도 서로 변수를 공유하게 된다.
근데 여기서 변수를 중복 선언하거나 의도치 않은 값을 할당해 생기는 에러를 번들링 도구인 Webpack에서는 모듈 번들링으로 해결한다.

 


Completed!

Webpack

webpack은 2022년 7월 현재 프론트엔드 애플리케이션 배포를 위해서 가장 많이 사용하는 번들러입니다. 실리콘벨리나 국내 IT 대기업을 막론하고 프론트엔드 애플리케이션을 대규모 유저에게 제공하기 위해 가장 많이 사용하는 방법입니다. 많은 웹 개발자에게 사랑받고 있고, 이제는 Node.js 백엔드 개발자도 배포를 위해서도 많이 사용합니다. 가장 많이 사용하는 번들러답게 공식문서도 한글로 번역이 되어있고, 자료도 쉽게 찾을 수 있어 처음 번들링에 대해서 학습할 때 참고하기 좋습니다. 

 

번들러 점유 순위

 

그래서 Webpack이 뭔데..

여러개의 파일을 하나로 합쳐주는 모듈 번들러를 의미한다.

모듈 번들러란 HTML, CSS, JavaScript 등을 전부 각각의 모듈로 보고 이를 조합해 하나의 묶음으로 번들링(빌드)하는 도구다.

 

그럼 모듈 번들러가 뭔데..?

✏️ module bundler
HTML, CSS, Javascript 등의 자원을 각각의 모듈로 보고 이를 조합해 하나의 묶음으로 번들링(빌드)하는 도구
(여기서 모듈은 코드뿐만 아니라 애플리케이션에 필요한 이미지 파일과 기타 파일도 모두 포함한다.)

 

 

모던 웹으로 발전하면서 html, css 파일의 내용이 javascript 파일 안으로 들어왔다.
→ 그래서 .js 파일의 양이 절대적으로 증가하고,
→ 세분화된 모듈 파일이 폭발적으로 증가해
→ 웹 애플리케이션의 의존성 트리도 대규모가 되었다.
이렇게 되면 위에서 말했던 javascript의 변수 스코프 문제 + 웹 애플리케이션을 실행할 때 네트워크 쪽의 비용 문제까지 신경쓰게 되었다.

모듈 번들러는
: 하나의 시작점 (ex. react app의 index.js)로부터 의존성을 가지는 모듈을 모두 추적해 dependency graph를 만들고, 하나의 결과물을 만들어 내는 방식으로 문제를 해결한다.

 

Webpack에서의 모듈

Webpack에서의 모듈은 JavaScript의 모듈에만 국한하지 않습니다. HTML, CSS, 혹은 .jpg나 .png 같은 이미지 파일들도 전부 포함한 포괄적인 개념입니다.

[그림] Webpack은 JavaScript 외에도 다양한 파일을 번들링 합니다.

따라서 Webpack은 주요 구성 요소인 로더(loader)를 통해 다양한 파일도 번들링이 가능합니다.

 

webpack이 제공하는 것들

네트워크 비용 감소

각 자원을 일일이 서버에 요청해 얻어올 필요가 없다
→ 대신 같은 타입의 자원을 요청해 요청과 응답을 주고 받는다

javascript 문법 버전 호환성 지원

loader를 사용해서 javascript ES6 문법을 ES5로 변환해주는 babel-loader를 이용할 수 있다.

development / production 모드 선택 가능

production 모드에서는 코드 난독화, 압축, 최적화 작업 등을 지원해준다.

 

webpack.config.js


webpack으로 번들링을 할 때, webpack.config.js라는 설정 파일을 직접 작성해서 내 입맛에 맞게 번들링이 가능하다. (config 파일이 필수로 요구되지는 않는다.)
config 파일 안에서 target, entry, output, module, plugins, loader, mode 등등을 설정해줄 수 있다.

entry

webpack이 의존성 그래프를 그리기 시작하는 시작점이 되는 파일을 지정한다.
default 값으로는 ./src/index.js을 사용한다.

module.exports = {
    name: 'webpack-setting',
    entry: './src/index.js',
};

output

생성한 번들을 내보낼 위치와 번들 파일의 이름을 지정한다.
default 값으로는 ./dist/main.js를 사용한다.

const path = require('path');

module.exports = {
    ...
  	output: {
		path: path.resolve(__dirname, 'dist'),
      	filename: 'bundle.js',
    }
};

loader

webpack은 기본적으로 javascript와 JSON 파일만 이해한다. 다른 유형의 파일을 처리하려면 loader를 사용해야 한다.
loader는 파일들을 유효한 모듈로 변환해 애플리케이션에 사용하거나, 의존성 그래프에 추가한다.

module.exports = {
    ...
  	module: {
		rules: [
          {
            test: /\.css$/,
            use: [MiniCssExtraPlugin.loader, "css-loader"],
            exclude: /node_modules/,
          },
        ]
    }
};

module의 rules 배열에 항목을 추가함으로써 사용할 수 있다. 예시는 css 파일을 사용하기 위해 css loader를 불러왔다.

  • test(필수): 변환이 필요한 파일들을 식별
  • use(필수): 변환을 수행할 loader를 가리킴
  • exclude: 바벨로 컴파일하지 않을 파일이나 폴더를 지정

plugins

loader가 특정 모듈들을 변환하는데 쓰였다면, plugin은 더 넓은 범위의 작업을 수행한다. 번들을 최적화하거나 에셋을 관리하고, 환경변수 주입 등의 작업을 해준다.

사용방법은
1. require 구문을 통해 plugin을 불러오고,
2. plugins 배열에 추가하고,
3. 이 때 다른 목적으로도 여러번 사용할 수 있도록 new 키워드로 인스턴스를 생성해주어야한다!

const webpack = require('webpack');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html"),
    }),
    new MiniCssExtractPlugin(),
  ],
};
  • html-webpack-plugin: 생성된 모든 번들을 자동으로 삽입해 애플리케이션용 html 파일을 생성한다.
  • mini-css-extract-plugin: css를 별도로 추출해 css를 포함하는 js 파일별 css 파일을 작성해준다.

mode

mode에는 development, production, none 세가지 옵션이 있다. default는 production이다.

module.exports = {
  mode: 'production',
  ...
};

웹팩과 번들링을 알아보면서 헷갈렸던 부분.

  • 번들링과 빌드는 다른개념인가?
  • 웹팩은 빌드를해주는것인가 번들링을해주는것인가?
  • npm run build는 웹팩을 실행하는데, 웹팩 = 빌드인가?

"빌드라는게 소스코드들을 최적화(브라우저호환, 코드 최소화, 난독화)하는 프로세스. 좁게보면 트랜스파일링 이라고 이해 할 수 있겠다.번들링은 필요한 모든 파일들을 묶는?(패키징) 프로세스. 웹팩으로 번들링하면 단순히 파일을 하나로 합쳐주는게 아니라 최적화도 해주고 패키징도 해줌. 빌드 과정에서 트랜스파일링도 하고 여러파일들을 단순하게 묶는 작업(번들링)도 한다고 생각하시면 될 것 같다. 빌드 과정 안에 번들링이 있다고 봐도 될 것 같다. 그리고 웹팩은 트랜스파일링, 번들링 전부 한다고 생각하면 될 것 같다. 빌드할때 webpack만 실행하기 때문이다.나중에 바벨같은걸 붙이면 트랜스파일링의 역할을 바벨이 한다고 보면 될 것 같다." 라는 답변을 받았다.

'코드스테이츠 > 코드스테이츠S4 Chapter & Unit' 카테고리의 다른 글

[Deploy]CI/CD  (0) 2023.04.03
[Deploy] Amazon Web Service  (0) 2023.03.31
[React] React Hooks  (0) 2023.03.22
[React] Virtual DOM  (0) 2023.03.22
[HTML/CSS] 웹의 동작원리  (0) 2023.03.20