웹팩을 알아보자

승환입니다·2023년 12월 15일
post-thumbnail

바닐라 자바스크립트를 공부를 하던중에 개발자 도구를 보니 네트워크탭에 무수히 많은 js,image,css파일이 다운되고 있는 걸 보았다.
지금까지 리액트만 써와서 자동으로 적용되는 웹팩만 써봤다.

웹팩은 모듈번들러다 많은 파일을 한 곳에 뭉쳐주는 것이다.

라고만 알고 있었다...
이번 기회에 웹팩이 어떻게 동작하고 적용하는지 그리고 왜 쓰는지 궁금해서 공부를 하려고한다.

웹팩 이전의 이야기

웹팩을 알기전에 module이라는 개념부터 짚고 넘어가야한다.
module이 뭘까?

모듈은 재사용이 가능한 하나의 파일이다.

옛날에 바닐라 자바스크립트로 코딩을 하고 그 모듈을 가져오기 위해서는

<script src="a.js"></script>
<script src="b.js"></script>
<script src="c.js"></script>
...

이런식으로 가져왔어야했다. 하지만 이런 무분별한 script태그는 변수나 함수 등 로직의 중복이 발생해서 값이 덮어씌어지던가 의도치않은 에러를 발생시킨다.
예를 들면 a.js에 number변수가 10이고 c.js에 number변수가 30이라면 number 변수가 덮어씌어져서 number는 30이 되는 것이다.

그렇다면 이 현상을 어떻게 해결할까?

처음에 시도한 방법은 즉시 실행함수를 쓰는 것이였다.
즉시 실행함수를 쓰면 scope가 나뉘어지면서 중복되는 네이밍을 방지해 값이 덮어씌어지는것을 방지할 수 있었다.

하지만 모듈단위로 개발을 하다보니 사용자가 웹 사이트에 접근할 때 사용자는 많은 파일을 다운받는다. a.js , b.js ,c.js 등등 프로젝트가 커질수록 이 현상은 커질 것이다.
즉 ,많은 파일들로 인한 네트워크 부하가 점점 커지면서 사용자 경험이 안좋아진다는 것이다.
즉시 실행함수는 중복로직의 문제는 해결했으나 네트워크 이슈의 해결책이 되지 못했다.

두번째 방법은 CommonJS를 이용한 방법 (require / export)
대체적으로 해결되었으나 브라우저에서는 호환이 안되는 단점이 있었다.

마지막으로 ES6모듈을 사용했다. (import / export)
로직의 중복과 덮어씌여지는건 완전히 해결되었다.
하지만 네트워크 부하가 심해지는 현상은 계속 지속되었는데 그때
webpack이라는 모듈번들러 도구가 나왔다.
webpack은 하나의 파일을 기점으로 의존되어있는 파일을 계속 참조해 하나의 파일로 합쳐주는 툴이다.

하나의 파일로 합쳐주다보니까 사용자가 웹사이트에 접근했을 때 파일 하나만 다운받으면 되기때문에 네트워크 비용이 감소한다. 즉 , 그만큼 사용자가 빠르게 웹페이지를 볼 수 있다는 뜻이다.


웹팩 문법 살펴보기

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
  entry: "./src/index.js", // 시작지점
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist"), // 나오는 곳
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // use: ["style-loader", "css-loader"],
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.jpg$/,
        use: ["file-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html",
    }),
    new MiniCssExtractPlugin({
      filename: "common.css",
    }),
    new CleanWebpackPlugin(),
  ],
  devServer: {
    static: {
      directory: path.resolve(__dirname, "dist"),
    },
    port: 8081,
  },
};
  • entry : 웹팩이 참조를 시작하는 파일 지점
  • output : 참조를 한 파일을 하나의 파일로 묶어줄텐데 그 묶은 파일은 filename , 즉 main.js이며 그 파일의 위치는 dist폴더 밑에 위치한다.
    rules: [
      {
        test: /\.css$/,
        // use: ["style-loader", "css-loader"],
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.jpg$/,
        use: ["file-loader"],
      },
    ],
  • css-loader : js파일에서 css를 import할 때 css를 해석할 수 있게해주는 도구
  • MiniCssExtractPlugin.loader : 번들화된 파일에 css를 link로 따로 처리해주는 툴
    왜 굳이 ? => 번들링 최적화가 된다. 왜냐하면 css와 js를 따로 정의를 해뒀으니까
  • test: /.css$/: 난 css만 처리해줄꺼야
  • use: ["file-loader"] : css도 해석해줬으니까 file도 좀 해석해줘
  • test: /.jpg$/ : jpg만 해석해줘
 plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html",
    }),
    new MiniCssExtractPlugin({
      filename: "common.css",
    }),
    new CleanWebpackPlugin는 할 때마다 지워달라는 (),
  ],

위의 output에서 번들화된 파일네임은 main.js다. js파일만을 가지고 프로젝트를 돌릴 수 없다. 그래서 HtmlWebpackPlugin으로 index.html로 바꿔준것이다.
MiniCssExtractPlugin는 아까 위에서 말한 css를 link에 넣을껀데 경로를 말하는 것이다. 경로는 common.css이다.
CleanWebpackPlugin는 웹팩 시작 쓸모없는거 지워달라는 뜻이다.


마치며

이번에 포스팅을 하면서 모듈의 역사와 웹팩이 무슨 이유로 등장했는지 , 그리고 간단하게 나마 나만의 웹팩 환경설정을 해봤다.
리액트에서 코드 스플릿팅 , 번들링 등 단어만 들어봤지 안에서 이런식으로 동작하는 처음 알았다. 여러모로 배울게 많고 배울게 있어서 좋은 것 같다.

profile
자바스크립트를 좋아합니다.

0개의 댓글