Skip to content

[ARCHIVED 2026-08-19] 역사 자료 — 현행 규범이 아니다. 아카이브 사유와 대체 문서는 docs/README.md의 Archive 섹션을 참조.

Vite Migration Proposal for Claude Design Review

Auth archive note (2026-08-03): 이 문서의 Kakao 전용 OAuth/API 지시는 현행 런타임에 적용하지 않는다. 현재 계약은 social-auth.mdcontracts/native-bridge.md를 따른다.

Ownership note (2026-07-23): this is a historical migration proposal. Its blanket “Codex does not edit src/react/ui/**” wording is superseded by docs/process/claude-free-design-contract.md: Claude owns visual design, while Codex may make design-preserving production bindings inside the UI surface.

이 문서는 Barbelic의 현행 무빌드 구조를 Vite 기반 ESM 앱으로 전환해도 되는지 Claude Design에게 검토 요청하기 위한 제안서다. 아직 실행 지시가 아니며, Claude Design의 동의와 보완 의견을 받은 뒤 단계별 작업으로 전환한다.

1. 개요

Barbelic 앱은 이전에 index.html에서 React, ReactDOM, Babel standalone, 서비스 파일, 모바일 UI, 데스크톱 UI, 컨테이너 파일을 <script> 순서 의존으로 직접 로드했다. 각 파일은 Gym/LiftGuild/UI 전역 객체를 노출했고, 부트 코드는 필요한 전역이 모두 생길 때까지 25ms 간격으로 최대 10초 동안 폴링했다.

이 구조는 Claude Design이 zip/prototype 형태로 UI를 넘기고, Codex가 곧바로 붙이기 쉬웠던 초기 단계에는 유효했다. 하지만 현재는 화면 수, 서비스 수, 모바일/데스크톱/iOS 플랫폼이 늘어났고, 부트 순서와 전역 의존이 계속 실무 비용을 만들고 있다.

따라서 제안은 다음과 같다.

  • main은 당분간 기존 window 전역 + Babel standalone 구조로 안정 배포를 유지한다.
  • 별도 Vite 전환 브랜치에서 ESM 기반 앱을 병렬로 만든다.
  • 각 단계는 배포 가능한 상태를 유지하며, 마지막에 충분히 검증된 Vite 앱으로 index.html을 교체한다.
  • Claude Design은 UI 컴포넌트를 window.Ui... 노출 방식에서 export function Ui... 방식으로 전환한다.
  • iOS 네이티브 브리지는 barbelic:native-auth CustomEvent 계약을 사용하므로 Vite 이후 별도 LiftGuild 전역을 유지하지 않는다.

2. 동기

2.1 현재 구조의 비용

현재 무빌드 구조는 다음 비용을 만든다.

  • index.html이 많은 <script>를 수동 순서로 관리한다.
  • 파일 추가/삭제 때마다 script 순서와 ?v= 캐시버스팅을 사람이 직접 갱신해야 한다.
  • bootLiftGuild가 전역 객체 생성을 기다리는 폴링 로직을 가진다.
  • 부트 레이스 때문에 최근 핫픽스가 반복적으로 발생했다.
  • 프로덕션에 react.development.js와 브라우저 Babel 컴파일이 그대로 나간다.
  • Node 테스트에서 React 컨테이너를 자연스럽게 import/render하기 어렵다.
  • 화면 간 공유 모듈이 어려워 아이콘, 상수, 차트 로직이 중복되기 쉽다.
  • classic <script>와 module 문법을 섞을 수 없어 점진적 ESM 전환에 제약이 크다.

2.2 왜 지금인가

최근 구조 정리로 다음 선행 조건이 어느 정도 갖춰졌다.

  • app.jsx가 얇아지고 컨테이너/서비스가 분리됐다.
  • src/react/ui/**와 앱 코어/서비스의 소유권 경계가 정리됐다.
  • codex/frontend, codex/backend, claude/ui, codex-mac/ios 역할 브랜치가 분리됐다.
  • 테스트가 늘어나면서 서비스/mapper/nav 동작을 보호할 수 있게 됐다.
  • Claude UI는 이미 모바일/데스크톱 화면을 독립된 컴포넌트 단위로 관리하고 있다.

즉, 지금은 빌드 시스템을 도입할 때의 변경 범위를 통제할 수 있고, 더 늦추면 script 순서와 전역 의존 비용이 더 커질 가능성이 높다.

3. 중요한 전제

3.1 classic script에 export를 섞지 않는다

현행 index.html<script> 로딩을 유지한 채 기존 파일에 export만 추가하는 방식은 금지한다.

이유:

  • classic script와 Babel standalone 환경은 ESM module registry가 아니다.
  • 현재 services 파일들은 type="module"이 아닌 classic <script src>로 로드된다.
  • 최상위 export가 들어가는 순간 기존 로딩 방식에서는 문법 에러 또는 실행 순서 문제가 발생한다.
  • 일부 파일만 <script type="module">로 바꾸면 classic script보다 나중에 실행되어 기존 LiftGuild 전역 순서 의존이 깨질 수 있다.

따라서 올바른 방식은 “현재 main을 그대로 두고, Vite 브랜치에서 ESM 앱을 병렬로 포팅한 뒤, 마지막에 검증된 스왑 PR을 여는 것”이다.

정확히 말해 “배포 앱을 그대로 유지한다”는 뜻은 기존 classic 파일에 export를 추가하면서 양쪽을 동시에 돌린다는 뜻이 아니다. 그런 듀얼 파일은 classic main에서 동작하지 않는다.

올바른 해석:

  • main: classic script + window 전역 구조를 그대로 둔다.
  • codex/frontend-vite: Vite/ESM 모듈 로딩 안에서 services를 export + window 노출 형태로 포팅한다.
  • 테스트 import 전환도 Vite 브랜치에서만 진행한다.
  • 최종 swap 전까지 main의 classic index.html과 services 파일은 export 없이 배포 가능 상태를 유지한다.

3.2 Vite 내부에서는 ESM export를 정본으로 둔다

Vite/ESM 컨텍스트에서는 각 서비스와 컨테이너가 명시적인 import/export로 연결된다.

js
export const BarbelicAuth = {
  startKakaoLogin,
};

iOS 네이티브 인증 복귀는 window 전역 함수 호출이 아니라 WebView 안의 barbelic:native-auth / barbelic:native-auth-complete CustomEvent 왕복으로 처리한다. 따라서 Vite 전환 후 앱 런타임에 BarbelicAuthBarbelicApi를 전역 네임스페이스로 노출하지 않는다.

3.3 services 포팅 소유권

services 포팅은 코드 위치상 codex/frontend가 주도하되, Auth/DB/API 의미를 가진 파일은 codex/backend 검토를 필수로 둔다.

파일작업 위치검토
barbelicNav.jscodex/frontend-
barbelicViewMappers.jscodex/frontend-
barbelicMappers.jscodex/frontend-
barbelicShared.jscodex/frontend-
supabaseAuth.jscodex/frontendcodex/backend 필수
barbelicRepository.jscodex/frontendcodex/backend 필수
barbelicApi.jscodex/frontendcodex/backend 필수

이 분류는 “Vite/ESM 전환은 앱 빌드와 컨테이너 구조 문제라 frontend 주도”라는 점과 “Supabase/Auth/API 동작은 backend 책임”이라는 점을 동시에 반영한다.

4. 제안하는 진행 절차

Phase 0. 합의 및 문서 확정

담당:

  • Codex Frontend: 초안 작성
  • Claude Design: UI 산출물 방식과 preview 방식 검토
  • Codex Backend: Auth/API/Vercel 영향 검토
  • Mac Codex: iOS CustomEvent 브리지 영향 검토

작업:

  • 이 문서를 Claude Design에게 공유한다.
  • Claude Design이 UI export 전환 방식에 동의하는지 확인한다.
  • Vite 전환 중에도 src/react/ui/** 소유권이 Claude에게 유지되는지 확인한다.
  • iOS 브리지가 barbelic:native-auth CustomEvent 계약으로 동작하는 것을 acceptance criteria에 명시한다.

승인 기준:

  • Claude Design이 “UI 파일을 export 컴포넌트로 넘기는 방식”에 동의한다.
  • Codex 쪽이 “main은 window 전역으로 유지, Vite 브랜치에서 병렬 포팅” 원칙에 동의한다.
  • Mac Codex가 iOS 로그인 복귀가 CustomEvent 계약으로 동작하는지 확인한다.
  • 병렬 브랜치가 장기화되지 않도록 전체 마이그레이션 타임박스와 중단 기준을 합의한다.

운영 guardrail:

  • codex/frontend-vite는 최소 주 1회 main 또는 역할 브랜치의 최신 변경을 반영해 드리프트를 줄인다.
  • Phase 2가 시작되면 최종 swap 전까지 큰 UI 변경은 동결하고, 작은 버그픽스만 허용한다.
  • Vite 전환이 정해진 타임박스 안에 패리티 검증 단계까지 도달하지 못하면, 전환을 멈추고 현재 무빌드 구조 유지 또는 범위 축소를 다시 결정한다.

Phase 1. Vite 병렬 브랜치 생성 + services ESM 포팅

담당:

  • 주 담당: codex/frontend
  • 검토 필요: codex/backend for Auth/API/Repository

권장 브랜치:

  • codex/frontend-vite

작업:

  • codex/frontend 최신 상태에서 Vite 실험 브랜치를 만든다.
  • vite, @vitejs/plugin-react, 필요 시 vitest를 dev dependency로 추가한다.
  • 새 진입점 후보를 만든다.
    • 예: src/react/main.jsx
    • 예: src/react/AppRoot.jsx
  • 기존 index.html은 main 배포용으로 유지한다.
  • Vite용 HTML 또는 entry는 별도 파일로 둔다.
    • 예: index.vite.html 또는 Vite 기본 index.html은 전환 브랜치에서만 사용
  • Vite 브랜치 안에서 services 파일을 ESM import/export 기반으로 포팅한다.
  • iOS 또는 외부 런타임과의 통신은 문서화된 브리지 이벤트로만 처리한다.
  • 테스트를 window-shim 기반에서 ESM import 기반으로 점진 전환한다.
  • Auth/API/Repository의 외부 동작은 바꾸지 않는다.

주의:

  • 이 단계에서 main 배포 앱을 깨지 않는다.
  • 기존 classic script 구조에 export를 섞지 않는다.
  • “export 추가”는 Vite 브랜치의 모듈 로딩 안에서만 한다.
  • Supabase/Auth/API 동작이 바뀌면 codex/backend 리뷰가 필요하다.

검증:

  • 기존 npm run check 통과
  • Vite dev 서버에서 빈 앱 또는 최소 root 렌더 확인
  • mapper/nav/auth/api 테스트 import 기반 통과
  • iOS CustomEvent 브리지 테스트 추가
  • 일반 브라우저에서 네이티브 브리지 핸들러가 없어도 에러 없음

Phase 2. Claude UI 컴포넌트 export 전환

담당: claude/ui

범위:

  • Claude 확인 결과 fixtures는 이미 ESM 형태로 관리되고 있으므로, Phase 2의 핵심 대상은 대부분 src/react/ui/**/screens/*.jsx 화면 컴포넌트다.
  • 주요 작업은 export function Ui... 추가와 window.Ui... = ... 노출 제거에 가깝다.
  • props 계약, fixtures, data-lg-* 마커는 유지한다.

작업:

  • src/react/ui/** 컴포넌트를 window 전역 노출 대신 named export 방식으로 전환한다.
  • 예:
jsx
export function UiHomeScreen(props) {
  return (...);
}
  • props 계약, data-lg-* 마커, fixture 철학은 유지한다.
  • Claude preview도 Vite dev 기준으로 단순화한다.

주의:

  • Codex는 src/react/ui/**를 직접 수정하지 않는다.
  • UI 화면 구조, 클래스명, CSS, flow 표현은 Claude Design이 소유한다.
  • Codex가 필요한 것은 import 가능한 component boundary와 props 계약이다.
  • Phase 2 시작 이후부터 최종 swap 전까지 큰 UI-flow 변경은 동결한다. 필요한 변경은 버그픽스 단위로 제한하고, Vite 브랜치에 즉시 반영한다.
  • Claude Design의 기존 standalone HTML preview는 Vite 기준 preview와 다르다. Vite 전환 중 preview 검증은 Claude Code 또는 Codex가 로컬 Vite dev 서버를 띄워 확인하는 방식으로 라우팅한다.

검증:

  • Claude preview에서 각 화면 독립 구동
  • 모바일/데스크톱 주요 화면 렌더
  • data-lg-* 계약 테스트 통과
  • Vite dev 환경에서 해당 UI 화면이 import 기반으로 렌더되는지 확인

Phase 3. React Container / Entry 전환

담당: codex/frontend

작업:

  • appController.jsx, sharedShell.jsx, mobileShell.jsx, mobileApp.jsx, desktopApp.jsx를 ESM import 기반으로 연결한다.
  • ReactDOM.createRoot를 Vite entry에서 실행한다.
  • bootLiftGuild 폴링을 제거한다.
  • Gym/UI/LiftGuild 일반 전역 의존을 제거한다.
  • desktop/mobile viewport 분기를 Vite entry 또는 React root에서 처리한다.

주의:

  • Vite 진입 모듈은 iOS 인증 복귀용 barbelic:native-auth 이벤트 리스너를 설치한다.

검증:

  • 모바일 웹: 홈, 운동 일지, 나의 기록, 내 정보
  • 데스크톱 웹: 홈, 운동 일지, 나의 기록, 내 정보
  • 운동 시작 -> 기록 -> 종료 -> 저장
  • 계획 작성/수정/삭제
  • PR 기록 -> 세션 상세 점프
  • 뒤로가기 레이어
  • 로그인 전/후 화면

Phase 4. Vercel / Dev Server 정리

담당:

  • codex/frontend: Vite build/dev 설정
  • codex/backend: API/Auth/Vercel route 확인

작업:

  • package.json에 build/dev script 추가
    • 예: dev, build, preview
  • Vercel build command 설정
    • 예: npm run build
  • Vercel output directory 설정
    • 예: dist
  • api/auth/** serverless function이 Vite build와 충돌하지 않는지 확인
  • 로컬 dev에서 /api/auth/kakao/* 처리 방식을 결정한다.
    • 선택지 A: vercel dev
    • 선택지 B: Vite dev proxy/middleware
    • 선택지 C: 기존 scripts/dev-server.mjs 일부 유지

검증:

  • Vercel Preview 정상 렌더
  • Kakao 로그인 start/callback 정상
  • iOS native OAuth start/callback 정상

Phase 5. 최종 Swap PR

담당:

  • 주 담당: codex/frontend
  • 검토: Claude Design, Codex Backend, Mac Codex

작업:

  • 기존 index.html script 폭탄 제거
  • Babel standalone 제거
  • React development CDN 제거
  • Vite build 산출물 기준으로 전환
  • 수동 ?v= 캐시버스팅 제거
  • 오래된 boot 폴링 제거

이 PR은 가장 위험한 전환 지점이다. 따라서 Vercel Preview에서 충분히 확인한 뒤 merge한다.

필수 검증:

  • Vercel Preview URL에서 모바일/데스크톱 렌더
  • iPhone 앱에서 로그인 및 세션 저장
  • iOS CustomEvent 인증 복귀 확인
  • Kakao 웹 로그인
  • Kakao iOS native login
  • 운동 저장/수정/삭제
  • 계획 저장/수정/삭제
  • PR 상세/세션 상세 이동
  • 뒤로가기 레이어
  • 콘솔 에러 0
  • npm run check 통과

5. 역할 분담

Claude Design: claude/ui

담당:

  • src/react/ui/**
  • 모바일/데스크톱 화면 컴포넌트
  • UI preview
  • props 계약 변경 제안
  • 화면 flow와 시각 디자인

Vite 전환 시 바뀌는 것:

  • 기존: window.UiHomeScreen = UiHomeScreen
  • 이후: export function UiHomeScreen(props)

유지되는 것:

  • data-lg-* 마커
  • props/callback 계약
  • fixtures 기반 preview
  • UI 소유권

Codex Frontend/App Core: codex/frontend

담당:

  • Vite 도입
  • ESM import/export 연결
  • React entry
  • app controller/container
  • mobile/desktop app composition
  • 테스트 import 전환
  • iOS CustomEvent 인증 복귀 리스너 설치

금지:

  • src/react/ui/** 직접 수정
  • iOS Swift/Xcode 직접 수정

Codex Backend/Platform: codex/backend

담당:

  • Supabase/Auth/API 동작 유지
  • Vercel serverless function 확인
  • Kakao login route 확인
  • repository/api service 동작 리뷰
  • RLS/RPC/schema 영향 검토

주의:

  • Vite 자체는 backend 변경이 아니지만, Auth/API route가 영향을 받으면 backend 리뷰가 필요하다.

Mac Codex/iOS: codex-mac/ios

담당:

  • iOS 앱 빌드
  • WKWebView / ASWebAuthenticationSession 회귀 확인
  • native bridge 확인
  • barbelic:native-auth / barbelic:native-auth-complete 이벤트 경로 확인

기대 영향:

  • 대부분 변화 없음
  • 최종 swap 이후 iOS 앱에서 WebView가 새 build 앱을 정상 로드하는지 확인 필요

6. Claude Design에게 확인할 질문

Claude Design에게 아래 항목을 확인받고 싶다.

  1. src/react/ui/** 산출물을 named export 컴포넌트 형태로 전환해도 되는가?

    • 예: export function UiHomeScreen(props) { ... }
  2. Claude preview를 Vite dev 기준으로 바꾸는 데 동의하는가?

  3. UI fixture와 props 계약 문서는 지금처럼 유지하되, import/export 기반으로 바꾸는 데 문제가 없는가?

  4. Vite 전환 동안 main은 기존 window 전역 구조를 유지하고, codex/frontend-vite 같은 별도 Vite 브랜치에서 병렬 포팅하는 전략에 동의하는가?

  5. 최종 swap PR 전까지 Claude UI 변경은 계속 claude/ui에서 진행하고, Codex는 그 변경을 Vite 브랜치에 주기적으로 반영하는 방식에 동의하는가?

  6. iOS 브리지를 barbelic:native-auth CustomEvent 계약으로 유지하고, 별도 앱 전역 API를 노출하지 않는 것에 동의하는가?

  7. UI 컴포넌트 파일에서 더 이상 window.Ui...를 노출하지 않는 최종 형태에 동의하는가?

  8. Phase 1에서 supabaseAuth.js, barbelicRepository.js, barbelicApi.js의 ESM 포팅은 codex/frontend가 진행하되, Auth/DB/API 의미 변경 여부를 codex/backend가 검토하는 방식에 동의하는가?

  9. Phase 2 시작 이후 최종 swap 전까지 큰 UI 변경을 동결하고, 필요한 변경은 작은 버그픽스 단위로만 처리하는 데 동의하는가?

  10. Vite 전환 중 UI preview 검증을 standalone HTML이 아니라 Claude Code 또는 Codex가 띄운 Vite dev 환경에서 수행하는 데 동의하는가?

  11. 병렬 Vite 브랜치를 최소 주 1회 최신 main/역할 브랜치와 동기화하고, 타임박스 안에 패리티 검증 단계에 도달하지 못하면 전환 범위를 재검토하는 데 동의하는가?

7. 제안 결론

Codex 측 제안은 다음과 같다.

  • Vite 도입은 진행하는 것이 맞다.
  • 단, 현행 classic script 파일에 export를 섞는 방식은 금지한다.
  • main은 안정 배포선으로 유지한다.
  • codex/frontend-vite 같은 병렬 브랜치에서 ESM 앱을 만든다.
  • Phase 1은 Vite scaffold, services ESM 포팅, 테스트 import 전환을 함께 진행한다.
  • Auth/Repository/API service 포팅은 codex/frontend가 작업하되 codex/backend 검토를 필수로 둔다.
  • Claude Design은 UI 파일을 export 컴포넌트 형식으로 전환한다.
  • Phase 2부터 swap 전까지 큰 UI 변경은 동결하고, Vite 브랜치는 최소 주 1회 최신 변경을 반영한다.
  • Vite preview 검증은 Claude Code 또는 Codex의 로컬 Vite dev 환경에서 수행한다.
  • Vite 이후 iOS 브리지는 barbelic:native-auth CustomEvent 계약으로 유지한다.
  • 마지막 swap PR은 Vercel Preview와 iOS 실기기 검증 후 merge한다.

Claude Design이 이 방향에 동의하면, Codex는 Phase 1부터 작은 PR 단위로 시작할 수 있다.