오늘 배운 것

어제 있었던 이슈는 특수 상황이기도 했지만, 프론트 멘토님의 조언을 참고하면 두 가지의 해결 방안이 있는 것으로 보였다.

1. 프로덕션과 개발 DB를 같이 쓰기

2. 개발환경 앱 빌드와 프로덕션 앱 빌드 환경을 분리하기

 

사실 2번의 의미를 정확히는 이해하지 못했다. 빌드 환경을 분리한다는 것은 어떤 의미일까? 아예 다른 환경에서 앱이 실행되는 거라면, 그렇다면 개발 환경에서 사용되는 자원(AsyncStorage 등)과 프로덕션 환경에서의 자원이 분리되는 의미라고 이해했다.

 

이 경우 프로덕션 앱 빌드를 하다가 개발 앱 빌드를 하더라도 둘이 자원을 공유하지 않으니 기존 환경에서의 AsyncStorage에 기존 토큰이 남아있을 리 없다. 

 

사실 1번의 방법도 가능은 하지만, 그래도 원칙상 DB를 서로 분리해두고 싶었다. 그래야 사용자 데이터와 개발하면서 쌓은 데이터를 서로 분리할 수 있을 것 같았다. 

 

여튼 이 문제는 급한 문제가 아니기도 하면서, 여러 가지 해결 방법을 써볼 수 있을 것 같았다. 그래서 일단은 잠시 보류하고 원래 작업하던 사용자 문의 폼을 적용하는 이슈로 돌아와 보자. 


첫 번째 문제는 '구글 폼'이라는 글자를 눌렀는데 구글 폼이 안 열리는 문제였다. 이 문제는 알고보니 RN의 Text 컴포넌트를 누르고 싶다면 onClick이 아니라 onPress 속성을 사용했어야 했다. 즉 속성명을 잘못 사용해서 발생한 문제였다. 

잘 뜬다!

 

두 번째는 문의하기를 누르면 헤더에 'settingsContactView'라는 jsx 파일의 이름이 그대로 뜨는 문제였다. 이 부분은 tabs와 관련이 있을 것 같았다. 

 

'expo router stack.screen' 이라고 검색했더니 나온 공식문서를 참고해봤다. 우리 프론트 프젝에서는 라우팅 라이브러리로 'expo-router'를 사용하기 때문이다. 

 

암튼 그랬더니 <Stack.Screen /> 이라는 컴포넌트 안에 options 이라는 속성값으로 'title' 값을 지정해주면 된다고 나와있었다. expo-router에서는 Stack이라는 컴포넌트를 기준으로 앱에서 navigation을 진행한다. 구현되어 있는 걸 보진 않았지만, 실제 스택처럼 라우팅 기록을 저장하고 필요 시 취소(롤백)하는 식으로 사용하는 것 같았다. 

 

아래와 같은 코드를 _layout.tsx 파일의 Stack 리스트 맨 밑의 원소로 추가해 주었다. 그랬더니 '문의' 화면으로 잘 바뀌었다.

<Stack.Screen
  name="settingsContactView"
  options={{
  headerTitle: '문의',
  headerTitleAlign: 'center',
  }}
/>

 

무사히 PR도 올렸다. 


이제는 다음 이슈인 다국어 지원을 할 차례이다. 

 

'react native 다국어 지원' 이라고만 검색했는데 굉장히 많은 포스트들이 나왔다. 그중 한 개를 클릭해서 보니, 다국어 지원에는 두 가지의 라이브러리가 필요한 것으로 보였다. 

 

첫 번째는 react-native-localize로, 현재 앱이 실행중인 국가의 코드를 얻어오는 라이브러리이다. 사용자의 현 위치에 따라서 자동으로 언어를 설정해 주려면 필요한 라이브러리이다. 두 번째는 i18next, i18next-react로 이것이 다국어 라이브러리라고 한다.

 

공식문서의 Getting Started 가이드와 심화 가이드를 보면서 진행해 보자. 우선 'npm install'을 통해 필요한 i18next, react-i18next 라이브러리를 설치하자. 

npm install react-i18next i18next react-native-localize --save

 

그 다음으로는 앱의 루트 파일에(공식문서에서는 App이 위치한 파일) i18을 초기화하는 코드를 작성해 주어야 했다. 우리는 기본으로 App 파일이 아니라 조금 다른 라우팅 시스템을 사용해서 폴더 구조가 조금은 다른데, 어쨌든 _layout.jsx 파일이 App.js의 역할을 하는 것은 맞다. (위의 이슈에서 Stack.Screen 컴포넌트를 추가한 파일이다.) 

 

해당 파일(_layout.jsx)에다가 다음과 같이 일단 예제 코드를 복붙해 주었다. 

import i18n from 'i18next';
import { getLocales } from 'react-native-localize';

i18n.use(initReactI18next).init({
  resources: {
    en: {
      translation: {
        'Welcome to React': 'Welcome to React and react-i18next',
      },
    },
  },
  lng: getLocales()[0].languageCode,
  fallbackLng: 'en',
  interpolation: {
    escapeValue: false,
  },
});

 

그리고 'resources' 속성 안에는 언어별로 dictionary 형태로 어떤 언어를 사용할지에 대한 정보가 들어가게 되는데, 공식문서에서는 이를 별도의 json 파일로 뺄 것을 추천하고 있었다. 그렇게 해야 코드가 복잡해지지 않을 것 같았다. 'fallbackLng'는 모종의 이유로 다국어 전환이 실패했을 때 어떤 언어를 보여줄지를 의미하는 것 같았다. 

 

그리고 react-native-localize에서 얻은 getLocales() 함수로 현재 접속한 위치에서 사용하는 기본 언어를 띄워서 lng(language) 파라미터 값으로 세팅해 준다. 

 

그리고 다시 실행을 하려는데, 웬걸 본적 없는 에러가 났다. 버전 미스매치 에러인데, 문제는 나는 저 라이브러리를 최근에 손댄 적이 없었다. 아마 직접적인 원인보다는 다른 이유로 난 에러 같았다.

 

에러 페이지깃허브 이슈를 돌아다니며 여러 명령어들을 시도해 보았다. 깃허브 이슈를 참고한 결과 이 이슈는 라이브러리 자체의 의존성 문제보다는 캐시로 인해서 뭔가 데이터가 꼬였을 가능성이 있었다. 

 

아래 명령어를 실행해 보고, 에뮬레이터에 있는 앱을 지웠다가 다시 빌드를 실행하니 그제서야 잘 되더라. 

rm -rf node_modules && npm cache clean --force && npm install && watchman watch-del-all && rm -rf $TMPDIR/haste-map-* && rm -rf $TMPDIR/metro-cache

 

+ Recent posts