ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Webpack vs Vite
    CS 2024. 8. 16. 13:35

    웹 개발 환경은 빠르게 변화하고 있으며, 이에 따라 도구와 기술도 계속해서 진화하고 있다. 프론트엔드 개발을 할 때 필수적으로 사용되는 빌드 도구들이 있는데, 그게 바로 Webpack과 Vite이다.

     

    Webpack은 오랫동안 널리 사용되어 온 모듈 번들러로, 복잡한 웹 애플리케이션에서 효율적인 자원 관리와 성능 최적화를 위해 중요한 역할을 한다. 그러나 최근 Vite가 등장하게 되었는데, 이 Vite는 Webpack의 복잡성을 대체할 수 있는 간단하고 빠른 개발 환경을 제공하면서 많은 사람들에게 주목 받고 있다.

     

    이 Webpack과 Vite에 대해서 자세히 알아보도록 할건데, 그 전에 모듈 번들러가 무엇인지부터 알고 가도록 하자.

     

    번들링

    JS와 CSS 같은 파일들 하나하나를 모듈로 보고 이 모듈을 배포용으로 병합하고 포장하는 작업을 말한다.
    📌 참고 📌
    참고로 웹 개발에선 번들링을 빌드라고 할 수 있다.

     

    모듈 번들러 ❓

    번들링을 진행하는 개발 도구를 의미한다.

     

    모던 웹으로 발전하면서 html, css의 내용들이 JS 파일로 들어오게 되었다.

    그래서 JS 파일의 양이 절대적으로 증가하고, 이에 따른 세분화된 모듈 파일이 폭발적으로도 증가했다.

     

    이렇게 되면서 JS의 변수 스코프 문제와 웹 애플리케이션을 실행할 때 네트워크 쪽의 비용 문제까지 신경쓰게 되었다.

    특히나 웹 사이트 전처리의 요구사항이 점점 많아 지게 되며 이를 자동화 해줄 것들이 필요해지게 되었다.

     

    그럼 이제 용어를 알았으니, 본론으로 들어가보도록 하자.

    번들러 중에 가장 인기가 높은 Webpack에 대해서 먼저 살펴보자면,

     

    ❓ Webpack ❓

     

    Webpack은 모던 JavaScript 애플리케이션을 위한 정적 모듈 번들러이다.

     

    웹 애플리케이션의 구성 파일들 간에는 서로 관계가 있는데, 이러한 관계를 Webpack에서 인식해서 번들링을 하게 되면 기존 원본 파일들을 압축 및 축소하게 된다.

     

    웹 페이지가 배포되기 전 최적화된 파일 셋으로 뽑아내는데, Webpack은 모듈간의 관계를 적립하는 dependency(의존성) graph를 가져서 모듈 관리가 수월하다.

     

    🧐 왜 압축 및 축소를 할까? 🧐

    그 이유는 바로 웹 사이트 접속 시에는 굉장히 많은 파일들이 다운로드될 수 있는데, 이 양에 비례하여 서버의 자원을 소모하게 되고, 웹 사이트 로딩이 느려지는 현상을 막기 위해 압축과 축소를 진행한다.

     

    결국 성능 향상이 주된 목적인 것이다.

     

    ✅ Webpack 핵심 요소 ✅

    Entry

    Webpack이 애플리케이션의 dependency(의존성) 그래프을 구축하기 위해 시작하는 지점을 설정한다.

     

    최초 진입점이 되는 대상 파일에 담겨진 웹 애플리케이션의 전반적인 구조와 내용을 기반으로 Webpack이 모듈들의 관계를 분석하여 하나의 번들로 결합한다.

     

    이는 Webpack 설정의 필수적인 부분이며, Webpack이 어떻게 애플리케이션을 번들링할지 결정하는 중요한 역할을 한다.

    // Webpack.config.js
    
    // Singe page application(SPA)
    module.exports = {
      entry: ‘./src/index.js’
    }
    
    // Multi Page Application(MPA)
    module.exports = {
      entry: {
        login: ‘./src/LoginView.js’,
        main: ‘./src/MainView.js’
      }
    }

     

    이렇게 entry를 설정하고 Webpack을 실행하면 파일들이 빌드가 되고, 모듈간의 의존관계가 생기는 구조를 dependency(의존성) 그래프라고 한다.

    Output

    Webpack 실행하여 빌드하고 난 후 결과물의 파일 경로를 의미한다.
    // webpack.config.js
    var path = require('path');
    
    module.exports = {
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist')
      }
    }
    
    /* Node.js API가 하는 역할은 아래 코드와 동일하다. */
    output: './dist/bundle.js'

     

    위 코드를 조금 설명해보자면,

    • 'filename'은 Webpack으로 빌드한 파일의 이름을 의미한다.
    • 'path'해당 파일의 경로를 의미한다.

    path 속성에서 사용된 메서드는 인자로 받은 경로를 조합하여 유효한 파일 경로를 만드는 Node.js API이다.

     

    Loader

    Webpack이 애플리케이션을 해석할 때, JS 파일이 아닌 html, css, images, font 등을 변환할 수 있게 도와주는 속성이다.

     

    Webpack은 모든 파일을 모듈로 취급하여 관리를 하는데, 사실상 JS 파일만 알고 있어서 이 로더를 이용하여 다른 파일들을 Webpack이 이해할 수 있게 변경해줘야 한다.

     

    Loader를 설정해주지 않으면 Webpack은 해당 파일을 해석할 수 없어서 에러가 발생하게 된다.

     

    주로 사용되는 로더는 다음과 같다.

    • CSS Loader
    • Babel Loader
    • Sass Loader
    • File Loader
    • Vue Loader
    • TS Loader
    // webpack.config.js
    
    module.exports = {
      module: {
        rules: [
          { test: /\.css$/, use: 'css-loader' },
          { test: /\.ts$/, use: 'ts-loader' },
          // ...
        ]
      }
    }

     

    위 코드처럼 rules라는 객체의 속성을 지정하는데,

     

    test에는 로더를 적용할 파일의 유형을 명시해주는데 이때 일반적으로 정규 표현식을 사용하며, use는 파일에 적용할 로더의 이름을 명시해주면 된다.

     

    따라서 위에 코드에서는 CSS 파일에 'css-loader'를 적용하고, TS 파일에는 'ts-loader' 적용하겠다는 의미로 해석이 가능하다.

     

    Plugin

    Webpack의 기본적인 동작에 추가적인 기능을 제공하는 속성이다.

     

    Plugin은 Webpack의 기본 동작을 확장하거나 수정하는 데 사용된다.

    어떻게 보면 Loadeer와 Plugin은 둘다 추가적인 기능을 제공하는 속성이라 헷갈릴 수 있다.

    • Loader: 개별 파일을 해석하고 변환하는 과정에서 관여를 한다.
    • Plugin: 해당 결과물의 형태를 바꾸는 역할을 한다. 즉, 전체 번들링 과정에서 추가적인 작업을 하는 것이다.
    // webpack.config.js
    
    // 방법 1
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      plugins: [
        new HtmlWebpackPlugin(),
        new webpack.ProgressPlugin()
      ]
    }
    
    // 방법 2
    module.exports = {
      plugins: [
        require('webpack'),
        require('html-webpack-plugin')
      ]
    }

     

    위 코드에 두 plugin은 다음과 같다.

    • HtmlWebpackPlugin : 웹팩으로 빌드한 결과물로 HTML 파일을 생성해주는 플러그인
    • ProgressPlugin : 웹팩의 빌드 진행율을 표시해주는 플러그인

    Mode

    Webpack이 어떤 환경에서 빌드를 수행할지를 지정한다.

     

    기본 값은 production인데, development와 none 등의 모드를 통해 Webpack은 각 환경에 맞게 최적화 작업을 수행한다.

    이 설정은 Webpack이 빌드 과정을 어떻게 처리할지 결정하는 데 중요한 역할을 한다.

     

    production 모드에서는 코드 난독화, 압축, 최적화 작업 등을 지원해 준다.

    module.exports = {
      mode: 'production',
    };

     

    ❄️ Webpack과 브라우저 호환성 ❄️

    Webpack은 ES5가 호환되는 모든 브라우저를 지원하며, import()와 require.ensure()를 위한 promise를 요구한다.

     

    그럼 이제 Vite에 대해서 알아보도록 하자.

     

    ❓ Vite ❓

     

    Vite는 프랑스어로 "빠르다(Quick)" 의미를 가진다. 발음은 veet와 비슷하며, 빠르고 간결하게 모던 웹 프로젝트 개발 경험에 초점을 맞춰 탄생한 빌드 도구이다.

     

    Vite는 개발 시에는 네이티브 ES Module을 넘어 Hot Module Replacement(HMR)과 같은 더욱 다양한 기능을 제공한다. 번들링 시에는 Rollup 기반의 다양한 빌드 커맨드를 사용할 수 있어, 높은 수준으로 최적화된 정적 리소스들을 배포할 수 있게 제공한다.

     

    💡 Hot Module Replacement(HMR)이란 💡

    웹 개발에서 코드 변경 사항을 웹 페이지 전체를 새로 고치지 않고도 실시간으로 적용할 수 있게 해주는 기능이다.
    주로 개발 중에 사용되며, 개발자가 코드의 일부를 수정하면 해당 부분만 업데이트되어 브라우저에서 즉시 반영된다.

    이를 통해 개발자들은 빠르게 코드의 수정 결과를 확인하고 효율적으로 작업할 수 있다.
    💡 ESM(ECMAScript Modules)이란 💡

    ES6에서 도입된 JavaScript의 모듈 시스템으로, JavaScript 코드의 모듈화를 지원하여 코드의 재사용성과 유지보수성을 높이고, 의존성을 명확하게 관리할 수 있도록 도와준다.
    🔥 추가로 알아둬도 좋을 거 같은 또 다른 번들러 🔥

    [ esbuild ]
    esbuild는 다른 번들러가 내부적으로 JavaScript 기반으로 번들링하는 것과 다르게 Go언어를 기반으로 번들링한다.
    이는 기존 속도보다 더 빠르지만, 아직 설정이 유연하지 못하고 안정성에서 이슈가 있어 정식 버전은 출시되지 못한 상태라고 한다.

    Vite가 이 esbuild의 단점을 보완한 번들러이다.

    [ Rollup ]
    Rollup의 정체성은 확장에 있다.

    작은 코드 조각들을 거대하고 복잡한 애플리케이션 혹은 라이브러리로 만들어준다고 하는데,
    같은 소스코드를 다양한 환경에 맞춰 다르게 빌드하는 것이라고 생각하면 된다.

    그래서 애플리케이션 만들 땐 webpack으로, 라이브러리 만들 땐 rollup으로 라는 말도 나온다고 한다.

    Webpack과 사용방식과 구성방식은 거의 흡사한데, input과 entry, plugin 형태로 끼워 넣으면 된다.

    webpack은 모듈들을 함수로 감싸서 평가하는 방식을 사용하지만, rollup은 모듈들을 호이스팅하여 한번에 평가하기에 성능상 rollup이 더 빠르다는 특징이 있다.

     

    📌 Vite를 사용해야 하는 이유 📌

    빠른 개발 서버 시작

    다른 전통적인 번들러의 경우 개발 서버를 시작할 때 애플리케이션의 모든 파일을 읽고, 처리하며 번들링해야 한다.

    이 과정은 애플리케이션의 규모가 커질수록 더 많은 시간이 소요되며, 초기 로딩 속도를 늦춘다.

     

    효율적인 모듈 처리

    Vite는 애플리케이션 모듈을 두 가지 카테고리로 나눈다.

    • Dependencies: 일반적으로 변경되지 않는 라이브러리 코드(ex. React, Vue.js)이다. Vite는 이러한 라이브러리를 미리 번들링하고, 캐싱하여 빠르게 제공한다.
    • Source Code: 자주 변경되는 애플리케이션 코드이다. Vite는 이 코드들을 브라우저가 필요할 때마다 처리하여, 번들링 대신 브라우저의 네이티브 ES Modules 시스템을 활용해 전달한다.

    이 접근법은 브라우저가 실제로 필요한 코드만 로드하게 하여 개발 속도를 크게 향상시킨다.

     

    빠른 HMR(Hot Module Replacement)

    전통적인 번들러의 경우 코드가 변경될 때마다 전체 모듈 그래프를 다시 계산하고, 다시 번들링해야 하므로 많은 시간이 소요된다.

     

    Vite는 변경된 파일만을 실시간으로 처리하여 브라우저에 전달하기에, 개발 중 코드를 수정하면, 즉각적으로 변경 사항을 브라우저에서 확인할 수 있어, 빠른 피드백이 가능하다.

     

    네이티브 ES Modules 사용

    Vite는 브라우저에서 ES Modules를 네이티브로 지원하는 것을 적극 활용한다.

    이는 번들링 도구가 브라우저 대신 모든 모듈 관계를 관리하는 대신, 브라우저가 직접 모듈을 처리할 수 있게 하는 것이다.

     

    작은 번들 크기

    Vite는 배포 시 Rollup을 사용하여 최종 번들을 생성하는데, 이는 최적화된 정적 결과물을 만들어내, 배포되는 파일 크기가 작아지고, 로딩 속도가 빨라진다.

     

    🔥 Webpack vs Vite 🔥

      Webpack Vite
    개발 환경에서의 속도 모든 모듈을 사전에 번들링하여 개발 서버를 구동한다.

    이로 인해, 초기 빌드 시간 길어지고 HMR 속도도 느려질 수 있다.
    ES 모듈을 브라우저가 직접 처리하도록 하여 초기 빌드 시간을 크게 단축시킨다.

    개발 서버 구동 시, 전체 코드를 번들링하지 않고, 필요한 모듈만 로드하므로 HMR 속도도 매우 빠르다.
    빌드 방식 의존성 그래프를 통해 애플리케이션의 모든 모듈을 한 번에 번들링한다.

    이 방식은 최종 빌드 파일을 매우 최적화된 상태로 제공할 수 있지만, 큰 프로젝트에서는 빌드 시간이 길어질 수 있다.
    개발 중에는 ES 모듈 통해 빠른 피드백을 제공하고, 빌드 시 Rollup을 이용해 최적화된 번들링을 수행한다.

    이 이중 접근 방식 덕에 빠른 개발 경험을 제공하면서도 최적화된 빌드를 유지할 수 있다.
    플러그인과 생태계 플러그인 생태계가 매우 방대하여, 거의 모든 종류의 웹 프로젝트에 필요한 기능을 추가할 수 있다.

    플러그인 시스템의 확장성이 뛰어나고 커뮤니티의 지원도 강력하다는 특징을 가진다.
    Webpack에 비해서는 비교적 새로운 도구이지만, 빠르게 성장하는 플러그인 생태계를 가지고 있다.

    특히 Vue.js와 통합이 잘 되어 있어, Vue 기반 프로젝트에서 Vite를 사용하는 것이 매우 좋다.
    학습 곡선 다양한 기능과 설정 옵션을 제공하기에, 초기 학습 곡선이 다소 가파를 수 있다.

    특히, 복잡한 프로젝트에서 설정을 다루는 것이 힘들 수 있다.
    설정이 간단하고, ES 모듈 기반으로 작동하기에 사용하기 쉽다.

    기본 설정만으로도 대부분의 프로젝트를 시작할 수 있으며, 커스텀 설정이 필요할 경우에도 비교적 직관적이다.

     

    🧐 언제 어떤 걸 사용하는 게 좋을까 🧐

    Webpack 선택해야 할 때

    • 복잡한 프로젝트: 대규모의 복잡한 웹 애플리케이션에서 다양한 플러그인과 설정이 필요할 때 Webpack이 더 유리하다.
    • 커스텀 빌드 프로세스: 프로젝트에 특화된 빌드 프로세스나 복잡한 요구 사항이 있는 경우 Webpack의 유연한 설정과 플러그인 시스템이 큰 도움이 된다.
    • 레거시 지원: 오래된 프로젝트나 IE11 같은 레거시 브라우저 지원이 필요할 경우 Webpack 안정적이다.

     

    Vite 선택해야 할 때

    • 빠른 개발 환경이 중요한 경우: Vite는 매우 빠른 개발 서버와 HMR 성능을 제공하기 때문에 빠른 피드백 루프가 중요한 경우 이상적이다.
    • 작거나 중형 규모의 프로젝트: 간단하고 빠르게 설정할 수 있는 Vite는 작은 프로젝트나 스타트업에서의 프로토타이핑에 매우 적합하다.
    • 모던 브라우저 타겟팅: 최신 브라우저만을 타겟으로 하는 프로젝트라면 Vite ES 모듈 기반 접근 방식이 적합하다.

     

    📌 모듈 번들러가 필요한 이유 📌

    성능 최적화와 자동화

    모듈 번들러는 코드 축소와 사용하지 않는 코드 제거와 같은 최적화 작업을 수행하여 HTTP 요청 수를 줄이고, 웹 사이트 성능을 향상시킨다. 이로 인해 로딩 속도가 빨라져 사용자 경험이 개선된다.

     

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

    HTML, CSS, JS, 이미지, 폰트 등 모든 파일을 모듈화하여 웹 애플리케이션을 효율적으로 구성할 수 있다.

    모듈 번들러는 이러한 파일들을 하나의 프로젝트로 통합하여 관리할 수 있게 해준다.

     

    번들러가 제공하는 편의성

    Sass, Stylus, TypeScript 등과 같은 파일들을 사용할 때, 모듈 번들러는 필요한 컴파일 과정과 플러그인을 자동으로 처리해 준다.

    이를 통해 개발자는 더 쉽게 다양한 언어와 도구를 활용할 수 있다.

     

    Dependency issue(종속성 문제) 해결

    모듈 번들러는 서버와 브라우저 모두에서 원활하게 작동할 수 있도록 모든 종속성을 관리하고, 빌드 시 이를 포함하여 번들링을 진행한다. 이를 통해 종속성 관리가 간소화되고, 예기치 않은 충돌을 방지할 수 있다.

     

    🧐 그렇다면 Webpack을 Vite로 교체하는 게 좋을까? 🧐

    Vite는 번들링 속도면에서는 강점이 있지만, 마이그레이션과 안정성 측면에서의 문제가 거론되고 있다.

     

    Vite는 개발 환경에선 esbuild를 사용하지만 프로덕션 환경에서는 Rollup으로 번들링을 수행한다.

    따라서, Webpack에서 Vite로 마이그레이션을 하게되면 Rollup config를 설정하는 것에 시간이 많이 소요된다.

     

    Rollup 설정에는 CommonJS 처리나 Ployfill 처리 등이 되어 있지 않기에 플러그인을 하나하나 설치해야 하는 번거로움이 생긴다.

     

    게다가 개발 환경과 프로덕션 환경의 설정이 다르기에 빌드 안정성이 낮아서 개발 환경에서만 사용하는 경우도 적지 않다고 한다.

     

    이미 Webpack으로 구성된 프로젝트라면 굳이 Vite로 교체할 필요없이 플러그인 설정 등의 최적화 통해 빌드 속도를 개선하는 것이 더 좋다.

    'CS' 카테고리의 다른 글

    Ngnix란?  (0) 2024.08.22
    SEO(Search Engine Optimization, 검색 엔진 최적화)  (0) 2024.08.18
    자바스크립트(JS)의 클래스  (0) 2024.08.16
    자바스크립트(JS)의 prototype  (0) 2024.08.09
    자바스크립트(JS)의 Closure  (0) 2024.08.09
Designed by Tistory.