Front-End/Web & 표준 & ETC

웹팩과 바벨 (Webpack vs Babel) 넌 또 누구냐!!

Voyage_dev 2022. 7. 5. 16:04

웹팩이란 (WebPack)?

웹팩이란 최신 프론트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러로 웹 애플리케이션을 구성하는 자원(HTML, CSS, JavaScript)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구이다.

의존성을 분석해 모듈을 번들시켜주는 역할을 하며 프로젝트를 개발하다보면 수 많은 라이브러리들을 사용하게 되는데 빌드(build) 과정을 통해 하나의 파일로 짠! 하고 만들어준다.

웹팩의 등장 배경

웹팩이 등장한 이유는 크게 3가지이다

  1. 파일 단위의 자바스크립트 모듈 관리의 필요성
  2. 웹 개발 작업 자동화 도구 (Web Task Manager)
  3. 웹 애플리케이션의 빠른 로딩 속도와 높은 성능

웹팩설치

npm i react react-dom
npm i -D webpack webpack-cli  //-D는 개발환경에서만 쓰인다는 것

webpack.config.js라는 파일을 만들어준다. 반드시 저 이름이어야 웹팩이 설정을 인식한다

const path = require('path');
const webpack = require('webpack');

module.exports = {
    name: 'wordrelay-setting',
    mode: 'development', //실서비스에서는 production
    devtool: 'eval', //production일때는 hidden-source-map사용
    resolve:{
        extensions:['.js','.ts'] //js나 ts파일 확장자 있는지 찾는다.
    },

    //파일 합치기
    //두가지 파일을 합쳐서 app.js파일로 만들어 html이 실행할 수 있도록 만들어준다.
    
    entry: {
        app: './src/index',
    }, //입력

		 module: {
        rules: [
            {
            test: /\\.ts?$/,
            exclude : /node_modules/,
            loader:'ts-loader',
            },
            {
            test: /\\.css$/,
            use: ['style-loader','css-loader']
            }
        ]
    },
    plugins: [
        
    ],
    output: {
        filename: '[name].js',
        path: path.join(__dirname, 'dist'),
    }
}

Node의 경로를 처리해주는 path 모듈과 webpack 모듈을 불러와야한다.

resolve는 웹팩이 알아서 경로나 확장자를 처리할 수 있게 도와주는 옵션이다. extensions에 넣은 확장자들은 웹팩에서 알아서 처리해주기 때문에 파일에 저 확장자들을 입력할 필요가 없어진다. 그리고 modules에 node_modules를 넣어야 디렉토리의 node_modules를 인식하게 된다.

웹팩 속성

엔트리 포인트를 시작으로 연결되어있는 모든 모듈을 하나로 합쳐서 결과물을 만드는 것이 웹팩의 역할이다. 웹팩을 사용할 때 중요한 속성이 4가지가 있다.

Entry / Output / Loader / plugin

Entry

웹팩은 하나의 시작점 (entry point)로부터 의존적인 모듈을 전부 찾아내서 하나의 결과물을 만들어낸다. 그렇기 때문에 entry 속성은 웹팩에서 웹 자원을 변환하기 위해 필요한 최초의 진입점이자 자바스크립트 파일 경로이다. 즉, entry를 통해 모듈을 로딩하고 하나의 파일로 묶는다.

  • mode : 웹팩의 실행모드를 의미, 개발 또는 프로덕션과 같은 모드
  • entry : 모듈이 시작되는 부분, 시작점 경로를 지정
entry: {
        app:'./src/index'
        another: './src/greeting'
        main:['./src/hi', './src/bye']
    },

app이 객체의 키로 설정되어 있는데 이 부분 이름은 자유롭게 수정 가능하다. 저 키 이름이 곧 결과물의 파일명이 된다. 즉, app이면 app.js가 파일명이 된다. entry 파일은 여러개가 될 수도 있으며 반대로 하나의 entry파일로 묶을 파일을 여러개 지정할 수도 있다. 이 때는 배열로 감싸주면 된다.

Output

  • output: 번들링된 파일들을 어디에 저장할지, 어떤 이름으로 할 것인지 알려준다. 일반적으로 dist, build라는 이름의 폴더를 사용한다. (기본값이 ./dist/app.js)
output: {
        filename: '[name].js',
        path: path.join(__dirname, 'dist'),
        publicPath: "/public/",
    }
  • path는 output으로 나올 파일이 저장될 경로
  • publicPath는 파일들이 위치할 서버 상의 경로
  • filename의 '[name].js' 는 앞서 entry 부분에서 키로 설정한 이름이 들어간다
  • path.join은 앞서 불러온 path모듈의 메서드로, 인자로 넣은 경로명들을 합쳐준다.
  • __dirname은 현재 디렉토리를 뜻하므로 위의 예시로 현재 디렉토리에위치한 dist 폴더의 결과물을 생성한다

Loader

기본적으로 웹팩은 자바스크립트 및 JSON 파일만 읽을 수 있다. 하지만 Loader를 사용하면 웹팩이 자바스크립트 파일이 아닌 웹 자원 (HTML, CSS, 이미지, 폰트)들을 변환하고 이를 애플리케이션에서 사용하고 종속성 그래프에 추가할 수 있는 유효한 모듈로 변환할 수 있다.

Loader는 타입스크립트 같은 다른 언어를 자바스크립트 문법으로 변환해주거나, 이미지를 data URL 형식의 문자열로 변환한다. 또한 CSS파일을 자바스크립트에서 직접 로딩할 수 있도록 해준다.

자주 사용되는 Loader로는

  • css-loader
  • style-loader
  • file-loader

Plugin

plugin은 웹팩의 기본적인 동작에 추가적인 기능을 제공한다. Loader는 파일을 해석하고 변환하는 과정에 관여하고, plugin은 해당 결과물의 형태를 바꾸는 역할을 한다. 예를 들어, 번들된 자바스크립트를 난독화 한다거나 특정 텍스트를 추출하는 용도로 사용한다.

압축을 한다거나, 핫리로딩을 한다거나, 파일을 복사하는 등의 부수적인 작업을 위한 부가기능이다.

Webpack build하기

npx webpack
//or
npm run dev

바벨이란?

바벨은 기본적으로 자바스크립트의 최신문법 및 사양을 지원하지 않는 브라우저에서도 쓸 수 있게끔 변환해주는 transcompiler이다.

사용하는 이유?

크로스 브라우징의 문제로 바벨이 탄생되었다. 크로스 브라우징이란 브라우저나 플랫폼마다 보여지는 모습이 다른 경우가 많은데, 이러한 차이를 최소화하여 브라우저, 환경에 영향을 최소한으로 받고 해당 웹 서비스를 사용할 수 있게 최적화를 하는 작업을 말한다.

이러한 크로스 브라우징 이슈를 해결하기 위해 생겨난 툴이 바벨이다. ES6+ 버전의 자바스크립트나 타입스크립트, JSX 등 다른 언어로 분류되는 언어들에 대해서도 모든 브라우저에서 동작할 수 있도록 호환성을 지켜준다.

loader에서는 이러한 바벨 등의 프론트엔드 빌드 과정을 웹팩의 번들링과 함게 쓸 수 있게 해주는 것이다. 번들링을 하면서 필요한 전처리나 컴파일까지 할 수 있다니 일석이조인데, 사용하지 않을 이유가 있을까?

바벨 외에도 타입스크립트를 컴파일해주는 ts-loader, css파일을 import 해주는 css-loader등이 있다

설치 방법

npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader

@babel/core : 바벨의 코어 패키지
@babel/cli :커맨드라인에서 파일을 컴파일하게 해주는 CLI 제공
@babel/preset-env : 구문변환에 대한 별도의 설정없이 최신 자바스크립트를 구형 브라우저에 사용할 수 있게 해주는 스마트 사전
@babel-loader: 바벨이랑 웹팩을 연결해준다

설정

module: {
        rules: [
            {
            test: /\\.ts?$/,
            exclude : /node_modules/,
            loader:'ts-loader',
            },
            {
            test: /\\.css$/,
            use: ['style-loader','css-loader']
            },
            {
          test: /\\.jsx?$/,
          loader: 'babel-loader', //js나jsx파일에 바벨로더를 적용해 최신문법이 옛날 브라우저에서도 돌아갈 수 있도록 해준다.
          options: {
            presets: [
          [
            '@babel/preset-env', {
              targets: { node: 'current' }, // 노드일 경우만
              modules: 'false',
              useBuiltIns: 'usage'
            }
          ],
          '@babel/preset-react', // 리액트를 쓴다면
          '@babel/preset-typescript' // 타입스크립트를 쓴다면
        ],
        ]
    },
  • test : 로딩할 파일을 지정
  • exclude : 제외할 폴더나 파일로, 바벨로 컴파일하지 않을 것들을 지정. 보통 node_modules
  • target : 지원하길 원하는 환경을 적는 곳
    • 현재 최신 버전 노드로 되어있는데 구 버전 노드 버전을 적어주면 구 버전 문법을 지원하기 위해 폴리필들이 추가되며, 노드 대신 브라우저를 타겟으로 할 수도 있다
  • modules를 false로 설정 : 최신모듈 시스템이 그대로 유지되면서 트리 쉐이킹이 된다.
    • 트리쉐이킹이란 ES2015 모듈 시스템에서 import 되지 않은 export들을 정리해주는 기능으로, 용량이 많이 줄어들기 때문에 꼭 사용하는 것을 권장한다. 단, commonJS나 AMD, UMD같은 모듈 시스템을 사용해야하는 클라이언트에서는 쓰면 제대로 처리되지 않는다.

 

 

출처 : 아래의 사이트들을 보면서 큰 공부 하였습니다

https://velog.io/@ellie12/번들러-웹팩-바벨

https://devlog.jwgo.kr/2018/12/03/webpack-babel-react/

https://velog.io/@dbsbest10/Webpack-과-Babel이란-무엇일까

https://velog.io/@inust33/2주차-개념-스터디-웹팩과-바벨에-대해

https://velog.io/@dea8307/모듈-번들러-webpack과-babel

https://bribrie.tistory.com/84

https://joshua1988.github.io/webpack-guide/guide.html