S4 Unit 3. [React] 번들링과 webpack

나현·2022년 11월 23일
0

학습일지

목록 보기
42/53
post-thumbnail

💡 이번에 배운 내용

  • Section4. 사람과 기계가 모두 쉽고 빠르게 접근 가능한 Web App을 만들 수 있다.
  • Unit3. 번들링과 webpack : 프론트엔드 개발에서 번들링은 사용자가 더 쉽고 빠르게 프론트엔드 애플리케이션에 접근할 수 있도록 용량을 줄이거나 파일을 최소화하여 유저에게 전달하는 과정이다. 이 개념과 이를 도와주는 툴인 webpack에 대해 학습한다.

느낀점

이번에는 직접 HTML,CSS,JS로 된 프로젝트와 react로 된 프로젝트를 번들링해보는 실습도 같이 진행하였다. 직접 해보니 어떤 방법으로 해야할지, 어떤 작업이 필요한지 잘 파악할 수 있었고 깃헙 페이지에 직접 배포할 수도 있었다. 평소 리액트로 된 작업물들은 어떻게 깃헙 페이지로 배포할지 몰랐는데 이번 기회에 잘 알 수 있었다. 재밌다!
이참에 지난번 유닛에서 작업했던 결과물고 배포해야겠다. 😁


키워드

번들링, 웹팩 webpack, 빌드, entry, output, loader, plugins, mode, optimization, babel, css-loader, style-loader, webpack-cli


학습내용

Ch1. 번들링

프론트엔드 개발에서 번들이란 이름 그대로 웹 애플리케이션을 제공하기 위한 파일 묶음을 의미한다. 사용자가 브라우저를 열고 주소를 입력하면 프론트엔드 개발자가 번들링한 여러 파일을 다운 받는다. 이 파일을 브라우저가 실행하여 웹 애플리케이션이 실행된다.

번들링이 필요한 이유는?
아래와 같은 상황을 해결하기 위해선 번들링이 필요하다.

  • 여러 js 파일에서 같은 변수를 사용하고 있어 변수 간 충돌이 일어난 경우
  • 프레임워크 코드가 무거울 경우
  • 파일 사이즈를 줄이기 파일의 공백을 지우거나 되돌려야 하는 경우
  • 배포 코드가 읽기 쉬워 접근이 쉬운 경우

위의 상황을 해결하고, 용량을 줄이면서 파일을 통합하기 위해 번들링이 필요하다. 이는 파일의 용량이 줄어들어 퍼포먼스에도 영향을 미치기 때문에 사용자에게도 더 나은 UX를 제공할 수 있다.

Ch2. webpack

webpack의 개념

Webpack은 프론트엔드 웹 애플리케이션 배포를 위해 사용하는 번들링 툴 중 하나다. 2022년 7월 기준으로 가장 많이 사용하는 번들러이기도 하다.
이 Webpack은 여러 개의 파일을 하나의 파일로 합쳐주는 모듈 번들러이다. 모듈 번들러란 HTML, CSS, JavaScript 등의 자원(모두 모듈이라 한다)을 조합해 하나의 묶음으로 번들링(빌드)하는 도구를 의미한다.
Webpack에서의 모듈이란 JS뿐만 아니라 HTML, CSS, 이미지도 전부 포함하는 개념이다. Webpack은 주요 구성 요소인 로더(loader)를 통해 이런 다양한 모듈들을 번들링한다.

기술이 발전하며 JavaScript 코드량이 많이 증가했고, 대규모의 의존성 트리를 가진 대형 웹 앱의 등장으로 세분화된 모듈 파일이 증가했다. 이 모듈 단위의 파일들을 브라우저에 띄우려면 JS특성상 각 변수들의 스코프 문제, 네트워크 비용도 신경써야 한다.
때문에 이런 문제에를 해결하기 위해 하나의 시작점(Ex. React App의 index.js 등)으로부터 의존성을 가지는 모듈(자원)을 모두 추적하여 하나의 결과물을 만들어내는 모듈 번들러가 등장하게 되었다.

빌드와 번들링

  • 빌드란:
    빌드는 개발이 완료된 앱을 배포하기 위해 하나의 폴더(directory)로 구성하여 준비하는 작업을 말한다. React 앱을 기준으로 npm run build를 실행하면 React build 작업이 진행되고, index.html 파일에 압축되어 배포에 최적화된 상태를 제공해준다.
  • 번들링이란:
    의존적 관계에 있는 파일들(import, export), 즉 내부적으로 포함된 모듈들을 묶는 작업을 의미한다. 모듈 간의 의존성 관계를 파악해 그룹화 하는 작업이다.

Webpack의 장점

  • 네트워크 비용이 줄어든다.
    자원들을 일일이 서버에 요청하던 방식과는 다르게, 같은 타입의 파일들은 묶어서 요청 및 응답이 가능하기 때문이다.
  • 다른 버전의 언어들을 호환이 가능하게 한다.
    JavaScript ES6의 문법들을 ES5로 변환해주는 babel-loader를 사용할 수 있다.
    이외에도 vue-loader, scss 파일을 css 파일로 변환해주는 scss-loader 등의 loader도 사용할 수 있다.
  • 코드 난독화로 코드 유출을 어느 정도 막을 수 있다.
  • 압축, 최적화가 가능하다.
  • 사용자가 느끼기에 더욱 쾌적한 환경을 조성할 수 있다.

cf. Webpack4 버전 이상부터는 Develoment, Production 두 가지의 모드를 지원한다. Production 모드로 번들링을 진행할 경우, 코드 난독화, 압축, 최적화(Tree Shaking) 작업을 지원한다.


Ch3. webpack의 핵심 컨셉

다음은 webpack.config.js 파일의 예시로, 이 코드 내의 속성을 확인하면 웹팩의 핵심 요소를 쉽게 알 수 있다.

module.exports = {
  target: ["web", "es5"],
  entry: "./src/script.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "app.bundle.js",
    clean: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader","css-loader"],
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html"),
    }),
    new MiniCssExtractPlugin(),
  ],
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ]
  }
};

웹팩 공식문서에 따르면 위에서 언급했던 요소들은 웹팩의 핵심 개념이다.
이 개념을 이해하면 웹팩의 작동 원리에 대해 좀 더 쉽게 이해할 수 있다.

  • Entry
  • Output
  • Loaders
  • Plugins
  • Mode
  • Browser Compatibility

Target

Webpack이 번들링할 대상을 명시한다. target의 기본값은 web이며(없을 경우 기본값 적용), web 외에도 다양한 환경을 컴파일 할 수 있으며 아래와 같이 지정된 ECMAScript 버전으로 컴파일할 수 있다.

module.exports = {
  target: ["web", "es5"],
};

Entry(엔트리)

webpack에서의 entry는 코드의 “시작점"이다. React의 index.js서 컴포넌트를 넣어 전체 코드가 시작되는 것을 생각하면 편하다.
Entry 속성은 Entry point라고도 하며, 웹팩이 내부의 디펜던시 그래프를 생성하기 위해 사용해야 하는 모듈입이다. 웹팩은 이 Entry point를 기반으로 직간접적으로 의존하는 다른 모듈과 라이브러리를 찾아낼 수 있다.

//기본 값
module.exports = {
	...
  entry: "./src/index.js", //index.js 대신 기본 시작점이 되는 코드를 입력
};

Output(출력)

Output 속성은 생성된 번들을 내보낼 위치와 파일의 이름을 지정한다.

const path = require('path');

module.exports = {
	...
  output: {
    path: path.resolve(__dirname, "dist"), // 절대 경로로 설정을 해야 합니다. 
    filename: "app.bundle.js",
    clean: true
  },
};

위 예제에서는 dist 폴더에서 app.bundle.js라는 파일에 번들링한다고 되어있다.
path는 절대 경로를 나타낼 때 쓸 수 있으며 사용할 때는 path 모듈을 사용하도록 한다.

Loader(로더)

Webpack은 기본적으로 JavaScript와 JSON 파일만 이해하지만, loader를 사용하면 다른 유형의 파일도 변환이 가능하다.

module.exports = {
	...
  module: {
    rules: [
      {
        test: /\.css$/, //css로 끝나는 모든 파일
        use: ["style-loader", "css-loader"],
        exclude: /node_modules/,
      },
    ],
  },
};

loader에는 다음과 같은 속성이 있으며 module.rules안에 정의해야 한다.
여기서 test와 use는 필수 속성이다.

  • test: 변환이 필요한 파일들을 식별
  • use: 변환을 수행하는데 사용되는 로더
  • exclude: (바벨로)컴파일하지 않을 파일이나 폴더
  • include: 반드시 컴파일해야 할 파일이나 폴더

Plugins(플러그인)

Plugins를 사용하면 번들을 최적화하거나 여러 작업(HTML 컴파일 및 생성, 에셋 관리, 환경변수 주입)이 가능하다.
플러그인을 사용하려면 해당 플러그인을 설치하고 requie()를 사용한다.
실제 사용시에는 new 키워드를 사용하여 인스턴스를 생성한다.

const webpack = require('webpack');
//모든 번들을 자동으로 삽입해 웹 앱용 HTML 파일 생성
const HtmlWebpackPlugin = require("html-webpack-plugin"); 
//CSS를 별도의 파일로 추출, CSS를 포함하는 JS파일 당 CSS파일을 작성
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html"),
    }),
    new MiniCssExtractPlugin(),
  ],
};

Optimization(최적화)

Webpack은 버전 4부터 선택한 항목에 따라 최적화가 가능하다.
대표적인 옵션으로 minimize와 minimizer가 있다.

module.exports = {
  ...
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(), //mini-css-extract-plugin 에 관련된 번들을 최소화
    ]
  }
};
  • minimize : 번들파일을 최소화시키는 작업 여부를 결정.
    TerserPlugin 또는 optimization.minimize에 명시된 plugins을 사용.
  • minimizer : defualt minimizer을 커스텀된 TerserPlugin 인스턴스를 제공해서 재정의 가능

Ch4. webpack과 react

리액트도 번들링이 필요하며, 필요한 라이브러리를 골라서 설치한 후 번들링할 수 있다.
리액트 개발에 꼭 필요한 라이브러리는 다음과 같다.

  • react, react-dom
    리액트를 설치하려면 당연히 필요한 라이브러리다.
  • babel
    JSX, 최신 JS 문법을 지원하지 않는 브라우저를 위해 babel을 설치하면 변환이 가능하다.
    리액트는 JSX문법을 사용했기 때문에 JS로 변환해줘야 한다.
  • css-loader
    리액트는 js파일에 css를 import해서 사용하므로 변환하려면 css loader가 필요하다.

이외에 필수는 아니지만 리액트 개발에 도움이 되는 라이브러리는 다음과 같다.

  • react-hot-reloader
    react-hot-reloader는 저장할 때 마다 변경사항을 개발 환경에 적용해주는 라이브러리다.
  • eslint
    JavaScript로 개발 시 자주 접하는 에러를 방지해준다.
  • prettier
    JavaScript로 개발 시 통일성 있게 코드 형식을 맞출 수 있게 도와준다.

참고자료 및 추가학습

1. webpack 공식문서
공식문서 링크: 🔗 https://webpack.kr/concepts/

2. 리액트에서 babel 설치하기
리액트 결과물을 webpack으로 번들링하기 위해 babel-loader가 필요했다.
아래는 직접 과제하면서 중요하다 싶은 점을 메모했다.

1) babel-loader 설치: preset-react를 꼭 설치해야 한다.

npm install -D @babel/core @babel/preset-env @babel/preset-react babel-loader

2) webpack.config.js 작성
아래처럼 작성하되, {runtime: 'automatic'} 이 항목이 들어가야 에러없이 잘 빌드된다.
runtime 옵션은 바벨의 옵션으로 기본값은 classic이며, automatic으로 설정하면 JSX가 변환하는 함수를 가져온다.

//...
module: {
  rule:[
    {
      test: /\.(js|jsx)$/,
      use:{
        loader: "babel-loader",
        options: {
          presets: [
            "@babel/preset-env",
            ["@babel/preset-react", {runtime:"automatic"}],
          ],
        }
      },
      exclude: /node_modules/,
    }
  ]
}
//...

3) 빌드하기
그 다음 npx webpack 명령어나 npm run build 명령어를 설정하여 빌드한다.
만약 깃헙 페이지로 배포할 예정이라면 output.path설정에서 폴더명을 'docs'로 해야 한다.

profile
프론트엔드 개발자 NH입니다. 시리즈로 보시면 더 쉽게 여러 글들을 볼 수 있습니다!

0개의 댓글