WiniLogis 프로젝트를 작업하며, 사내의 다른 Vite 기반 프로젝트들과 비교해 개발 환경 구동 속도가 39초로 현저히 느리다는 문제를 인지했습니다.
특히 코드 수정 시마다 브라우저가 전체 재렌더링되며 흰 화면이 노출되는 등, 개발 흐름을 반복적으로 끊는 비효율이 발생하고 있었습니다.
또한 Jenkins 파이프라인의 빌드 시간이 길어, 코드 반영부터 배포 완료까지의 피드백 루프가 지나치게 늘어나는 문제도 함께 존재했습니다.
이러한 병목 지점을 해소하고 개발자 경험을 개선하기 위해, WiniLogis 프로젝트에 Webpack → Vite 마이그레이션을 진행했고, 그 과정과 결과를 공유하고자 합니다.
Vite 선정 이유
1. Native ESM 기반의 압도적인 구동 속도
Webpack은 구동 시 프로젝트 전체를 번들링해야 하지만, Vite는 브라우저의 Native ESM 방식을 채택하여 번들링 없이 필요한 페이지를 즉시 띄웁니다. 또한 외부 의존성을 사전에 번들링하여 개발 서버 구동 시간을 획기적으로 단축합니다.
2. esbuild와 Rollup의 조합을 통한 성능 최적화
개발 환경에서는 Go 언어로 작성되어 압도적으로 빠른 esbuild를 사용하고, 운영 환경 빌드 시에는 안정적인 Rollup을 활용합니다. 이를 통해 로컬 개발 속도는 물론 CI/CD 파이프라인의 빌드 시간까지 줄일 수 있었습니다.

3. 사내 차세대 프로젝트와의 개발 환경 통일
현재 오토위니에서 진행되는 차세대 프로젝트들은 모두 Vite로 구성되어 있습니다. WiniLogis의 빌드 시스템을 이에 맞춰 마이그레이션함으로써, 프로젝트 간 개발 환경의 편차를 줄이고 팀 내 유지보수 효율을 극대화하고자 했습니다.
주요 마이그레이션 과정
1. 패키지 설치 및 설정 파일 생성
- 컴파일러 최적화: Babel 기반 플러그인 대신 Rust 기반의 @vitejs/plugin-react-swc를 설치했습니다. 이를 통해 개발 서버의 HMR 속도와 운영 빌드 시의 코드 변환 속도를 최대로 끌어올렸습니다.
- vite.config.ts: 기존 Webpack 설정이 출력 디렉토리를 build로 지정하는 것 외에 복잡한 로직이 없었기에, Vite로의 전환이 매우 수월했습니다. Plugin 적용, Path Alias(src), Dev Server 설정을 이 파일 하나로 통합하여 관리 효율성을 높였습니다.
- 타입 정의 추가: src/vite-env.d.ts 파일을 생성하여 ImportMetaEnv에 대한 타입 선언을 추가하고, 환경 변수 사용 시의 타입 안정성을 확보했습니다.
2. index.html 이동 및 수정
Vite는 public/index.html을 템플릿으로 사용하는 Webpack과 달리, 프로젝트 루트의 index.html을 진입점으로 삼기 때문에 아래와 같이 처리했습니다.
- 루트 이동: public/index.html 파일을 프로젝트 최상단(Root)으로 이동시켰습니다.
- 모듈 엔트리 추가: Vite가 애플리케이션 코드를 인식하고 Native ESM 방식으로 스크립트를 로드할 수 있도록 <body> 태그 내부에 <script type="module" src="/src/index.tsx"></script>를 삽입했습니다.
3. 환경 변수 파일 재구성
- 파일명 변경: 기존 Webpack 환경에서 사용하던 .env.local은 Vite에서 모든 모드(mode)에 공통으로 로드되는 특수 파일입니다. 이를 그대로 사용할 경우 환경별 설정 충돌이 발생할 수 있어, 로컬 개발 전용인 .env.development로 대체했습니다.
- 환경별 매핑: 테스트 배포용 .env.staging을 신규 생성하고, 운영용 .env.production과 함께 각 환경에 맞는 VITE_MODE 값을 할당했습니다.
4. 소스 코드 일괄 치환 (with Claude Code)
마이그레이션 전 참고했던 AB180의 기술 블로그에서 언급된 것과 동일하게 환경 변수 참조 방식에서 문제가 발생했습니다.
저는 이 문제를 Claude Code를 활용해 해결했습니다.
- Claude Code를 통해 약 50개 이상의 파일에 있는 177개의 process.env 참조를 import.meta.env로 전환했습니다.
- 문법 변환: process.env.NODE_ENV === 'production'을 Vite 내장 변수인 import.meta.env.PROD로 변경했습니다.
- 멀티라인 패턴 해결: Prettier의 줄 바꿈 규칙으로 인해 process.env\n .VARIABLE 형태로 끊겨 있는 코드는 일반적인 sed 명령어로 치환되지 않습니다. Claude Code의 제안대로 perl -0777 옵션을 사용하여 파일 전체를 하나의 문자열로 읽어 들여 예외 패턴들을 일괄 치환했습니다.
5. package.json 스크립트 변경 및 의존성 삭제
빌드 도구 교체에 따라 실행 스크립트를 최적화하고 불필요한 패키지를 정리하여 프로젝트를 경량화했습니다.
- 스크립트 갱신: 로컬 실행(start), 테스트 빌드(build:dev), 운영 빌드(build:prod) 명령어를 Vite CLI 기반으로 변경했습니다. 기존 Jenkins 파이프라인과의 호환성을 위해 명령어 명칭은 동일하게 유지했습니다.
- 의존성 경량화: webpack, babel-loader, css-loader, dotenv-webpack 등 기존 번들링에 사용되던 18개의 devDependencies를 제거했습니다. 이를 통해 node_modules 크기를 줄이고 의존성 관리 효율을 높였습니다.
6. CI/CD 파이프라인 대응 및 트러블슈팅

마이그레이션 완료 후 Jenkins 파이프라인 실행 시 빌드 에러가 발생했으며, 이를 해결하기 위해 서버 환경을 업데이트했습니다.
- Node.js 버전 업그레이드: 기존 Jenkins 서버의 Node.js 18.18.2v 환경이 최신 Vite 및 관련 의존성 라이브러리의 요구 사양을 충족하지 못해 빌드 오류가 발생했습니다. 서버의 Node.js 버전을 25v로 업데이트하여 호환성 문제를 해결했습니다.
- 빌드 결과물 경로 유지: 기존 Jenkins 파이프라인이 build/ 폴더를 바라보고 있었기에, Vite의 기본 출력 디렉토리인 dist 대신 build를 사용하도록 vite.config.ts 설정을 유지하여 파이프라인 수정 없이 배포가 가능하도록 했습니다.
마이그레이션 결과
1. 개발 서버 구동 속도: 39s → 148ms 프로젝트 전체를 번들링하지 않고 필요한 파일만 즉시 로드하는 Vite의 구동 방식 덕분에 속도가 약 260배 단축되었습니다.
2. 프로젝트 빌드 속도: 29.09s → 4.43s Vite의 최적화된 빌드 프로세스를 통해 소스 코드 번들링 시간이 약 85% 감소했습니다. 이를 통해 로컬 작업 중 발생하는 대기 시간을 최소화했습니다.
3. CI/CD 파이프라인 소요 시간: 3분 30초 → 1분 30초 빌드 성능 향상이 젠킨스 파이프라인에도 반영되어, 전체 배포 시간이 2분가량 단축되었습니다. 결과적으로 코드 푸시부터 배포 완료까지의 피드백 루프가 기존 대비 2.3배 빨라졌습니다.
느낀 점
1년 전 사수가 WiniLogis 관리자 프로젝트 마이그레이션을 진행할 당시, 옆에서 과정을 지켜보며 '내가 나중에 WiniLogis 웹 프로젝트를 직접 개선한다면 어떤 부분부터 손대야 할지'에 대해 많은 고민이 있었습니다.
3년 차 개발자가 된 지금, 로컬 개발 환경과 파이프라인 빌드 시간을 개선하기 위해 이번 마이그레이션을 주도하며 그 실마리를 찾을 수 있었습니다. 막연히 걱정했던 것보다 과정이 훨씬 수월하게 진행되는 것을 보며, "고민할 시간에 직접 부딪혀 보는 것이 정답"이라는 점을 다시 한번 깨달았습니다.

작업 완료 후 참고한 2025 State of JS에서 Vite가 가장 사랑받는 라이브러리 1위로 선정된 것을 보고 이번 마이그레이션이 올바른 선택이었다는 확신도 얻었습니다.
현재 WiniLogis는 Bitbucket 저장소를 사용하면서 배포는 Jenkins를 통해 진행하고 있는데, 저장소와 CI/CD 파이프라인이 통합되어야 관리 효율이 더 높다고 생각합니다. 이미 사내의 다른 프로젝트들도 통합 관리를 통해 안정적으로 운영 중인 만큼, WiniLogis 역시 조만간 Bitbucket Pipeline으로 이관하여 운영 환경을 일원화할 계획입니다.
'지식 정리 📝' 카테고리의 다른 글
| Android WebView 디버깅: chrome://inspect Pending authentication 오류 해결 (0) | 2026.03.12 |
|---|---|
| Frontend Kit – AI 문답 기능 도입 (Gemma 3 27B) (0) | 2026.02.27 |
| Keycloakify를 활용한 React 기반 Keycloak 테마 개발 및 다국어 처리 (2) | 2026.02.09 |
| Lighthouse 90점대인데 체감은 느린 이유? Vercel Region 최적화로 해결 (2) | 2026.02.03 |
| Autowini 프론트엔드 분리 프로젝트 CI/CD 파이프라인 구축 (Bitbucket 기반) 2 (0) | 2026.01.19 |