bible-viewer
개역한글·개역개정을 나란히 놓고 읽는 성경 뷰어
개인기획 · 개발 · 배포 단독2026.01 — 현재
ReactTypeScriptViteTailwindFirebase
왜 만들었나
개역한글과 개역개정을 같이 펴놓고 대조하는 일이 잦은데, 기존 앱들은 번역본 전환이 탭 이동이었다. 동시에 보려면 창을 두 개 띄워야 했다. 두 본문을 같은 절 기준으로 나란히 놓는 뷰어가 필요했다.
내가 한 역할
기획부터 배포까지 단독. 본문 데이터 파이프라인 설계, 검색 인덱싱, 칼럼 레이아웃, Firestore 동기화까지 전부.
배운 점
30MB 짜리 성경 본문 JSON 을 resolveJsonModule 로 import 하면 tsc 가 heap OOM 으로 죽는다.
타입 체커가 JSON 리터럴 전체를 타입으로 펼치기 때문이다. ?url 로 경로만 받아 런타임에 fetch 하는 쪽으로 바꿨다.
번역본을 정적 JSON 으로 둘지 Firestore 에 넣을지도 오래 고민했다. 본문은 불변이고 용량이 크니 정적 JSON, 사용자별 상태(북마크·읽은 위치)만 Firestore 로 갈랐다. Firestore 의 last-write-wins 특성 때문에 삭제를 tombstone 으로 처리하지 않으면 다른 기기의 오래된 쓰기가 삭제를 되살린다는 것도 이때 알았다.
기술적으로 재밌었던 것
칼럼 순서 변경을 dnd-kit 없이 Pointer Events 만으로 구현했다.
행 기반 그리드라 “칼럼” 이 단일 DOM 노드가 아닌 게 문제였는데,
투명한 셀 뒤에 absolute 기둥 카드를 한 장 깔고 CSS 변수(--drag-x)를 조상에 직접 write 해서
매 pointermove 마다 리렌더가 0회 나도록 만들었다. 나머지 칼럼은 translateX(±pitch) 로 자리를 양보한다.
아이폰 홈스크린 아이콘 재배치와 같은 감각이 나온다.
아쉬운 점
브라우저 없이 통합 테스트를 돌리려고 Vite 의 ssrLoadModule 로 Node 에서 Firestore 로직을 실행했는데,
이 방식이 정직하긴 해도 실제 브라우저 환경의 IndexedDB persistence 는 여전히 커버하지 못한다.