본문 바로가기
이론/Frontend

Webpack 빠르게 흝어보기

by 유세지 2022. 3. 15.

웹팩이란?

웹팩(Webpack)은 HTML, CSS, JavaScript 와 같은 코드들과 이미지, 동영상, 오디오 등 웹 페이지를 구성하는 자원들을 하나의 결과물로 묶어주는 모듈 번들러입니다.

 

여러 파일들이 상호작용하는 기존의 웹 환경에선 자바스크립트의 언어적 특성 때문에 발생하는 변수의 유효 범위 문제나, 개발과 배포시에 이루어지는 반복적인 작업에 대한 자동화의 필요성 등을 느끼게 되었는데요, 이러한 문제들을 해결하기 위해 AMD, Common.js, Grunt, Gulp 등과 같은 도구들을 이용해 왔습니다.

 

또한 좋은 사용자 경험을 위해 웹 사이트의 로딩 속도를 끌어올리려는 많은 시도가 있었는데, 그 중에서도 대표적인 것이 바로 서버에 요청하는 파일의 숫자를 가능한 줄이는 것이었습니다.

 

위에서 언급한 필요들을 충족시키기 위해선 다양한 기능들을 가진 새로운 도구가 필요하다는 결론에 도달했고, 널리 사용되고 있는 지금의 웹팩이 탄생하게 되었습니다.

 

 

빠르게 시작하기

$ npm i webpack webpack-cli webpack-dev-server --save-dev

npm i 명령어를 통해 webpack과 webpack-cli, webpack-dev-server를 설치합니다. webpack-cli는 webpack.config.js 파일을 통해 웹팩의 세부적인 부분을 다룰 수 있게 만들어주고, webpack-dev-server는 변경사항을 즉시 반영시켜주는 개발용 서버를 제공합니다.

 

 

설치가 끝났다면, 웹팩 구성 파일을 만들어줍니다. 예시로 이전에 사용했던 구성을 가져오겠습니다.

/* webpack.config.js */

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "development",
  entry: "./src/js/index.js",
  resolve: {
    extensions: [".js", ".css"],
  },
  devServer: {
    port: 9000,
  },
  devtool: "source-map",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-env"],
              plugins: ["@babel/transform-runtime"],
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset/resource",
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: "./index.html",
    }),
  ],
};

 

이제 웹팩의 설정을 변경하고 싶다면, 이 파일에서 원하는 기능들을 추가하거나 삭제해 줄 수 있습니다.

옵션들을 하나씩 살펴볼까요?

 

- Mode

모드(Mode)는 지정해주는 값에 따라 webpack이 내장하고 있는 최적화 기능을 사용할 수 있게 해주는 옵션입니다.

위 예시처럼 파일에서 명시해주거나, CLI 명령어에서 인수로 전달해 줄 수도 있습니다.

 

$ webpack --mode=development

 

지정할 수 있는 값에는 development와 production이 있으며, 설정하지 않은 경우 기본값은 production이 됩니다.

단, none을 넘기면 기본 최적화 옵션에서 제외시킵니다.

 

 

- Entry

엔트리 포인트(Entry Point)는 프로그램의 시작점을 지정하는 옵션입니다. 웹팩은 여기서 지정한 경로를 기점으로 내부의 디펜던시 그래프를 생성하고, 엔트리 포인트가 의존하는 다른 모듈과 라이브러리를 찾아냅니다. 아래처럼 배열 값을 주입하면 다중 메인 엔트리를 생성할 수 있습니다.

 

module.exports = {
  entry: ['a.js', 'b.js', 'c.js'],
  ...
}

 

구성 파일에 엔트리를 명시하지 않았을 경우, 기본값은 ./src/index.js 으로 설정됩니다.

 

 

- Resolve

리졸브(Resolve)는 모듈을 해석하는 방식을 변경합니다. 모듈 해석은 webpack의 기본값이 적용되지만, 경우에 따라 해석 방식을 명시해줌으로써 구체적으로 변경할 수 있게 됩니다.

 

그 중에서도 예시에서 사용된 extensions는 파일의 확장자 해석 순서를 변경합니다. 위처럼 할당된 값이 [".js", ".css"] 라면, 동일하면서 다른 확장자를 가진 파일이 있을때 배열 내부의 순서대로 해석하게 되며 나머지는 해석하지 않습니다. 또한 파일 import시 확장자를 생략할 수 있게 됩니다.

 

 

- devServer

devServer은 webpack-dev-server에서 쓰이는 옵션으로, 개발 서버가 동작하는 방식을 변경합니다. 예시에서는 실행 포트만 지정해주었지만, allowedHosts 옵션으로 화이트리스트를 지정하고, 로그 수준을 변경하는 logging, 오류와 경고를 브라우저 전체 화면에 띄우는 client 등 개발 전반에 필요한 옵션들을 지정 가능합니다.

 

 

- output

아웃풋은 컴파일 된 파일을 어떻게 저장할지 설정하는 옵션입니다. 입력(엔트리 포인트)은 다양하게 설정할 수 있지만 출력 설정은 하나만 가능합니다.

 

filename에는 출력할 파일의 이름을, path에는 파일이 저장될 경로를 설정할 수 있습니다. path를 설정하지 않으면 dist 디렉토리에 저장되게 됩니다.

 

 

- Module

모듈은 웹팩이 자바스크립트 파일이 아닌 다른 파일들을 변환하도록 도와주는 로더(Loader)를 감싸주는 옵션입니다. 예시에서는 바벨 로더와 스타일 로더, CSS 로더를 사용했습니다.

 

바벨 로더와 CSS 로더는 각 자원을 감싸는 역할을 하고, 스타일 로더는 CSS 파일을 별도의 분리된 파일이 아닌 인라인 스타일 태그로 추가되도록 만들어주는 역할의 로더입니다.

 

 

- Plugin

플러그인(Plugin)은 기본적인 웹팩의 동작에 추가 기능을 제공해주는 옵션입니다. 예시에서는 CleanWebpackPlugin과 HtmlWebpackPlugin이 사용되었습니다.

 

CleanWebpackPlugin은 빌드시 이전 빌드 폴더를 자동으로 정리하거나 삭제해주는 플러그인이고, HtmlWebpackPlugin은 빌드한 결과물들을 자동으로 추가한 HTML 파일을 생성해주는 플러그인입니다.

 

이 외에도 다양한 플러그인들이 있습니다.

 

 

 

명령어 설정

기본적이 구성이 완료되면, package.json에서 웹팩을 바로 사용할 수 있도록 명령어를 추가해줍니다.

 

"scripts": {
  "start": "webpack serve --open",
  "build": "webpack",
}

 

이걸로 웹팩을 사용할 준비가 끝났습니다!

 

참고 문서

Webpack 공식 문서

웹팩 핸드북 by 캡틴판교

JavaScript 표준을 위한 움직임: CommonJS와 AMD by Naver D2

 

반응형

댓글