웹/웹뷰 코드 합치면 개발 2배 빨라지는 거 아니었어요? | 2024 당근 테크 밋업
구현의 기초가 된 학습 자료
이전의 프로젝트에서는 어드민 페이지는 데스크톱을 위한 뷰만, 모바일 앱 또한 태블릿 사이즈를 지원하지 않아서 다양한 브라우저의 너비에 맞는 반응형 컴포넌트를 포함하지 않았다.
하지만 모바일 환경, 데스크톱 환경 더 나아가 웹뷰 환경까지 고려하여 컴포넌트를 작성하려고 하니, 어떤 방법이 있는지 학습 자료를 찾아보던 중 상단에 클립해놓은 2024 당근 테크밋업의 “웹/웹뷰 코드 합치면 개발 2배 빨라지는 거 아니었어요?”를 보고 유레카를 외치며 직접 적용해보기로 했다.
핵심적인 부분은 아래와 같았다.
풍물 커뮤니티 프로젝트에서는 TailwindCSS를 적용중이어서 md:, lg: 등의 미디어 쿼리로 화면 별로 컴포넌트의 너비, 높이, display, postion 등의 속성을 제어해서 처리해 줄 수 있었다.
1. 뷰 타입 정의 및 감지
먼저 브라우저 환경을 정확히 감지하기 위한 타입 시스템을 구축했다.
import { useMediaQuery } from "react-responsive"; //mediaQuery 조건을 감지하기 위한 라이브러리
type ViewType = "webview" | "mobile" | "desktop";
// UserAgent 기반 웹뷰 감지
const getInitialView = (): ViewType => {
if (typeof window !== "undefined") {
const ua = navigator.userAgent.toLowerCase();
if (ua.includes("react-native") || ua.includes("wv") || ua.includes("webview")) {
return "webview";
}
}
return "desktop";
};
// 미디어 쿼리 기반 반응형 감지
export function useView(): ViewType {
const initial = useViewStore((state) => state.view);
const isMobile = useMediaQuery({ query: "(max-width: 768px)" });
if (initial === "webview") return "webview";
if (isMobile) return "mobile";
return "desktop";
}
2. ts-pattern을 활용한 타입 안전한 분기 처리
CSS로 해결할 수 없는 구조적 차이가 있는 컴포넌트들은 ts-pattern의 match 함수를 사용해 타입 안전하게 분기 처리했다.