concept/React, Redux, RN

웹 뷰 찍먹하기 (feat. expo CLI)

오연 : Oana 2025. 3. 10. 23:30

들어가기

  • 지난 해 12월, 솔로프리너 강연
    • 프로그래밍 좀비 350개의 개인 앱을 만들어 월급의 7배 수익을 달성한 방법 (일 100만원의 수익)
    • 왜 하필 앱이지?
      • 광고 수익
      • 구독 결제

웹뷰 란?

  • 프레임워크에 내장된 웹 브라우저 컴포넌트로 뷰(View)의 형태로 앱에 임베딩하는 것
    • App에서 웹브라우저를 이용해 화면을 보여주는 방식

웹뷰를 사용하는 이유?

  • 웹 기반으로 구동되는 모듈을 앱에서 사용해야 할 때, 앱 전용 모듈을 다시 개발하는 것은 시간적으로 오래 걸리고 비효율적

웹뷰의 단점

  • UX 측면에서 반응성이 약하기 때문에 페이지를 이동하거나 새로고침했을 때, 깜빡이는 현상과 앱 사용간의 부드러움이 조금 떨어짐, UI 가 제한적
  • Native API 를 직접 쓸 수 없어 기기와 직접적인 연동이 어렵다.
    • ex. 카메라 직접 접근, 생체 인증
  • 웹뷰만으로 구성된 앱은 스토어 심사가 어려울 수 있다.

웹뷰의 장점

  • 여러 플랫폼에서 개발이 가능 (웹, AOS, IOS)
  • 웹과 앱을 한번에 개발하기 때문에 개발 속도가 빠르고, 사용자에게 동일한 UX 제공이 가능
  • 배포가 쉽고 빠르다
    • 앱의 경우 수정사항이 있을 때, Native 배포 절차에 심사가 포함되어 시간이 오래 걸리고 까다로움
    • 웹뷰의 경우에는 바로 배포가 가능
  • 웹 → 리액트 네이티브
    • onMessage 프로퍼티: React Native의 WebView에서 웹페이지(JavaScript)로부터 메시지를 받을 때 사용
    • postMessage 메소드: 웹페이지에서 React Native의 WebView로 메시지를 보낼 때 사용

React Native CLI

  • Expo CLI 이전, 리액트 네이티브 팀과 커뮤니티가 제공한 툴
  • 기초적인 개발 설정을 제공하지만 추가 구성 설정 필요
  • 자바스크립트 코드와 네이티브 기기 소스 코드를 합쳐야 한다면 React Native CLI 가 적합

Expo CLI

  • 정리된 앱 개발 워크플로우로서 프로젝트 생성 및 코드 작성과 네이티브 기능 통합이 쉬움
  • React Native CLI 보다 훨씬 쉽고 간단하며 언제든 React Native CLI 로 전환 가능
  • EAS (Expo Application Services)
    • Expo 관리 장치에서 앱을 빌드하고 앱 스토어에 제출하는 프리미엄 서비스

프로젝트 설정하기

# Expo CLI 설치
sudo npm install -g expo-cli

# 원하는 프로젝트로 변경
cd { 원하는 프로젝트 경로 }

# Expo 프로젝트 생성
# 구버전: expo init { 프로젝트 명 }
npx create-expo-app --template {Example}
yarn create expo-app
npm create expo-app

리액트 네이티브 웹 뷰 추가하기

# WebView 라이브러리 설치
yarn add react-native-webview
import { WebView } from 'react-native-webview';

export default function App(){
	return (https://moxda.store>" }} />)
}

 

한계점

  • 노치에 가려지는 화면
  • 뒤로/앞으로 가기 불가
  • 스와이프 불가
  • 키보드가 화면을 다 잡아먹는데... 스크롤이 안 되는 현상

웹과 다른 앱 개발에서 필요한 개념

  • 네비게이션 (웹에는 라우터가 있지만 앱에는 네비게이션)
    • 화면 중첩과 보호
    • 조금 더 자세히 알아보면..
      • 웹은 앵커 태크 (<a></a>)
        • 웹은 URL이 브라우저 히스토리에 스택으로 푸시
      • 앱은 네비게이터 (Navigater)
        • 네비게이션은 정의한 화면을 렌더링하는 방법을 결정하는 리액트 컴포넌트
        • 앱이 화면을 전환하고 탐색 기록을 관리할 수 있는 방법
      • 차이점은 스택이 변경될 때 제스쳐와 애니메이션을 제공한다는 것
      네비게이션 구성 방법
      • 네비게이션 컨테이너
        • 탐색 트리를 관리하고 상태를 포함하는 루트 컴포넌트
        • 모든 네비게이터 구조는 여기에 래핑
      • 화면 구성을 정의하기 위한 스크린 컴포넌트를 자식으로 포함
      <NavigationContainer>
        <Stack.Navigator
          screenOptions={{
            headerShown: false,
          }}
          initialRouteName="Login">
          <Stack.Screen name="Login" component={Login} />
          <Stack.Screen name="Main" component={MainWebView} />
          <Stack.Screen name="SignUp" component={SignUpWebView} />
        </Stack.Navigator>
        Stack Drawer BottomTab
      </NavigationContainer>
      
    • 네비게이션이란?
  • 네이티브 기기와 통신
    • 권한 획득
  • 저장소 차이 (local storage, session storage vs async storage)
  • 푸시 알림
    • expo-notifications
  • 사진 촬영
  • 파일 업로드, 다운로드

앱 구현과 기본 설계는 어떻게..?

  • 모바일 웹과 앱에서의 컴포넌트를 어떻게 구분해서 제어할까?
    • 앱인지 (웹뷰인지) 여부를 판단해서 조건문으로 컴포넌트를 렌더링
    • 웹뷰인지 앱인지 여부를 판단하는 방법
      • userAgent 활용
      const isIos = window.navigator.userAgent.match('iPad') ||  window.navigator.userAgent.match('iPhone')
      
      • 스크린 넓이로 판단
  • 페이지 라우팅은 어떻게 제어할까?
  • 로그인 여부에 따라 다른 화면을 보여줄 수 있을까?
    • 쿠키, 로컬 스토리지에 저장된 유저 정보를 전송하고 네비게이션을 중첩
  • 유저 정보를 어떻게 저장해둘까?
 

@react-native-async-storage/async-storage

Asynchronous, persistent, key-value storage system for React Native.. Latest version: 2.1.2, last published: 10 days ago. Start using @react-native-async-storage/async-storage in your project by running `npm i @react-native-async-storage/async-storage`. Th

www.npmjs.com

 

 

배포 하기

eas build

정리

목표는 최소한의 개발, 최대한 빠른 릴리즈

  • 화면에 대한 설계
    • 각 화면의 연결을 어떻게 관리할 것인지 네비게이션 고려
    • 웹, 모바일 웹, 앱을 구분하는 함수를 만들고 웹과 앱이 통신하는 브릿지 작성
    • 유저의 사용성을 개선하기 위한 저장소 추가
    • 앱이 배포되기 위한 필요 최저한의 네이티브 개발
      • 푸시 알림

참고