브라우저 안에서 에디터를 만든다는 것: WYSIWYG 구현의 현실

브라우저 안에서 에디터를 만든다는 것: WYSIWYG 구현의 현실

Quill 라운드트립 파이프라인부터 LUT 기반 색상 편집기까지—'보이는 대로 저장된다'는 약속이 얼마나 비싼지 아는 사람만 이해하는 이야기

WYSIWYG 에디터 Quill 라운드트립 변환 VS Code 웹뷰 Mapbox LUT 에디터 UI 설계 Markdown 변환 브라우저 에디터
광고

"WYSIWYG 에디터 만들면 되지 않나요?" 기획자가 이 말을 꺼내는 순간, 프론트엔드 개발자의 머릿속에서는 이미 비상벨이 울립니다. Figma 시안에서는 그냥 텍스트 박스 하나인데, 실제로 구현하면 그 뒤에 파이프라인이 다섯 단계가 붙어 있거든요. 최근 dev.to에 올라온 두 편의 글이 이 감각을 다시 한번 확인시켜줬습니다—VS Code 웹뷰 안에 WYSIWYG 마크다운 에디터를 구현한 사례, 그리고 Mapbox 색상 테마를 실시간으로 편집하는 브라우저 기반 GUI 툴. 겉보기엔 다른 문제처럼 보이지만, 핵심 고통은 같습니다. '사용자가 보는 것'과 '실제로 저장되는 것' 사이의 갭을 누가 메울 것인가.

라운드트립의 저주: Markdown → HTML → Delta → HTML → Markdown

SPECLAN이라는 VS Code 확장을 만든 개발자는 솔직하게 고백합니다. 전체 개발 공수의 40%가 WYSIWYG 에디터 하나에 들어갔다고. 스택을 보면 왜 그런지 바로 보입니다. Quill 2.x로 리치 텍스트 편집을 받고, remark로 Markdown을 HTML로 변환하고, turndown으로 다시 Markdown으로 돌려보내는 구조입니다. 여기에 YAML 프론트매터 파싱을 위한 gray-matter, Quill이 기본 지원하지 않는 테이블을 위한 quill-table-up까지.

문제는 이 파이프라인이 본질적으로 손실적(lossy)이라는 점입니다. Markdown → HTML → Quill Delta → HTML → Markdown 매 단계를 거칠 때마다 링크, 강조, 중첩 리스트가 조금씩 어긋납니다. 작성자는 커스텀 turndown 규칙을 직접 작성하는 데 몇 주를 썼다고 합니다. 여기서 나오는 결론이 날카롭습니다. "저장 파이프라인부터 먼저 만들어라. 라운드트립이 제약이고, 제약이 설계를 결정한다." 에디터 UI가 아니라 데이터 흐름이 설계의 출발점이어야 한다는 뜻입니다. Figma에서 먼저 화면 그리고 나중에 API 맞추다가 망한 경험 있는 분들 공감하실 겁니다.

프론트매터는 보이지 않지만, 없으면 파일 자체가 의미 없다

이 프로젝트에서 또 하나 날카로운 지점은 YAML 프론트매터 처리입니다. 각 스펙 파일에는 상태, 엔티티 ID, 부모 참조, 타임스탬프 등 10개 이상의 필드가 있는데, 에디터는 Markdown 본문만 보여줍니다. 사용자가 본문에서 타이틀을 수정하면 YAML의 title 필드와 충돌이 생길 수 있습니다. 이게 사실 설계에서 가장 까다로운 부분입니다—사용자가 건드릴 수 없는 메타데이터와 편집 가능한 콘텐츠를 어떻게 깔끔하게 분리하느냐. UI 레이어에서 숨긴다고 문제가 사라지는 게 아니라, 오히려 더 조심해야 하는 영역이 됩니다.

VS Code 웹뷰의 현실: postMessage로 모든 걸 연결해야 한다

웹뷰 개발을 안 해본 분들은 모르는 고통이 있습니다. 에디터(iframe)와 익스텐션 호스트 사이의 모든 통신이 postMessage 입니다. 로드, 저장, 더티 상태, 언두, 외부 파일 변경 감지까지 전부요. 작성자는 타입드 핸들러를 양쪽에 두는 구조화된 메시지 프로토콜을 직접 구축했습니다. 거기에 CustomTextEditorProvider를 쓰면 VS Code의 TextDocument와 Quill의 Delta를 동기화해야 하는데, Git 작업으로 파일이 외부에서 바뀌는 순간 이벤트 시퀀싱이 꼬입니다. 웹뷰 안의 console.log는 어디서도 안 보이니 별도 로깅 브릿지까지 만들었다고 합니다. 이거 실제로 겪어보면 진짜 눈물 납니다.

색상 편집기의 다른 버전: LUT와 실시간 지도

Mapbox 쪽 사례는 결이 다르지만 같은 철학에서 출발합니다. 지도 색상 테마를 커스터마이징하기 위해 LUT(Lookup Table)를 사용하는데, 기존 워크플로우가 문제였습니다. 브라우저 LUT 편집기에서 조정 → PNG 익스포트 → 터미널에서 base64 인코딩 → 플레이그라운드에 붙여넣기 → 결과 확인 → 처음으로 돌아가기. 색감이라는 감각적이고 직관적인 작업에 이 정도 마찰이 있으면 창의적 흐름이 완전히 끊깁니다.

해결책은 단순했습니다. LUT 편집기와 지도를 같은 창에 넣자. Mapbox GL Theme Editor는 싱글 페이지 앱으로 슬라이더를 드래그하는 순간 LUT 프리뷰와 실제 지도가 동시에 업데이트됩니다. 색조 회전, 채도, 밝기, 대비, 색온도 글로벌 컨트롤에 더해 특정 색상을 아이드로퍼로 찍어 개별적으로 리맵핑하는 타깃 색상 보정 기능까지. 결과물은 PNG로 저장하거나 Base64로 바로 복사할 수 있습니다. UI 설계의 본질, 즉 사용자의 멘탈 모델과 실제 데이터 흐름 사이의 마찰을 줄이는 것을 잘 보여주는 사례입니다.

시사점: '보이는 것'과 '저장되는 것' 사이를 설계하는 것이 진짜 일

두 사례에서 공통으로 보이는 패턴이 있습니다. 에디터 UI는 사실 빙산의 일각이고, 진짜 복잡성은 변환 파이프라인, 상태 동기화, 데이터 무결성 보장에 있다는 것. WYSIWYG라는 단어가 주는 환상—'보이는 대로 저장된다'—은 구현 레벨에서 절대 공짜가 아닙니다. Quill이 테이블을 기본 지원 안 한다는 것, 웹뷰 통신이 전부 postMessage라는 것, LUT 파일 하나를 지도에 반영하는 데 6단계 수작업이 필요하다는 것—이 간극들을 메우는 게 프론트엔드 개발자의 일이고, 그 간극은 Figma 시안에는 절대 나와 있지 않습니다.

전망: 에디터는 점점 더 도메인 특화로 간다

범용 에디터(Notion, TipTap 기반 툴)가 성숙해질수록, 반대로 특정 도메인에 최적화된 에디터의 가치가 올라갑니다. 스펙 관리를 위한 Markdown 에디터, 지도 스타일링을 위한 색상 편집기, 애니메이션 타임라인 에디터, 코드 리뷰용 인라인 코멘트 에디터. 각각이 다른 데이터 모델, 다른 저장 포맷, 다른 협업 패턴을 가집니다. Container Queries나 @layer 같은 새로운 CSS 기능이 UI 레이어 복잡성을 줄여주고 있고, 웹뷰 API도 점점 성숙해지고 있지만, 결국 '이 에디터가 어떤 데이터를 만들어야 하는가'를 먼저 결정하는 것이 구현보다 중요합니다. 저장 파이프라인부터 설계하라는 SPECLAN 개발자의 조언은, 그래서 단순히 이 프로젝트만의 이야기가 아닙니다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요