Programming/JS

[Webpack] Webpack 이란 무엇인가?

w00se 2021. 5. 16. 11:29

https://pixabay.com/ko/photos/양-귀-비-꽃-초원-6239705/

Webpack이란 무엇인가?


At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles.

 

위는 webpack 공식 문서에 나온 webpack에 대한 설명이다.

webpack은 module bundler(모듈 번들러)이며 webpack은 프로젝트에 사용된 module의 의존성 그래프를 바탕으로 하나 이상의 bundle을 생성한다.

 

'실전 리액트 프로그래밍'에 의하면 module(모듈)은 각 리소스 파일이며 bundle(번들)은 webpack 실행 후 반환되는 결과물이다.

 

webpack에 대한 자세한 설명은 아래 공식 문서 링크에서 확인 가능하다.

https://webpack.js.org/concepts/ 

 

Concepts | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

 

Webpack은 왜 필요한가?

webpack 없이 여러 개의 javascript 파일을 호출하는 방식은 아래와 같은 문제점이 있다.

 

1. 프로젝트 규모가 커지면(특히 SPA의 경우) javascript가 많이 포함되는데, 이런 경우 Html에 script 태그를 명시하고 관리하기  어렵다. => 여러 개의 파일을 로딩하는 것은 성능 저하를 저하시킬 수 있다.

2. 의존성에 의해 javascript가 실행되는 순서도 신경 써야 한다.

 

webpack은 애플리케이션에 사용된 javascript를 하나의 파일(또는 그 이상)로 합쳐 제공하므로 위에 명시된 문제를 해결할 수 있다.

Loaders와 Plugins

Loaders

- webpack은 기본적으로 javascript와 json 파일만 처리 가능하다.

- Loaders는 webpack이 다른 형식의 파일을 처리 가능하도록 만들어 준다.

ex) css-loader를 사용하면 webpack이 css 파일을 처리할 수 있다.

 

Plugins

- '실전 리액트 프로그래밍'에 의하면 plugin은 webpack이 실행되는 전체 과정에 개입할 수 있다.

- plugin을 통해 optimization, asset management and injection of environment variables 같은 작업을 수행할 수 있다.

 

Webpack을 이용한 개발환경 설정 연습

webpack으로 개발환경을 설정하고 style 설정 및 DOM 요소를 조작시키는 연습을 한 예제입니다.

 

directory 구조는 아래와 같습니다.

Direectory 구조

 

package.json

{
  "name": "practice_webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.14.2",
    "@babel/preset-env": "^7.14.2",
    "babel-loader": "^8.2.2",
    "clean-webpack-plugin": "^4.0.0-alpha.0",
    "css-loader": "^5.2.4",
    "html-webpack-plugin": "^5.3.1",
    "style-loader": "^2.0.0"
  },
  "devDependencies": {
    "webpack": "^5.37.0",
    "webpack-cli": "^4.7.0",
    "webpack-dev-server": "^3.11.2"
  }
}

 

webpack.config.js

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

module.exports = {
    entry: "./src/index.js",
    output: {
        filename: 'main.js', // main.js 라는 이름으로 번들 파일 생성
        path: path.resolve(__dirname, 'dist'),
    },
    resolve: {
        extensions: [".js", "jsx", ".css"], // extensions 배열에 있는 확장자는 생략 가능
    },
    module: { // loader 설정
        rules: [
            {
                test: /\.js$/,
                exclude: '/node_modules',
                use: 'babel-loader',
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'], // 확장자에 적용되는 loader가 두 개이 상이면 오른쪽 부터 적용
            }
        ]
    },
    devServer: {
        port: 5000,
        overlay: true,
        hot: true,
        // writeToDisk: true,
    },
    mode: 'production',
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: './template/index.html',
        })
    ]
}

사용된 loader

babel-loader: webpack에서 babel을 실행하기 위한 로더, babel 실행 시 babel.config.js에 설정된 파일이 적용된다.

css-loader: 확장자가 css인 모듈을 처리하기 위한 로더

style-loader: css-loader로 처리한 css 데이터를 번들 파일이 브라우저에서 실행될 때 style 태그로 삽입

*style-loader가 없으면 css 스타일이 적용되지 않음

 

사용된 plugin

CleanWebpackPlugin: 웹펙이 실행될 때마다 dist 파일을 정리해주는 pluginHtmlWebpackPlugin: template 옵션에 지정된 html에 파일 구조대로 html 생성하고 bundle 파일을 생성된 html에 script 태그로 삽입

 

webpack-dev-server

webpack-dev-server는 프론트엔드 개발환경에서 개발용 서버를 제공해 준다.

 

특징

- 모듈 내에서 수정 사항이 발생하면 빠르게 반영해준다.(HMR)

=> HMR 기능을 사용하기 위해서는 hot 옵션을 true로 설정해야 한다.

 

 

babel.config.js

const presets = ['@babel/preset-env'];

module.exports = { presets };

 

template/index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <title>webpack 연습</title>
    </head>
    <body>
        <div>
            <div id="text">
                텍스트
            </div>
            <button id="button_change_text_color">
                텍스트 색 바꾸기
            </button>
        </div>
    </body>
</html>

 

src/App.css

#text {
    color: #fd6165;
}

 

src/handleText.js

const printText = () => {
    const text = document.getElementById("text");

    console.log(text.innerText);
}

const changeTextColor = () => {
    const text = document.getElementById("text");

    text.style.color = "black";
}

export { printText, changeTextColor }

 

src/index.js

import { printText, changeTextColor } from './handleText';
import './App.css';

printText();

const button = document.getElementById("button_change_text_color");
button.addEventListener("click", changeTextColor);

 

실행 예시

개발 환경 설정 실행 예시


참고 자료

실전 리액트 프로그래밍 리액트 훅부터 Next.js까지(개정판) - 이재승

https://webpack.js.org/concepts/ - webpack 공식 문서

https://nesoy.github.io/articles/2019-02/Webpack - Nesoy Blog

https://jeonghwan-kim.github.io/series/2020/01/02/frontend-dev-env-webpack-intermediate.html - 김정환 블로그

 

주니어 개발자가 공부하며 정리한 포스트입니다!

혹시 본 게시글 중 틀린 내용이 있다면 댓글을 통해 알려주세요 :)

감사합니다.