본문으로 건너뛰기

결정-0018: 컴포넌트 워크벤치는 Storybook(angular-vite)으로 한다

상태

승인됨

맥락

디자인 시스템 컴포넌트를 앱 화면 없이 격리해서 보고 검토할 곳이 필요했습니다. 라이트와 다크 양쪽을 지원하기로 했으므로 두 모드를 함께 볼 수 있는지가 특히 중요했습니다. 한 모드만 보면 다른 쪽이 깨진 것을 늦게 발견하기 때문입니다.

당시 전제는 Angular 22와 Vite 기반 빌더, zoneless 구성, TypeScript 6, Tailwind 4, Vitest 4, 그리고 SSR 사용입니다.

워크벤치 설정은 이 저장소를 받는 쪽이 물려받아 유지해야 하는 부채입니다. 클론 직후 Docker 없이 빌드된다는 기준을 세울 때와 같은 종류의 고민이었습니다.

검토한 대안

Storybook (@storybook/angular-vite) — 채택

구분 내용
장점 사실상 표준이며 애드온 생태계가 있습니다. 접근성 검사와 뷰포트, 상호작용 테스트가 그것입니다. 스토리 포맷이 널리 알려져 있어 이 아키텍처를 채용하는 쪽이 이해하기 쉽고 링크로 공유할 수 있습니다
단점 preview 상태이며 문서가 API와 기본값이 바뀔 수 있다고 밝힙니다. 서드파티 Angular 변환 플러그인에 의존하고 Vite 버전이 둘로 갈립니다

Storybook (webpack)

stable 이지만 레거시 빌더를 peer 로 요구합니다. 현재 빌더와 다르므로 빌드 툴체인이 둘이 됩니다. 기각합니다.

자체 워크벤치 라우트와 Vitest

컴포넌트 갤러리를 라우트로 두고 자동 검증은 이미 있는 Vitest 가 맡습니다. 의존성이 0이고 버전 위험이 0입니다. 잃는 것은 격리 렌더링과 애드온이며, 접근성 자동 검사를 재현하려면 결국 직접 만들게 됩니다. Storybook 이 동작함을 확인했으므로 채택하지 않았습니다.

정적 빌드 후 서빙

HMR 이 없어 값 하나 바꿀 때마다 전체 재빌드를 수동으로 돌려야 합니다. 디자인 시스템 작업은 바꾸고 눈으로 확인하는 반복이라 이 비용이 큽니다. 기각합니다.

검증한 것

Storybook 을 고르기 전에 실제로 도는지 확인했습니다. 문서만으로는 이 조합에서의 동작을 알 수 없었기 때문입니다.

시그널로 갱신되는 컴포넌트를 워크벤치에 올려 브라우저에서 클릭했습니다. 정적 컴포넌트는 변경 감지가 깨져 있어도 렌더링되므로 검증이 되지 않습니다.

확인 항목 결과
dev 서버와 정적 빌드 양쪽의 DOM 갱신 클릭 수만큼 갱신되었습니다
window.Zone undefined 입니다. zone.js 없이 동작합니다. peer 로 선언되어 있지만 실제로 설치되지 않으며 앱의 zoneless 구성을 워크벤치가 깨지 않습니다

이것이 가장 걱정했던 지점이었습니다. 워크벤치만 zone.js 를 되살리면 한쪽에서만 재현되는 변경 감지 버그가 생깁니다. 그 위험은 실재하지 않았습니다.

결정

  1. @storybook/angular-vite 를 씁니다. 애플리케이션 빌더와 같은 Vite 계열이고 Vitest 애드온으로 상호작용 테스트를 붙일 수 있습니다.
  2. .storybook/tsconfig.json 을 반드시 둡니다.
  3. preview.ts 에 애플리케이션 프로바이더를 추가하지 않습니다. 워크벤치가 앱과 다른 변경 감지 설정을 쓰면 한쪽에서만 재현되는 버그가 생깁니다. 전역 스타일만 앱과 공유합니다.
  4. 모든 컴포넌트 스토리는 라이트와 다크를 나란히 띄웁니다. 테마 속성을 하위 트리에 걸 수 있게 만들어 둔 덕에 한 화면에 둘을 넣을 수 있습니다.
  5. 포맷 검사가 .storybook 도 검사합니다. 설정 파일이 포맷 게이트 밖에 있으면 반드시 어긋납니다.

주의

.storybook/tsconfig.json 이 없으면 원인을 찾기 어려운 방식으로 멈춥니다

프리셋이 Angular 변환 플러그인에 이 경로를 넘깁니다. 없으면 TypeScript 타입과 @Component 데코레이터가 변환되지 않은 채 브라우저로 나가 프리뷰가 SyntaxError 로 멈춥니다. 그 에러는 화면에 표시되지 않고 스토리 준비 중 상태로 보입니다.

재검토 조건

  • @storybook/angular-vite 가 stable 에서 벗어나 깨지는 경우 자체 워크벤치와 Vitest 조합으로 전환합니다. 스토리는 컴포넌트를 참조하는 얇은 파일이므로 전환 비용이 스토리 재작성에 한정됩니다.
  • Angular 메이저 업그레이드에서 Storybook 이 따라오지 못하는 경우도 같습니다. 업그레이드를 Storybook 에 묶어 미루지 않습니다.
  • 디자이너와 협업하거나 팀이 커지는 경우 애드온의 값이 올라갑니다. 본 결정이 그 방향에 유리합니다.

결과

  • 컴포넌트를 앱 화면 없이 격리해서 보고 두 모드를 동시에 비교할 수 있습니다.
  • HMR 이 있어 값을 바꾸고 바로 확인하는 반복이 빠릅니다.
  • zoneless 구성이 워크벤치 때문에 흐트러지지 않습니다.
  • 감수하는 것
    • preview 상태 도구를 기본값으로 둡니다. 이 아키텍처를 채용하는 쪽이 물려받는 부채입니다.
    • Vite 버전이 트리에 둘 존재합니다. 현재 문제를 일으키지 않지만 플러그인 동작이 갈릴 여지가 있습니다.
    • 서드파티 Angular 변환 플러그인에 간접 의존합니다.
© 2026 dev.goraebap