webpack

fe_sw·2022년 8월 24일
0

Webpack

목록 보기
1/4

웹팩이란

프런트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러이다.

모듈 번들러란, 애플리케이션을 구성하는 파일(HTML, CSS, Javscript, Images, font)등을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미한다.

자바스크립트 뿐만 아니라 자바스크립트 내에서 필요한 css나 img와 같은 파일(.css, .jpg)도 번들링해서 하나의 파일로 합쳐준다.

모듈이란

모듈이란 프로그래밍 관점에서 특정 기능을 갖는 작은 코드 단위를 의미한다.

// math.js
function sum(a, b) {
  return a + b;
}

function substract(a, b) {
  return a - b;
}

const pi = 3.14;

export { sum, substract, pi }

모듈 번들링이란

웹 애플리케이션을 구성하는 수십개의의 자원들을 하나의 파일로 병합 및 압축 해주는 동작을 모듈 번들링이라고 한다.

웹팩을 사용하는 이유

1.파일 단위의 자바스크립트 모듈 관리

자바스크립트의 변수 유효 범위는 기본적으로 전역 범위를 갖는다. 최대한 넓은 변수 범위를 갖기 때문에 어디에서도 접근할 수가 있다.

// app.js
var num = 10;
function getNum() {
  console.log(num);
}
// main.js
var num = 20;
function getNum() {
  console.log(num);
}
// index.html
<html>
  <head>
    <!-- ... -->
  </head>
  <body>
    <!-- ... -->
    <script src="./app.js"></script>
    <script src="./main.js"></script>
    <script>
      getNum(); // 20
    </script>
  </body>
</html>

이러한 문제점은 실제로 복잡한 애플리케이션을 개발할 때 발생한다. 변수의 이름을 모두 기억하지 않은 이상 변수를 중복 선언하거나 의도치 않은 값을 할당할 수 있다.

따라서 모듈단위의 개발은 가독성과 유지보수의 큰 이점을 가져와준다.

이처럼 파일 단위로 변수를 관리하고 싶은 욕구, 자바스크립트 모듈화에 대한 욕구를 예전까진 AMD, Common.js와 같은 라이브러리로 풀어왔다.

2.웹 개발 작업 자동화 도구

이전부터 프런트엔드 개발 업무를 할 때 가장 많이 반복하는 작업은 에디터에서 코드를 수정하고 저장한 뒤
브라우저에서 새로 고침을 누르는 것이었다. 그래야 화면에 변경된 내용을 볼 수 있었다.

또한 배포할 때 (HTML, CSS, JS, 이미지 압축, CSS 전처리기 변환)등과 같은 작업들을 해야 했습니다.

웹팩은 이런일들을 자동화 해준다.

3.웹 애플리케이션의 빠른 로딩 속도와 높은 성능

파일을 컴파일 할 때, 여러개 파일을 읽어오는데 시간이 오래 걸린다. 그 부분을 해결하기 위해
여러 파일을 하나의 파일로 번들링 해준다.-> 서버에 요청하는 파일의 숫자를 줄임(높은성능)

웹팩 기본설정

엔트리/아웃풋

웹팩은 여러개 파일을 하나의 파일로 합쳐주는 번들러(bundler)다. 하나의 시작점(entry point)으로부터 의존적인 모듈을 전부 찾아내서 하나의 결과물(output)을 만들어 낸다. app.js부터 시작해 math.js 파일을 찾은 뒤 하나의 파일로 만드는 방식이다.

// webpack.config.js

var path = require("path");
module.exports = {
  entry: "./src/index.js",
    output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./dist"),
  },
};
//filename: 웹팩으로 빌드(번들링)한 파일의 이름을 의미
//path: 해당 파일의 경로를 의미합니다.

로더

웹팩은 모든 파일을 모듈로 바라본다. 자바스크립트로 만든 모듈 뿐만아니라 스타일시트, 이미지, 폰트까지도 전부 모듈로 보기 때문에 import 구문을 사용하면 자바스크립트 코드 안으로 가져올수 있다.

이것이 가능한 이유는 웹팩의 로더 덕분이다. 로더는 타입스크립트 같은 다른 언어를 자바스크립트 문법으로 변환해 주거나 이미지를 data URL 형식의 문자열로 변환한다. 뿐만아니라 CSS 파일을 자바스크립트에서 직접 로딩할수 있도록 해준다.

// webpack.config.js

module.exports = {
  module: {
    rules: [],
  },
};

플러그인

웹팩에서 알아야 할 마지막 기본 개념이 플러그인이다. 로더가 파일 단위로 처리하는 반면 플러그인은 번들된 결과물을 처리한다. 번들된 자바스크립트를 난독화 한다거나 특정 텍스트를 추출하는 용도로 사용한다.
플러그인의 배열에는 생성자 함수로 생성한 객체 인스턴스만 추가될 수 있다.

// webpack.config.js
var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  plugins: [new HtmlWebpackPlugin(), new webpack.ProgressPlugin()],
};

webpack 설치

npm i webpack webpack-cli --save-dev

package.json scripts 추가

  "scripts": {
    "build": "webpack"
  }

webpack.config.js 추가

const path = require("path"); //node path module
const webpack = require("webpack");
const childProcess = require("child_process"); //깃 명령어가능
const HtmlWebpackPlugin = require("html-webpack-plugin"); //html도 빌드가능
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); //build시 이전 build 결과물 삭제
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {//es6가아닌 node가 사용할 모듈시스템
  mode: "development", //개발환경
  entry: {
    main: "./src/app.js", //모듈의 시작점
  },
  output: {
    filename: "[name].js", //결과 파일이름
    path: path.resolve("./dist"), //절대경로계산해주는 resolve
  },
  module: {//로더 js뿐만아닌 다른파일도 모듈로처리해서 번들해줌
    rules: [
      {
        test: /\.(scss|css)$/, //로더가 처리해야될 파일들의 패턴(정규표현식)
        use: [
          process.env.NODE_ENV === "production"
            ? MiniCssExtractPlugin.loader
            :"style-loader", //style-loader:자바스크립트파일에서 css파일을 불러올수 있음(html파일에서 css직접불러오기 안해도됨)
          "css-loader", //css파일을 만나면 css-loader가 처리함
          "sass-loader" //sass,scss파일 처리
        ],
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: "url-loader", //이미지파일도 번들 (파일복사: file-loader,특정크기미만 js문자열처리: url-loader)
        options: {
          publicPath: "./dist/", //파일로더가 처리하는파일을 모듈로 사용했을때 경로를추가(index.html파일이 dist에 있는경우 사용x)
          name: "[name].[ext]?[hash]", //파일로더가 파일을 아웃풋에 복사할때 사용되는 파일명 [원본파일명].[파일확장자][캐쉬무력화를 위해 매번다른 해쉬값 적용]
          limit: 10000, //파일용량 10kb // 10kb미만은 url-loader로 처리->자바스크립트 문자열로 처리 , 이상이면 file-loader가 처리->파일복사
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader" // 바벨이 통합할수 있도록 해주는 로더 // use:["babel-loader"] 이런식도 가능
      }
    ],
  },
  plugins: [
    new webpack.BannerPlugin({//빌드된파일에 주석을 추가해주는 플러그인
      banner: `Build Data:${new Date().toLocaleDateString()} 
        Commit Version:${childProcess.execSync(
          "git rev-parse --short HEAD"
        )}//childProcess로 터미널 명령어 실행가능(깃 커밋 버젼)
        Author: ${childProcess.execSync("git config user.name")}
        `,
    }),
    new webpack.DefinePlugin({//개발환경,운영환경의 환경정보를 제공해줌
    }),
    new HtmlWebpackPlugin({//html도 빌드가능 (따로설치해야됨)
      template: "./src/index.html", //template 경로
      templateParameters: {
        env: process.env.NODE_ENV === "development" ? "(개발용)" : "production", //템플릿에 넣어줄 변수값
      },
      minify:
        process.env.NODE_ENV === "development" //디버깅위해 개발모드에서만 적용
          ? {
              collapseWhitespace: true, //빈칸제거
              removeComments: true, //주석제거
            }
          : false,
    }),
    new CleanWebpackPlugin(), //build시 이전 build 결과물 삭제 (따로설치해야됨)
    ...(process.env.NODE_ENV === "production"
      ? [new MiniCssExtractPlugin({ filename: "[name].css" })] //스트일시트 코드만 뽑아서 별도의 CSS 파일로 만들어 역할에 따라 파일을 분리
      : []) //브라우져에서 큰 파일 하나를 내려받는 것 보다, 여러 개의 작은 파일을 동시에 다운로드하는 것이 더 빠르다. //다른 플러그인 설정과 다르게 로더설정도 해줘야함
  ]
};

0개의 댓글