Logan.

2026-05-15

Figma to Storybook 자동 변환 파이프라인 SECTION 분할과 시각 회귀 루프

Figma URL에서 .stories.tsx까지 — REST API, 휴리스틱 매핑, SECTION을 케이스 스토리로 쪼개기, 시각 회귀 보정 루프 전체.

by Logan·9분 읽기·part 4 of 본격 Storybook 도입·#storybook #figma #automation

안녕하세요, 로건입니다 👋

디자이너가 Figma URL을 던져주면 컴포넌트 스토리가 자동으로 생기는 — 그런 꿈을 한 번쯤 꾸지 않은 프론트는 없을 거예요. 저도 처음엔 REST API로 노드 트리만 잘 파싱하면 끝날 줄 알았습니다.

그런데 첫 자동 생성 결과를 본 순간, 197줄짜리 깨진 JSX와 마주했죠. 그날부터 알게 됐어요. 자동 변환은 출발선일 뿐이고, 본작업은 따로 있다는 걸. 이 글은 SECTION을 케이스 스토리로 쪼개고, 픽셀이 맞아 떨어질 때까지 7번씩 다시 그리던 시간에 대한 이야기입니다.

파이프라인의 큰 그림

먼저 전체 흐름을 한눈에 보고 시작할게요.

각 단계를 풀어볼게요.

휴리스틱 매핑이 시작점이다

자동 생성기의 첫 일은 figma에 그려진 이름들을 우리 디자인 시스템 컴포넌트로 매핑하는 것입니다. 휴리스틱 한 줄 한 줄이 변환 품질을 결정해요.

Figma에서 본 이름매핑 대상비고
Top Navigation<TopNavigation>정확한 PascalCase 매핑
switch (lowercase)<ToggleSwitch>통상명 → 사내명
Status Bar(삭제)OS가 그리는 영역
icon_01, icon_02(삭제 or <Icon name="" />)annotation node
그리드, restricted area(삭제)figma annotation
INSTANCE 노드 (Button/Primary/MD)<Button tone="primary" size="md">variant 자동 추출

여기서 깨달은 게 하나 있어요. figma는 자유로운 캔버스라, 디자이너마다 노드 이름 규칙이 조금씩 달라요. 우리 팀은 디자이너와 합의해서 INSTANCE의 variant 이름을 props 이름과 1:1로 맞추기로 약속했어요. 그 약속 한 줄이 휴리스틱 정확도를 80%에서 95%로 올렸습니다.

SECTION을 케이스로 쪼개기

이게 처음에 가장 헷갈렸던 부분이에요. figma에는 SECTION이라는 컨테이너 노드가 있어서, 디자이너가 한 화면의 여러 케이스를 묶어 그릴 때 자주 사용합니다. 예를 들면 알림 설정 화면의 "권한 허용 / 권한 거부 / 권한 미정" 같은 상태들을 한 SECTION 안에 나란히 그려요.

자동 변환기는 이걸 어떻게 처리해야 할까요?

답은 각 FRAME을 별도 스토리로 분리하는 것이었어요. 결과적으로 한 figma SECTION이 N개 케이스 스토리가 됩니다.

// NotificationSettings.stories.tsx
export const PermissionGranted: Story = { args: { permission: "granted" } };
export const PermissionDenied: Story = { args: { permission: "denied" } };
export const PermissionUndetermined: Story = {
  args: { permission: "undetermined" },
};

그리고 케이스들이 공유하는 layout/data는 별도 디렉토리에 추출했어요.

src/stories/screens/NotificationSettings/
├── NotificationSettings.stories.tsx
└── _shared/
    ├── Layout.tsx        // ScreenLayout wrapper
    ├── data.ts           // fixture-free dummy data
    └── components.tsx    // 화면 안 sub-block

_shared/ 디렉토리 패턴이 케이스 5개 이상 되는 화면에서 코드 중복을 깔끔하게 제거해줬어요.

첫 자동 생성 결과는 거의 항상 깨진다

이게 가장 솔직한 진실이에요. 자동 변환기에 figma URL을 넣어서 나온 첫 결과는 거의 모두 한두 곳이 깨져 있습니다. 흔한 깨짐은 이런 것들이에요.

증상원인
카드 우측이 잘림device frame (390) ≠ figma frame (360)
아이콘 색이 안 먹음SVG loader가 color prop을 무시
trailing gap이 남음flex-wrap + gap RN-Web 버그
<View> 안 children이 stretch됨width/height가 잘못 주입됨
폰트가 OS 기본으로 fallbacktokens.typography 매핑 누락

여기서 핵심은 — 이 깨짐들을 한 번 잡아두면 다음 변환에도 안 깨진다는 거예요. 그래서 자동 변환기 작업은 변환 자체가 아니라 깨짐 사례를 휴리스틱에 흡수시키는 것이 본작업이 됩니다.

시각 회귀 루프 — 3~7번 다시 그린다

자동 변환을 한 번 돌리고 끝나는 화면은 거의 없어요. 보통 이런 루프를 돕니다.

Figma 원본과 Storybook 렌더의 side-by-side 비교

처음엔 "7번이나 돌면 자동이 아니잖아요?"라고 생각했어요. 그런데 한 화면을 손으로 처음부터 짜려면 보통 반나절이 들어요. 자동 + 7번 보정은 한 시간 안쪽이고요. 그리고 보정 한 번 한 변환 룰은 영구히 휴리스틱에 흡수되니까, 변환할수록 빨라집니다. 100번째 화면쯤 되면 첫 결과의 정확도가 95% 가까이 올라옵니다.

Storybook과 Figma를 함께 보기

각 스토리에는 figma 원본 URL을 메타데이터로 박아둡니다.

parameters: {
  design: {
    type: "figma",
    url: "https://www.figma.com/design/<FILE_KEY>/?node-id=<NODE_ID>",
  },
}

Storybook의 Designs 탭에서 옆에 figma 원본이 함께 떠요. 디자이너가 합격 검수할 때 두 화면을 같은 창에서 비교할 수 있게 되는 거죠. 작은 디테일이지만 합격 검수 시간을 절반으로 줄여준 한 줄이었습니다.

자동의 환상과 본작업

요약하면 이래요. 자동 변환은 본작업을 시작하게 해주는 도구이지, 본작업을 대체해주는 도구가 아닙니다. 본작업은 두 가지예요.

  1. 휴리스틱 보정: 첫 결과의 깨짐을 룰로 흡수시키기
  2. 케이스 설계: SECTION을 어떻게 N개 스토리로 쪼갤지 결정하기

자동이 해주는 건 그 본작업의 시간을 절반으로 줄여주는 것이에요. 그래서 자동화에 환상을 안 갖되, 자동화의 ROI는 명확하게 인정하는 게 — 그게 검증 단계에서 손에 남은 한 줄 정도의 결론입니다.

다음 편에서는 이 변환 작업을 하면서 마주친 함정 여섯 개에 대해 풀게요. 그 중에는 "사용자가 분노한 오후"도 있어요. 디자이너의 표정이 굳었던 그 순간에 대해서요.

related — in series · 본격 Storybook 도입