개발 slecs

릴리즈 빌드에서 목 폴백을 완전히 제거한 방법

목차

release 빌드에 mock 폴백이 살아 있었다. 조용히, 아무도 모르게.


배경 — 왜 이게 문제였나

개발 편의를 위해 API 호출이 실패하거나 환경 설정이 빠진 경우에 mock 데이터를 내려주는 폴백 경로를 만들어두는 건 흔한 패턴이다. 로컬에서 백엔드 없이 UI 개발을 돌려야 할 때, 또는 CI 파이프라인에서 빠르게 빌드만 검증할 때 유용하다.

문제는 이 폴백 경로가 release 빌드에서도 살아있었다는 점이다. api_client.dart 쪽에 mock 데이터를 반환하는 분기가 있었고, main.dart / main_web.dart 에서 환경 초기화 시점에 해당 경로가 차단되지 않은 채로 배포되고 있었다.

실제로 서비스 중에 이게 트리거됐을 가능성이 있는지는 별개의 얘기지만, "릴리즈 빌드에서 mock이 살아있을 수 있다"는 구조 자체가 이미 위험 신호다. 혹시라도 실 사용자가 mock 데이터를 받아보는 상황이 생기면 그건 단순 버그가 아니라 신뢰 문제가 된다.


작업 내용 — 어디를 어떻게 막았나

변경된 파일은 세 곳이다.

파일 역할 이번 변경 포인트
app/lib/data/api_client.dart 실제 API 요청 처리, mock 폴백 분기 포함 release 빌드 플래그 확인 후 mock 경로 진입 차단
app/lib/main.dart 앱 엔트리포인트, 의존성 초기화 mock 관련 의존성 주입을 debug/profile 빌드 한정으로 제한
app/lib/main_web.dart 웹 타깃 엔트리포인트 동일한 가드 로직 적용 (모바일/웹 일관성 확보)

Flutter에서는 빌드 모드 분기를 아래처럼 처리한다.

// api_client.dart
import 'package:flutter/foundation.dart';

Future<Response> _request(String path) async {
  // release 빌드에서 mock 폴백 진입 자체를 차단
  if (kReleaseMode) {
    return _realRequest(path);
  }

  try {
    return await _realRequest(path);
  } catch (e) {
    // debug/profile 빌드에서만 mock 폴백 허용
    return _mockFallback(path);
  }
}

kReleaseMode는 컴파일 타임 상수라 트리 쉐이킹이 적용된다. 즉 release 빌드 바이너리에는 mock 관련 코드가 아예 포함되지 않게 된다. 단순히 "if 분기로 막는" 것과 "바이너리 자체에서 제거되는" 것 사이에는 꽤 큰 차이가 있다. 후자가 맞다.


회고 — 이런 게 왜 이렇게 자주 생기나

솔직히 팀 리딩하면서 이런 류의 이슈를 한 번 이상 본 적 없는 사람은 드물 거다. 패턴이 거의 정해져 있다.

  • 개발 초기에 "일단 mock 붙여서 빠르게 개발"
  • mock이 편하다 보니 폴백으로 두게 됨
  • "어차피 실패할 일 없으니 괜찮겠지"
  • 릴리즈 나감

여기서 팀장 입장에서 더 신경 쓰이는 건 코드리뷰에서 이걸 잡을 수 있었느냐는 질문이다. api_client.dart에 mock 분기가 있는 걸 리뷰 시점에 봤을 텐데, 그 시점에 "이거 release에서도 동작하나요?" 라는 질문을 던졌어야 했다. 그게 없었다면 리뷰 체크리스트에 빌드 모드 분기 확인 항목을 추가해야 한다는 뜻이다.

당장 팀에 공유한 체크포인트는 이 정도다.

  • mock / stub / fake 관련 코드가 들어가는 PR은 빌드 모드 가드 여부를 명시적으로 확인
  • kDebugMode / kReleaseMode / kProfileMode 셋의 차이를 팀 전체가 숙지 (특히 profile 빌드에서 mock이 동작해도 되는지 여부)
  • main_web.dart처럼 타깃별 엔트리포인트가 있는 경우 동일한 가드 로직이 모든 엔트리에 적용되었는지 확인 — 이번에 웹 쪽도 같이 잡은 게 잘한 부분

작은 fix처럼 보이지만 영향 범위는 작지 않다. release 빌드의 동작 신뢰성을 보장하는 일이기 때문이다. 이런 핀포인트 수정일수록 커밋 메시지와 PR 설명을 명확히 남겨두는 게 나중에 히스토리 추적할 때 훨씬 편하다는 것도 다시 한번 느꼈다.

다음은 mock 의존성 자체를 별도 패키지로 분리해서 release 빌드 pubspec에는 아예 포함되지 않는 구조까지 가져가는 걸 검토해볼 생각이다.


끝.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.