Webpack 기초적인 사용법

Rosevilleage·2023년 3월 20일
0

대표적인 번들러인 webpack의 기초적인 사용법에 대해서 정리를 해본다.

webpack

자바스크립트 모듈 번들러로, 플러그인과 로더를 통해 자바스크립트 외의 소스 파일들을 번들링 할 수 있다.

번들링

개발단계에서 생성된 html, css, javascript, image 등의 파일들을 압축해 네트워크 코스트를 줄이는 방법으로 브라우저에서 필요로하는 파일들의 로드 시간 단축과 성능 향상을 목표로 한다.

왜 번들링을 통해 파일(모듈)들을 압축해 브라우저로 전달해야 하는가?

웹 생태가 점점 발전해 오면서 브라우저를 통해 제공되는 웹 서비스들은 사용자와의 더욱 많은 상호작용이 필요하게 되었고, 이는 필요한 파일 갯수의 증가로 이어지게 되었다.

브라우저는 렌더링이 진행될 때 웹 서버로부터 필요한 파일들을 다운 받아야 하기 때문에 웹 서버로부터 받아올 파일양의 증가는 로딩시간의 증가로 이어졌고 이는 안좋은 사용자 경험을 유발하게 된다.

또한 다운 받은 파일(모듈)들의 전역변수 충돌 등의 문제들 때문에 최종적으로 번들링을 사용하게 되었다.

webpack의 주요 개념

webpack은 공식문서에서 다음 여섯개의 개념을 핵심으로 꼽고있다.

  • Entry : 번들링을 시작하는 진입점

    연결된 다른 모듈과 라이브러리를 찾아내 의존성 그래프를 만들어 번들링에 사용한다.
    기본값은 ./src/index.js

  • Output : 생성된 번들을 내보낼 위치와 이름을 지정

    기본 출력값은 ./dist/main.js, 기타 파일은 ./dist 폴더에 저장된다.

  • Loders : javascript 외 파일들을 번들링할수 있도록 변환하는 로더들을 지정

    상위 수준의 로더는 두가지 속성을 가진다.

    • test : 변환이 필요한 파일들을 식별할 문자열
    • use : 사용될 로더를 가리킬 문자열(복수라면 배열형식)
  • Plugins: 번들을 최적화하거나 에셋 관리, 환경변수 주입 등 광범위할 작업을 수행할 플러그인들을 지정

    new 연산자로 플러그인의 인스턴스를 생성해 지정해 사용한다.

  • Mode : development, production, none 중 하나를 지정해 webpack에 내장된 환경별 최적화를 활성화

    기본값은 procuntion
    복수의 mode를 사용할 수도 있다.
    webpack 폴더를 만들어 common, dev, prod 파일을 만들어 mode 별 설정과 공용 설정을 나누고 webpack-merge를 install해 사용하는 방식으로 병합해 상황에 따라 사용 수 있다.

  • Browser Compatibility : es5가 호완되는 브라우저를 지원

    IF8이하를 제외한 es5를 지원하는 브라우저에서 사용 가능하다.

    webpack은 import(), export.ensure() 로 모듈을 불러올 때 Promise를 사용하기 때문에 Promise를 지원하지 않는 구형 브라우저를 지원하기 위해서는 폴리필을 로드해야 한다.

  • target : 특정 환경에 대한 런타임 코드를 생성하도록 지정

    기본값은 web으로 복수의 환경을 지정할때는 배열 형식으로 지정 가능하다. 하지만 모든 환경을 복수로 지정할 수는 없다. ex) [web, es5], node

기본적인 세팅과 사용법

생성된 작업 폴더를 다음 명령어를 통해 초기화 한다.

npm init -y

초기화가 완료되면 다음과 같이 package.json이 생성된다.

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

이후 로컬에서 webpackwebpack-cli를 설치한다.

npm install webpack webpack-cli -D

package.json의 scripts에 "build": "webpack"를 추가해 빌드시에 사용한다.

이후 webpack에 설정을 해주기 위해서 webpack.config.js파일을 생성하고 위에서 정리한 속성들을 필요에 따라 지정해주면 완료된다.

//webpack.config.js
const path = require('path'); // 경로 지정을 위해 npm 에서 불러온 모듈

module.exports = {
  target: ["web", "es5"],
  entry: "index.js", // webpack의 진입점
  output: { // 번들파일의 위치와 이름 dist폴더에 bundle.js라는 이름으로 생성된다.
    filename: "bundle.js",
    path: path.resolve(__dirname, "./dist")
  },
  mode: "development", // 필요에 따라 mode 별로 설정을 나눌 수 있다.
}

css를 변환해 번들에 추가하기 위해 로더를 install 한 후 추가 한다.

npm install style-loader css-loader -D
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader","css-loader"] // use는 오른쪽에서 왼쪽으로 읽히기 때문에 css-loader를 뒤에 위치해야 한다.
      }
    ]
  }
}

두 로더를 간단하게 설명하자면
css-loader는 js파일에 css파일을 모듈로 불러들일 수 있도록하는 역할을 하고,
style-loader는 html 파일에 <style> 태그를 통해 적용시키는 역할을 한다.

때문에 css-loader가 먼저 읽히도록 위치를 설정한다.

추가로 이미지를 사용해야 한다면 file-loader도 install 한다.

npm install file-loader -D
module: {
  rules: [
    {
      test: /\.jpg/,
      use: ["file-loader"]
    }
  ]
}

배포에는 html파일도 필요하기 때문에 plugin으로 html도 배포할 폴더에 변환해 생성한다.

npm install html-webpack-plugin -D
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin")

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

이렇게 진행 했을 때 webpack.config.js는 다음과 같은 모습을 하게 된다.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
  target: ["web", "es5"],
  entry: "index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./dist")
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader","css-loader"]
      },
      {
        test: /\.jpg/,
        use: ["file-loader"]
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin({
    template: path.resolve(__dirname, "src", "index.html")
  })]
};

추가적인 plugin들

추가적으로 dev-server와 clean-webpack-plugin등을 추가해 배포할 번들 폴더를 관리하거나 코드 변경사항을 브라우저에서 실시간으로 확인할 수 있다.

dev-serve를 사용하기 위해 먼저 install 해준다.

npm install webpack-dev-server -D

이후 webpack.config.js에서 devServer속성을 통해 경로와 port등을 설정하면 사용이 가능하다.

옵션들에 관한 내용은 여기서 다루기에는 조금 많아서 다른 포스트에서 정리한다.

devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    compress: true,
    port: 8080,
  }

파일이 변경되어서 이전 번들 파일이 필요하지 않게 되어도 생성된 번들 파일은 자동으로 사라지거나 하지 않는다. 그래서 clean-webpack-plugin을 통해 자동으로 관리되게 설정한다.

마찬가지로 플러그인을 install하고, webpack.config.js에 설정한다.

npm install clean-webpack-plugin -D
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    // ...
    new CleanWebpackPlugin(),
  ]
}

이후 배포를 할 때, 최적화를 위해 css를 처음부터 전부 가져오는 것이 아닌 필요한 상황이 올 때 가져오는 온 디멘드 로딩이 필요하다면,

style-loader를 mini-css-extract-plugin.loader로 교체해볼 수 있다.

mini-css-extract-plugin은 CSS 파일을 CSS 코드가 포함된 JS 파일 별로 생성하기 때문에 디멘드 로딩을 사용할 수 있다.

대부분의 경우에서 style-loader가 더 빠르지만, 특정 css 파일이 무거워 처음부터 전부 불러오는게 부담되는 상황이라면 mini-css-extract-plugin이 효율적일 수 있다.

npm install mini-css-extract-plugin -D
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"]
      }
    ]
  },
  plugins: [new MiniCssExtractPlugin()]
};

0개의 댓글