본문 바로가기
프로그램개발/ClientSide(JavaScript,Angular,Vue)

React Native 아키텍쳐에 대한 이해

by 크레도스 2018. 6. 5.

출처 : https://github.com/nhnent/fe.javascript/wiki/April-9---April-13,-2018


Weekly Pick!

원문 : https://www.logicroom.co/react-native-architecture-explained/

React Native 아키텍쳐에 대한 이해

React Native는 자바스크립트가 네이티브 코드가 하는 방식과 동일하게 iOS와 안드로이드 휴대폰에서 동작할 수 있게 해주는 모던 프레임워크이다.

이런 동적이며 강력한 프레임워크는 어플리케이션 아키텍쳐를 통합하려는 조직에게 다양한 가능성을 제시하고 어플리케이션 개발에서 '한 번 개발하고 어디에나 배포한다'를 가능하게 한다.

그러나 많은 사람들이 이것이 어떻게 동작하는지는 잘 모른다. 여러분이 React Native 웹 사이트에서 테스트 프로젝트를 시작하려면 깊은 고민에 빠질 것이다. 휴대폰, 에뮬레이터, 자바스클비트 엔진, 브라우저 디버거 그리고 으악... 도대체 네이티브 코드는 어디서 돌아가는거야?

React Native로 앱을 만들기 시작한다면 다음 사항을 이해할 필요가 있다.

  1. 실행 아키텍쳐
  2. 빌드 아키텍쳐
  3. 디버깅 아키텍쳐

이 사항들을 한 번 알아보자!

보통 자바스크립트 웹 어플리케이션이 동작하는 방식

React Native 어플리케이션의 아키텍쳐를 처음 이해하기 위해서는 기초적인 것부터 시작해야 한다. 바로 모던 자바스크립트 어플리케이션이 어떻게 동작하는가이다.

자바스크립트가 원래 웹의 언어이기 때문에 단일 페이지 어플리케이션(Single Page Applications, SPA)이라고 말하는 동적 자바스크립트 어플리케이션이 브라우저에서 동작하는 것부터 살펴보기 시작하자.

SPA에서 브라우저는 두 가지를 로딩한다.

<html>
  <script src=/path/to/js/>
</html>

SPA는 마크업 언어(HTML)와 브라우저와 사용자가 상호작용할 수 있도록 하는 프로그래밍 언어(자바스크립트)를 사용하여 어플리케이션을 표현한다.

최종 결과물은 여러분이 기대하는 모든 것(입력 컨트롤, 동적인 동작, 유효성 검사 등)을 포함하는 렌더링된 웹 페이지이다.

img

잠시 뒤에는 React Native 빌드 과정이 이와 아주 비슷한 방식이라는 것을 알게 될 것이다. 다른 것은 브라우저가 자바스크립트와 HTML 마크업을 다운로드하는 대신 단말이 자바스크립트와 React Native 마크업을 로딩하는 것이다.

자바스크립트 실행 환경 아키텍쳐(Bridging)

React Native가 어떻게 동작하는가에 대한 다음 부분은 자바스크립트가 실제로 어떻게 실행되는지를 알아보는 것이다. 자바스크립트가 원래 휴대폰에서 동작되는 언어는 아니기 때문에 휴대폰 프로세서에서 동작하고 통신하기 위해서 브릿지(Bridging)라고 하는 기술을 써야 한다.

즉, 휴대폰은 '자바스크립트 코어'라고 하는 것을 실행해야 하고 이는 기본 '실행 환경'이다. 실행 환경은 운영체제가 자바스크립트를 실행할 수 있도록 하는 어떤 코드일 뿐이다. 자바스크립트를 실행할 수 있는 몇 가지 네이티브 코드를 로딩한 다음 자바스크립트 코드를 여기에 로딩한다(빌드 과정에서 휴대폰으로 전송된다 - 나중에 자세히 설명한다). 더 자세한 사항은 문서를 참고하자.

다음 다이어그램에서 휴대폰의 운영체제에 자바스크립트 실행 환경이 있다는 것을 알 수 있다. 이 환경 내부에서 React Native 자바스크립트 코드가 실행된다.

참고: 이 시점에서 질문을 할 수 있다. React Native는 자바스크립트인가? 아니면 네이티브 코드인가? 음... 실제로는 둘 다 이기도 하다. React Native 프로젝트는 빌드 과정에 작은 네이티브 프로젝트를 함께 포함한다.

React Native Architecture

위의 다이어그램은 우리가 고려해야 할 첫 부분에서 일어나는 일을 단순화 한 것이다. 아키텍쳐가 어떻게 돌아가는지 상위 단계에서 보여준다. 여기에서 React Native 앱의 강력함을 제공하기 위한 네이티브 코드와 React 코드가 모두 실행된다. React Native 앱은 앞서 언급한 '자바스크립트 코어' 혹은 '실행 환경'으로 자바스크립트를 로딩한다.

또 다이어그램은 하나의 (브리지 포인트라고 표현하는)파란색 선을 보여준다. 실제로는 휴대폰에서 자바스크립트 코드가 네이티브 컨트롤과 통신하기 위한 여러 개의 브릿지 포인트가 있다. 왜 그럴까?

자바스크립트가 네이티브 앱을 실행하기 위해서는 여전히 기본 네이티브 코드를 써야 하기 때문이다. 그리고 각 앱이 써야하는 네이티브 코드의 인스턴스는 하나 이상이다. 예를 들어 각 휴대폰에서 서로 다른 컨트롤들을 많이 사용하는 앱이 필요할 수도 있는 것처럼 말이다. 이는 자바스크립트 실행 환경에서 각 컨트롤들이 설정되고 브릿지를 통하여 통신히는 것으로 이루어진다.

실제로는 이렇게 구성된다.

React Native Architecture Deeper

각 React Native 컨트롤이 네이티브에 대응되는 컴포넌트와 통신하는 것을 볼 수 있다.

React Native가 자바스크립트로 작성된 컨트롤을 제공하기 때문에 자바스크립트로 개발하는 것이 '가능'하다. 하지만 휴대폰의 실제 네이티브 컴포넌트가 항상 뒷받침 되어야 한다. React Native는 양방향 통신이 가능하도록 브릿지를 제공한다.

네이티브 코드는 자체 스레드에서 동작하기 때문에 React Native 자바스크립트 코드가 오래 실행되더라도 UI가 멈추거나 느려지지는 않는다. 이는 이벤트를 사용하는 브릿지를 통해 호출되기 때문이다. 이것이 React Native 앱을 개발하는데 주의해야 하는 중요한 사항이다. 그러므로 자바스크립트 코드는 프로세스를 블로킹하지 않는다는 것을 유념하라.

React Native 빌드 과정 아키텍쳐

이제 React Native가 우리가 이해한 브릿지라는 것을 통해 통신한다는 것을 이해하였다. 그러면 이 모든 것들은 어떻게 설정되는 것일까?

보통의 자바스크립트 앱을 이해하는 것으로 다시 돌아갈 필요가 있다. React Native도 매우 비슷한 방식으로 동작한다. 휴대폰은 실제로 (SPA가 HTML 마크업 + 자바스크립트를 요청하는 것처럼 비슷한 방식으로 React 마크업과 자바스크립트의) 페이로드를 요청한다.

개발자가 첫 번째로 해야할 것은 커맨드를 사용하여 React Native 프로젝트를 빌드하는 것이다.

react-native run-ios

그 후 React Native는 다음 두 가지를 수행한다.

  1. 로컬 노드 웹 서버를 실행하고 모든 React Native 자바스크립트 코드를 포함하는 하나의 파일을 서비스한다. 이것은 단순한 마크업(HTML처럼 보이기도 하는)과 자바스크립트 로직이다. 이 파일은 index.platform.bundle 파일이다.
  2. 그리고 (iOS나 안드로이드를 위한)순수 네이티브 어플리케이션 프로젝트를 빌드하고 휴대폰으로 배포한다. 이 프로젝트는 자바스크립트 실행 환경을 포함하도록 설정되어 있다. 그런 다음 1번 단계에서 서비스되는 파일을 다운로드한다.

참고: iOS에서 이 실행 환경은 iOS 운영체제가 제공하지만 안드로이드에서는 React Native가 포함하고 있다. 이것의 진짜 이름은 '자바스크립트 코어'지만 여기서는 일반적인 용어로써 사용하기 때문에 불리는 것과는 반대로 동작한다는 것을 이해할 수 있을 것이다.

아래에 React Native 프로젝트의 스크린샷을 보자. 프로젝트에는 실제로 iOS와 안드로이드 프로젝트가 포함되어 있다. React Native가 서비스 파일들을 다운로드 하기 위해 사용하는 프로젝트들이다.

React Native Webstorm Screenshot

서비스되는 파일은 React Native 빌드 과정을 통하여 곧바로 (이미 살펴본)자바스크립트 실행 환경으로 전달된다. 이제 전체 React Native 어플리케이션을 실행하기 위해 필요한 네이티브 컨테이너와 자바스크립트 코드가 준비되었다.

아래 다이어그램은 두 가지 단계를 보여준다. 파일을 서비스하는 웹서버, 그리고 휴대폰으로 배포될 프로젝트.

React Native Bundle Diagram

이제는 React Native가 프로젝트를 어떻게 빌드하고 단말에서 실행하기 위한 환경을 구성하는가에 대한 올바른 이해가 필요하다.

진짜 단말을 사용하든 에뮬레이터를 사용하든 같은 방식으로 서비스되는 파일을 사용한다.

Hot Reloading

어플리케이션이 어떻게 빌드되고 배포되는지 알아보았다. 하지만 개발은 어떻게 하는 걸까?

React Native는 자바스크립트 코드를 내려받기만 한다. 자바스크립트는 컴파일되거나 전처리 빌드가 필요없다(그냥 스크립트 언어이다). 이는 React Native의 가장 큰 장점이다. (시간이 걸리는 느린)빌드가 시작된 이후부터는 React Native 앱을 새로 고침하는 것으로 간단하게 자바스크립트를 다시 로딩할 수 있다. 이를 위해 React Native는 휴대폰의 메뉴에서 '디버그 시간' 도구를 제공한다.

우리가 React Native 프로젝트를 아주 빠르게 바꾸고 수정할 수 있다는 의미이다.

다시 로딩할 수 있는 이 기능을 'Hot Reloading'이라고 부른다. 나중에 앱을 패키징하고 앱스토어에 배포할 때 'Code Push'라고 볼리는 기능을 사용하여 React Native 앱의 코드 수정사항을 배포할 수도 있다. 'hot-reload'할 수 있는 React Native의 장점이다. 이것은 전체 앱 스토어 릴리즈를 피할 수 있다는 의미이다.(그냥 서버에 스크립트를 업데이트 하면 된다).

디버깅 아키텍쳐

처음 React Native를 공부할 때는 디버깅이 어떻게 돌아가는지 알지 못했다. 프로젝트가 어떻게 빌드되는지 설명해 주는 사람도 없었다. 단일 페이지 어플리케이션과 같은 방식으로 동작한다는 것도 불분명했다.

디버거를 실행하기 위해서는 두 가지가 필요하다.

  1. 소스 코드의 위치를 설정한다(가끔은 단말에서 수동으로 설정해야할 때도 있다).
  2. 디버거가 디버깅 정보를 전달할 수 있도록 브라우저를 연다.

React Native Debugging Screenshot위의 스크린샷에 많은 것들이 있지만 4가지 주요 사항을 보자.

  • 첫 번째로, 앱의 번들 파일은 localhost:8089/index.platform.bundle에서 서비스된다.
  • 두 번째로, 디버거는 localhost:8089/debugger-ui에서 서비스된다.

이 두 가지는 React Native가 빌드된 환경에서 브라우저로 볼 수 있다.

  • 세 번째로, 프로세스는 (터미널에서) 빌드 과정 결과믈을 제공하기 위해 유지된다.
  • 네 번째로, 에뮬레이터나 단말에서 React Native 개발자 옵션을 열고 디버깅과 hot reloading 항목을 변경할 수 있다.

참고: React Native용 기본 포트는 8081이다. 하지만 포트가 충돌나서 8089로 바꾸었다. react-native-port-patcher를 사용하여 포트를 바꾸었다.

결론

이 글에서 살펴본 것은

  1. 실행 환경 아키텍쳐 - 그리고 브릿지가 자바스크립트 실행 엔진(core)를 통해 어떻게 네이티브 코드와 자바스크립트 코드를 연결하는가
  2. 빌드 아키텍쳐 - React Native가 노드 서버에서 번들이라고 불리는 서비스 파일을 만들어 내고 단말이 다운로드 하는 것, 이것이 SPA와 유사하게 동작한다는 것
  3. 디버깅 아키텍쳐 - React Native가 또한 (노드 서버에서 서비스되는) 디버깅할 수 있는 웹페이지를 제공하고 구글 크롬에서 디버깅할 수 있는 것

어떻게 동작하는지 어떻게 빌드되는지에 대한 이해없이 무언가를 만들기 시작한다는 것은 어려운 일이다. React Native 앱을 만들 때 일반적인 네이티브 코드가 실제로 어떻게 자바스크립트와 통신하는지 이해할 수 있어야 한다.

이것을 아는 것은 앱을 더 간결하게 만들수 있게 하고 여러분이 이 훌륭한 프레임워크를 사용할 때 자신감을 갖게 해줄 것이다. 이 글이 도움이 되었길 바란다.