webpack -> Vite 마이그레이션

정태수·2026년 7월 29일
post-thumbnail

배경

React + TypeScript 기반 사내 대시보드의 프론트엔드 빌드 시스템을 Webpack에서 Vite로 전환했다. 이 프로젝트는 다음과 같은 특징을 가진, 마이그레이션 난이도가 낮지 않은 구조였다:

CRA(react-scripts) 잔재 + 커스텀 Webpack 설정이 혼재 — react-scripts, react-app-rewired를 devDependencies로 두고 있으면서, 동시에 webpack.config.js(공통) / webpack.dev.js / webpack.prod.js 등 커스텀 설정 파일을 직접 운용

7개의 배포 환경이 각각 별도 빌드 스크립트로 관리됨

jQuery 기반 레거시 라이브러리(daterangepicker, slick-carousel) 사용

Sentry 소스맵 업로드가 Webpack 플러그인에 강하게 결합

Kotlin/Gradle 백엔드와 같은 저장소에서 프론트엔드를 빌드하고, 결과물을 Thymeleaf 템플릿(index.html)으로 서빙하는 구조

왜 바꿨나

Webpack 기반 빌드/HMR 속도 개선
CRA 의존성(구버전 TypeScript 강제, 느린 재시작)에서 벗어나기
최신 프론트엔드 생태계(Vite 플러그인 생태계) 활용

무엇을 바꿨나

index.html 이동 및 진입점 명시

CRA 관례상 public/index.html에 있던 파일을 루트로 이동 시켰음. vite는 <script 태그> 직접 파싱해서 진입점 인식하기 때문에 HtmlWebpackPlugin이 자동으로 넣어주던것과 달리 엔트리 스크립트 태그를 ㅜ동으로 추가.

Thymeleaf 속성은 Vite의 파서가 손대지않고 그대로 통과시킴

Typescript 설정변경 : moduleResolution bundler로 변경
최신 패키지들은 package.json의 exports 필드로 타입 경로를 지정하는데 moduleResoluton: node 는 ㅇ ㅣ필드를 무시해서 타입선언을 못찾는 문제.

레거시 라이브러리 전역 노출 처리

daterangepicker가 내부적으로 window.moment, window.$를 참조하는 구조라 vite 환경에서 별도 전역 할당이 필요했음.

커스텀 vite 플러그인

마크업 팀에서 넘어온 css 파일에 실제로 존재하지 않는 .map 파일을 가리키는 주석이 남아 콘솔 경고 발생
vite 플러그인 파일에서 load ㅜㄱ에서 파일을 직접 읽어 주석 제거한 문자열 반환하도록 해결

서드파티 패키지 api 변경 대응

swiper/swiper-react → swiper/react (swiper 버전업에 따른 export 경로 변경)
sentry.config.js: CommonJS(module.exports) → ESM(export default) 전환 (Vite/ESM 환경에서 default import 호환을 위해)

profile
프론트엔드 개발자

0개의 댓글