소비관리 서비스 탄생기 - 13. RN 세팅

Seoyong Lee·2022년 11월 29일
0

프로젝트

목록 보기
13/16
post-thumbnail

지난 시간까지는 기획과 디자인을 발전시켰다면 이제 개발로 돌아와 리액트 네이티브로 실제 작업을 진행하기 위한 준비 과정을 진행해보려 한다.

리액트 네이티브 초고속 세팅하기

1. RN + TS 템플릿

먼저 React Native에 타입스크립트가 적용된 기본 템플릿을 내려받는다.

npx react-native init spoon --template react-native-template-typescript

주의점
필요한 설정들도 함께 완료되어야 마지막까지 에러가 발생하지 않는다. 예를 들어 다음과 같이 루비가 아예 없거나 버전이 맞지 않으면 에러가 발생한다.

error Your Ruby version is 2.6.10, but your Gemfile specified 2.7.5

업데이트는 다음과 같이 rvm을 이용해 진행할 수 있다.

 rvm install 2.7.5
 rvm use 2.7.5

안드로이드 스튜디오와 Xcode 또한 미리 설치해야 한다. 안드로이드 스튜디오는 추가로 JDK 다운로드 및 환경변수 설정이 필요하다.
React Native adb reverse ENOENT

export PATH=/Users/<your_computer_name>/Library/Android/sdk/platform-tools:$PATH
export ANDROID_HOME="/Users/<yourcomputername>/Library/Android/sdk"
export PATH=$ANDROID_HOME/emulator:$PATH
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$ANDROID_HOME/tools/bin:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH

yarn start에 성공하면 메트로가 실행되는 것을 볼 수 있다.

2. ios, android 가상 기기 실행

yarn start로 메트로 서버를 실행시킨 상태에서 각각 yarn ios, yarn android를 통해 가상 기기를 실행시킬 수 있다. 보통 한 번에 실행되는 경우는 없으며 각 환경마다 세팅이 필요하다.

주요 발생 문제들

  • ios 빌드에 실패하는 경우: 최초 한번은 cd ios && pod install && cd 를 통해 업데이트해 주어야 한다. 또한 Xcode로 레포의 ios 폴더를 열어 signing의 Team도 설정해야 한다.
  • ios flipper 관련 에러: 이 방법으로 관련 코드를 직접 주석 처리한다.
  • android 가상 기기 연결 실패: 보통 에뮬레이터 실행에 실패하는 경우 터미널에 위에서 설명한 환경변수 설정이 되어있지 않거나 구글 플레이 라이센스 문제일 수 있다. 참고

3. eslint 추가

다음 명령어를 통해 eslint를 추가한다.

npm init @eslint/config

4. 절대경로 설정을 위한 module resolver 추가

다음 과정을 통해 절대경로로 import 할 수 있다.

  • babel-plugin-module-resolver 추가
    yarn add --dev babel-plugin-module-resolver

  • babel config 수정

    module.exports = {
      presets: ['module:metro-react-native-babel-preset'],
      plugins: [
        [
          'module-resolver',
          {
            root: ['./src'],
            extensions: ['.ts', '.tsx', '.jsx', '.js', '.json'],
            alias: {
              '@': './src/',
            },
          },
        ],
      ],
    };
  • tsconfig 수정

    {
      "extends": "@tsconfig/react-native/tsconfig.json",
      "compilerOptions": {
        "baseUrl": "./",
        "paths": {
          "@/*": ["src/*"]
        }
      },
      "include": ["src/**/*"],
      "typeRoots": ["src/types"]
    }
    

주의점
eslint 관련 설정을 추가해 주어야 에러가 발생하지 않는다.

yarn add -D eslint-plugin-import
yarn add -D eslint-import-resolver-babel-module

eslintrc
'babel-module': {} // 추가

참고 - How to Setup Path Alias in a React Native TypeScript App

5. react navigation 추가

네비게이션 구현을 위해 @react-navigation, @react-navigation/native-stack 등을 추가한다. 그 뒤 APP에 라우트 구조를 추가한다.

import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        screenOptions={{
          headerShown: false,
        }}
        initialRouteName="Home">
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Login" component={Login} />
      </Stack.Navigator>
    </NavigationContainer>
  )
}

6. 상태관리 추가

recoil이나 redux 등을 추가한 후 관련 세팅을 진행한다. 여기선 recoil을 사용할 예정이다.

yarn add recoil

그 뒤 최상단에 RecoilRoot를 추가한다.

import React from 'react';
import {RecoilRoot} from 'recoil';

import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <RecoilRoot>
      <NavigationContainer>
        <Stack.Navigator
          screenOptions={{
            headerShown: false,
          }}
          initialRouteName="Home">
          <Stack.Screen name="Home" component={Home} />
          <Stack.Screen name="Login" component={Login} />
        </Stack.Navigator>
      </NavigationContainer>
	</RecoilRoot>
  )
}

폴더구조

이제 모든 세팅이 완료되었다. 다음으로 폴더구조를 설정해보자.

├── App.tsx // 최상단
├── src
|  ├── assets
|  |  └── imgs
|  ├── features
|  |  ├── login
|  |  |  ├── components
|  |  |  ├── hooks
|  |  |  └── utils
|  |  └── ...
|  ├── recoil
|  ├── types
|  └── screens
|     ├── Home.tsx
|     └── Login.tsx
├── package.json
├── tsconfig.json
└── yarn.lock

개인적으로 선호하는 방식은 다음과 같이 스크린을 제외하면 페이지나 컴포넌트 등을 따로 분리하지 않고 구현하려는 feature 안에서 구분하는 방법이다. 이렇게 진행하면 나중에 page 등이 비대해져서 찾지 못하는 사태를 방지할 수 있고 feature 별로 구분해서 협업하면 conflict 방지에도 유리하다. 그러나 비슷한 컴포넌트가 각각 다른 feature에 중복으로 작성될 가능성이 생기므로 주기적으로 확인하여 합쳐주는 작업을 진행해야 한다. 이렇게 합쳐진 공통 컴포넌트는 보통 상단에 shared 폴더에 모아두고 추후 storybook으로 관리하기 편하도록 데이터와 UI를 분리하여 view 부분만 재사용 하게 된다.

작업 진행

이제 디자인을 토대로 각 기능을 구현하면 된다. 그러나 하나의 기능을 100% 완성하고 다음으로 넘어가면 그사이에 완성된 기능에서 변경 사항이 생길 수 있다. 최대한 이러한 재작업을 방지하기 위해 일단 뼈대가 되는 컴포넌트들을 구성하고 디자인 디테일은 최대한 나중에 구현하는 방식으로 진행하였다.

0개의 댓글