유지보수 가능한 Tailwind와 shadcn/ui · 방법 안내

기존 Tailwind와 shadcn/ui 화면을 감사하는 방법

기존 화면의 owner 누수, raw color, 동적 class와 shadcn update 위험을 찾아 안전하게 리팩터링합니다.

검증일 근거 자료

사용 시점

이 방법 안내서는 Tailwind와 shadcn/ui를 이미 사용하는 화면에서 변경 위치가 불분명하거나 override가 반복될 때 사용함

목표와 범위를 고정함

감사 대상은 한 feature 또는 한 변경 흐름으로 제한한다. 저장소 전체 class 수를 줄이는 작업으로 확대하지 않는다. 결과물은 owner별 문제 목록, 같은 owner 안에서의 수정, 검증 증거다.

  1. live context를 수집함

    pnpm exec shadcn info --json -c apps/web
    rg -n "@theme|@source|@custom-variant" packages/ui apps/web
    rg -n "@base-ui/react|#[0-9a-fA-F]{3,8}|(?:bg|text|border)-(?:slate|gray|zinc|neutral)-" apps/web

    DESIGN_SYSTEM.md, 가장 가까운 AGENTS.md, components.json, theme provider, token adapter, cn 구현과 대상 primitive를 함께 읽음

  2. 각 문제에 owner를 하나 지정함

    관찰owner기본 조치
    light·dark 값이 호출부마다 다름theme providersemantic role의 실제 값을 통합함
    같은 intent의 padding·color override가 반복됨shared primitive기존 variant를 사용하거나 닫힌 variant를 추가함
    업무 상태와 문구가 공용 component에 있음product composition앱으로 내림
    one-off grid formula가 있음page·feature호출 위치에 유지함
    vendor markup에 !important가 있음scoped integration CSSversion과 제거 조건을 기록함

    owner가 둘이면 변경을 분리하고 dependency 방향을 설명함

  3. 위험도가 높은 패턴부터 교정함

    우선순위는 동적 class fragment, 존재하지 않는 semantic utility, app의 headless primitive 직접 import, raw color, 반복되는 내부 style override 순서로 둠

    // 피할 방식
    <div className={`bg-${tone}-600`} />
    
    // 사용할 방식
    const toneClass = {
      default: "bg-primary text-primary-foreground",
      danger: "bg-destructive text-destructive-foreground",
    } as const;

    layout formula와 renderer literal까지 무조건 token으로 바꾸지 않는다. owner와 변경 이유가 다른 예외는 inventory로 남김

  4. shadcn source 변경을 preview함

    pnpm exec shadcn docs button -c apps/web
    pnpm exec shadcn add button --dry-run -c apps/web
    pnpm exec shadcn add button --diff button.tsx -c apps/web

    upstream 접근성·API 변화와 local variant를 구분해 필요한 부분만 병합함. local 수정이 있는 계층에는 --overwrite를 기본값으로 사용하지 않음

  5. owner에 비례해 검증함

    pnpm run fmt:check
    pnpm run lint
    pnpm --filter @jongminchung/web run typecheck
    pnpm --filter @jongminchung/web run test
    pnpm --filter @jongminchung/web run build

    primitive 동작이 바뀌면 keyboard, focus, accessible name과 dismissal을 확인하고, token이 바뀌면 모든 consumer의 light·dark 결과를 확인함

결과를 owner 단위로 보고함

  • 어떤 결정을 theme, primitive, composition 또는 page로 이동했는지 기록함
  • 선택한 기존 variant와 semantic token을 명시함
  • 실행한 검사와 결과를 남김
  • 유지한 예외에는 owner, 이유, 범위와 제거 조건을 남김

완료 조건

  • 새 동적 class fragment와 consumer raw color가 없음
  • app이 공용 접근성 경계를 우회하지 않음
  • 반복 override가 variant 또는 제품 composition으로 수렴함
  • components.json alias와 Tailwind @source가 실제 경로를 가리킴
  • 변경 범위에 맞는 interaction과 visual 결과가 확인됨