데우스랠리 / 2025.06 ~
데우스랠리 코드젠 아키텍처
참고 자료 · 데우스랠리 데모 영상 보기 ↗
TL;DR
데우스랠리 코드젠은 디자이너가 GUI에서 편집한 모션 데이터를 웹/iOS/Android 핸드오프 코드로 이어주는 작업이었어요.
핵심은 노드마다 흩어져 있는 편집 데이터를 코드젠 함수가 읽을 수 있는 구조로 다시 묶는 일이었어요. 데우스랠리의 원본 데이터는 각 노드가 자기 motion과 transition 정보를 들고 있는 형태였지만, 코드젠에는 루트 노드부터 이어지는 전체 타임라인 흐름이 필요했어요.
그래서 루트 노드를 기준으로 자식 관계를 순회하고, 각 노드의 motion value, easing, delay, duration을 코드젠용 타임라인 DST로 정규화했어요. DST는 AST처럼 코드젠 함수에 바로 넘길 수 있는 중간 구조예요. 이 변환 계층을 두면서 기존 코드컴포넌트 코드젠 자산을 데우스랠리 데이터 구조에서도 사용할 수 있게 확장했어요.
문제 정의 Problem
데우스랠리의 편집 데이터는 사용자가 조작한 노드 단위 상태에 가까웠어요. 각 노드는 자기 motion과 transition 정보를 들고 있었고, 에디터 입장에서는 그 구조가 자연스러웠어요.
하지만 코드젠에서 필요한 입력은 개별 노드 조각이 아니었어요. 실제 출력 코드는 루트 노드에서 시작해 자식 노드들이 어떤 순서와 관계로 움직이는지 알아야 했고, 각 노드의 값도 하나의 타임라인 흐름 안에서 해석되어야 했어요.
문제는 문자열을 어떻게 출력할지가 아니라, 편집 도구의 데이터 모델과 코드젠의 데이터 모델 사이를 어떻게 연결할지였어요. 노드 중심 편집 데이터를 그대로 밀어 넣으면 기존 코드젠 함수가 기대하는 입력과 맞지 않았고, 반대로 코드젠을 위해 에디터 데이터를 바꾸면 편집 경험 쪽 구조가 흔들릴 수 있었어요.
접근 방식 Approach
편집 데이터와 코드젠 입력을 억지로 하나로 합치지는 않았어요. 에디터는 노드 단위로 조작하기 좋은 구조를 유지하고, 코드젠 직전에 루트 기준 타임라인 DST로 변환하는 계층을 따로 두는 방향으로 잡았어요.
먼저 루트 노드에서 시작해 전체 자식 관계를 순회하고, 각 노드의 motion과 transition 정보를 수집했어요. 이 과정에서 랠리 타임라인 구성에 필요한 easing, motion value, default delay, default duration 같은 값을 코드젠 함수가 읽을 수 있는 형태로 정규화했어요.
단순 property 매핑으로 다룰 수 없는 값은 별도 규칙으로 분리했어요. zIndex가 대표적이었어요. zIndex는 자기 자신에게만 적용되는 값이 아니라 sibling 관계에 영향을 주는 값이라, 특정 시점에 zIndex를 가진 노드가 있다면 그 노드를 기준으로 sibling 간의 관계와 sibling들의 zIndex 값을 함께 계산해야 했어요.
핵심 결정 Decision
여기서는 노드별 편집 데이터를 루트 기준 타임라인 DST로 재구성하는 계층을 따로 뒀어요.
단일 노드 기준 코드젠이었다면 프리뷰에 들어가는 타임라인 데이터를 그대로 직렬화하는 단순한 구조도 가능했을 거예요. 하지만 데우스랠리는 전체 노드 관계를 포함한 코드젠이 필요했어요. 그래서 개별 노드의 데이터를 출력하는 방식보다, 루트에서 시작해 전체 흐름을 다시 만드는 쪽이 더 맞다고 판단했어요.
대신 변환 로직은 복잡해졌어요. 특히 zIndex처럼 sibling 관계까지 바꾸는 프로퍼티는 단순한 값 매핑으로 처리하기 어려웠어요. 그래도 편집 도구의 데이터 구조와 코드젠 함수의 입력 구조 사이에 책임이 분명한 계층을 뒀고, 기존 코드컴포넌트 코드젠 로직에 맞는 DST 입력을 만들었어요.
해결 결과 Result
기존 코드컴포넌트 코드젠 자산을 데우스랠리 데이터 구조에서도 쓰도록 확장했어요. 디자이너가 GUI에서 만든 노드별 모션 데이터를 웹/iOS/Android 핸드오프 코드 생성 흐름에 연결되는 DST로 정리했어요.
코드젠 함수가 기대하는 입력 구조와 편집 도구의 데이터 구조 사이에 명확한 변환 책임을 뒀어요. 덕분에 편집 도구 쪽은 노드 중심 구조를 유지하고, 코드젠 쪽은 전체 타임라인 흐름을 기준으로 동작하게 됐어요.
배운 점 Learning
이 작업을 하면서 코드젠에서 중요한 건 출력 문자열을 만드는 일만이 아니라는 걸 배웠어요. 출력 함수가 다룰 수 있는 중간 구조로 데이터를 정규화하는 일이 먼저였어요.
편집 도구의 데이터 모델과 코드젠의 데이터 모델은 목적이 달라서 완전히 같아지기 어려워요. 다음 계층이 이해할 수 있는 형태로 데이터를 넘기려면, 그 사이 변환 책임을 흐리지 않고 별도 구조로 두는 게 중요하다는 걸 체감했어요.
이 작업을 다시 한다면 Next
다음에 비슷한 코드젠 구조를 만든다면 DST 명세와 edge case의 동작 규칙을 더 먼저 정리하고 싶어요. 특히 zIndex처럼 sibling 관계까지 바꾸는 프로퍼티는 단순 property 매핑으로 다루기 어려워요.
구현을 먼저 시작하면 이런 규칙이 코드 안에서 흩어지기 쉬워서, 다음에는 변환 규칙을 문서나 테스트 형태로 먼저 잡아두고 시작하는 편이 더 안정적일 것 같아요.