프론트엔드/실전 리액트 프로그래밍

[스터디 with 실전 리액트 프로그래밍] 17편 - 웹팩

Junheehee 2022. 8. 22. 20:56

실전 리액트 프로그래밍

 

웹팩(Webpack)

 

웹팩은 모듈 번들러다.

모듈은 자바스크립트 파일 같은 리소스 파일이고, 번들은 여러 모듈로 만들어진 결과 파일이다.

 

2000년대 초반의 웹 페이지는 페이지가 바뀔 때마다 새로운 HTML을 요청해서 화면을 그리는 방식이었다.

이 때는 페이지당 필요한 리소스 파일이 많지 않아서 웹팩과 같은 번들러가 필요하지 않았다.

하지만 single page application이 등장하면서 하나의 HTML 파일이 많은 자바스크립트 파일을 포함했고, 더이상 script 태그로 불러오기에는 무리가 있었다.

파일이 실행되는 순서도 신경써야 하고, 변수를 덮어쓰는 위험도 생겼기 때문이다.

그래서 이런 문제점을 해결해주는 웹팩이 등장했다.

 

 

 

 

webpack-cli

 

webpack-cli는 webpack을 cli에서 실행할 수 있게 해준다.

webpack을 설치하고 webpack-cli로 실행해보자.

$ npm init -y
$ npm install webpack webpack-cli

 

 

// util.js

export function sayHello(name) {
  console.log(`hello ${name}`);
}

간단한 함수 하나를 정의했다.

 

 

// index.js

import { sayHello } from "./util";

function func() {
  sayHello("Junhee");
  console.log("func!!");
}

func();

 

 

sayHello를 import 해서 호출하는 함수를 정의했다.

 

 

$ npx webpack
// ./dist/main.js

(()=>{"use strict";console.log("hello Junhee"),console.log("func!!")})();

웹팩을 실행하니, dist 폴더가 만들어지고 main.js 번들 파일이 생겼다.

별다른 설정 없이 웹팩을 실행하면 ./src/index.js 모듈을 입력으로 받아서 ./dist/main.js 번들 파일을 만든다.

 

위처럼 export, import 키워드로 모듈을 불러올 수 있는 것은 웹팩이 ESM을 지원하기 때문이다.

 

 

 

 

webpack.config.js

 

babel.config.js처럼 웹팩도 webpack.config.js 파일을 이용해서 설정할 수 있다.

 

 

// webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist"),
  },
  mode: "production",
  optimization: { minimizer: [] },
};

 

 

 

index.js를 입력 파일로 사용해서 dist 폴더에 main.js 번들 파일을 생성한다.

코드를 확인하기 위해 optimization 속성에서 압축 설정을 하지 않았다.

 

웹팩을 실행하면, main.js가 생성된 것을 확인할 수 있다.

// ./dist/main.js

/******/ (() => {
  // webpackBootstrap
  /******/ "use strict";
  var __webpack_exports__ = {}; // CONCATENATED MODULE: ./src/util.js

  function sayHello(name) {
    console.log(`hello ${name}`);
  } // CONCATENATED MODULE: ./src/index.js

  function func() {
    sayHello("Junhee");
    console.log("func!!");
  }

  func();

  /******/
})();

 

 

 

 

로더(loader)

 

로더는 모듈을 입력으로 받아서 원하는 형태로 변환한 후 새로운 모듈을 출력해 주는 함수다.

자바스크립트 파일을 처리하는 babel-loader, css 파일을 처리해주는 style-loader, css-loader 외에도 json, txt, png 등의 파일을 처리해주는 로더가 존재한다.

 

 

url-loader로 이미지 모듈을 처리해보자.

 

// ./src/index.js

import { sayHello } from "./util";
import Icon from "./react-icon.png";

function func() {
  sayHello("Junhee");
  console.log("func!!");
  console.lo(Icon);
}

func();

이미지 하나를 다운받은 뒤 import 했다.

 

// webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: "url-loader",
          },
        ],
      },
    ],
  },
  mode: "production",
  optimization: { minimizer: [] },
};

 

webpack.config.js에 이미지 모듈을 url-loader가 처리할 수 있도록 설정했다.

물론 url-loader도 "npm install url-loader" 명령어로 설치해야 한다.

 

웹팩을 실행하니, 이미지가 데이터로 변환되었다.

url-loader로 이미지 파일 처리

 

 

이미지 파일의 크기가 크면 자바스크립트가 늦게 실행됨으로 크기가 작은 이미지 파일만 데이터로 변환하는 것이 좋다.

options 속성을 통해 변환 파일의 크기를 제한할 수 있다.

 

// webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 1000,
            },
          },
        ],
      },
    ],
  },
  mode: "production",
  optimization: { minimizer: [] },
};

이미지의 크기가 options의 limit보다 크면 url-loader가 아닌 file-loader가 처리한다.

file-loader는 모듈을 데이터로 변환하지 않고, dist 폴더에 추가한다.

그리고 파일 이름을 해시값으로 변경함으로써, 브라우저의 캐싱 효과를 활용한다.

 

file-loader로 이미지 파일 처리

 

 

 

 

플러그인

 

웹팩에는 로더말고 플로그인도 있다.

플러그인은 웹팩이 실행되는 전체 과정에 개입하면서 기능을 수행한다.

 

번들 파일명을 해시값으로 설정할 경우, 파일이 수정될 때마다 파일명도 바뀐다.

html-webpack-plugin은 그에 맞춰 html 파일에서 사용하는 번들 파일명도 자동으로 수정해준다.

 

 

 

 

트리 쉐이킹(tree shaking)

 

트리 쉐이킹은 불필요한 코드를 제거해 주는 기능이다.

나무를 흔들어 죽은 잎을 떨어뜨리는 것을 비유해서 지은 이름이다.

웹팩은 기본적으로 이 트리 쉐이킹 기능을 제공해서 번들 파일을 최적화해준다.

 

이 때 ESM이 아닌 commonJS 모듈 시스템을 사용한다면 트리 쉐이킹이 되지 않는다.

commonJS 모듈 시스템은 module.exports와 require 등의 키워드를 사용한다.

 

 

 

 

이 외에도 웹팩에는 다양한 기능이 있다.

번들 파일의 크기가 너무 크다면 최적화를 위해 분할할 수도 있다.

또 여러 로더와 플러그인이 존재하며, 목적에 맞게 자체 제작해서 사용 가능하다.

 

 

 

 

코드

 

 

GitHub - junhee-won/react-study: with 실전 리액트 프로그래밍

with 실전 리액트 프로그래밍. Contribute to junhee-won/react-study development by creating an account on GitHub.

github.com