코드베이스 하나로 서비스 여러 개: 빌드 변수로 도메인별 설정 나누기
비슷한 서비스를 여러 개 운영할 때, 저장소를 복사해서 따로 관리하면 버그 수정 하나를 여러 번 해야 합니다. STARROAD는 K-POP, K-DRAMA, K-MOVIE 세 가지 타자 연습 사이트를 저장소 하나에서 만듭니다. 이 글은 그 방법을 정리합니다.
빌드할 때 도메인을 정한다
Vite는 VITE_로 시작하는 환경 변수를 빌드 시점에 코드에 넣어 줍니다. STARROAD는 VITE_APP_DOMAIN 하나로 어떤 사이트를 빌드할지 정합니다.
"build:kpop": "VITE_APP_DOMAIN=kpop tsc && vite build",
"build:kdrama": "VITE_APP_DOMAIN=kdrama tsc && vite build",
"build:kmovie": "VITE_APP_DOMAIN=kmovie tsc && vite build"
빌드 결과물에는 선택한 도메인의 설정만 들어가므로, 실행 중에 주소를 보고 분기하는 코드가 필요 없습니다.
달라지는 것을 한곳에 모은다
세 사이트의 차이는 domainConfig.ts의 설정 객체 하나에 모여 있습니다. 타입으로 모양을 정해 두었기 때문에, 새 도메인을 추가할 때 빠뜨린 항목이 있으면 컴파일 단계에서 알 수 있습니다.
- 브랜드: 서비스 이름, 대표 색
- SEO: canonical 주소, 제목, 설명, OG 이미지, 언어
- 문구: "가수 / 그룹"과 "드라마"처럼 분야마다 다른 화면 용어(한국어·영어)
- 디자인: 글꼴, 배경, 강조 색
- 데이터: 사용할 Firestore 컬렉션 이름
- 저장소 접두사: localStorage 키 앞에 붙는 값. 같은 브라우저에서 두 사이트를 써도 설정이 섞이지 않습니다.
화면 코드는 "가수를 선택해 주세요" 같은 문장을 직접 쓰지 않고 설정에서 가져옵니다. 그래서 같은 컴포넌트가 K-DRAMA에서는 "드라마를 선택해 주세요"를 보여 줍니다.
배포는 사이트별로
Firebase 프로젝트 하나에 Hosting 사이트를 여러 개 만들 수 있습니다. 각 사이트는 자기 기본 주소(*.web.app)와 연결된 도메인을 가집니다. STARROAD는 도메인별 배포 스크립트가 해당 사이트를 고른 뒤, 그 도메인으로 빌드하고 Hosting만 배포합니다. 결과적으로 kpop.kstarroad.com과 kdrama.kstarroad.com은 같은 코드에서 나온 서로 다른 빌드입니다.
주의할 점
- 빌드를 바꿔 배포하는 실수: K-POP 빌드를 K-DRAMA 사이트에 올리는 사고를 막으려면, 빌드와 배포를 한 명령으로 묶어 두는 것이 좋습니다.
- 사이트별 정적 파일: robots.txt와 sitemap.xml은 도메인마다 달라야 합니다. 공용 public 폴더에 하나만 두면 모든 도메인이 같은 sitemap을 가리키게 됩니다. 빌드할 때 도메인에 맞게 생성하세요. 관련 문제는 catch-all rewrite 글에서 다뤘습니다.
- 공유 데이터베이스: 같은 Firebase 프로젝트를 쓰면 Firestore 보안 규칙도 하나입니다. 컬렉션 이름을 도메인별로 나누면 규칙을 쓰기 쉬워집니다.
언제 이 방식이 맞을까
화면 구조와 기능이 거의 같고 콘텐츠와 문구만 다르다면 이 방식이 잘 맞습니다. 기능이 크게 달라지기 시작하면 설정 객체에 조건 분기가 늘어나는데, 그때가 저장소를 나누거나 공용 패키지를 분리할 시점입니다.