어서와, 개발은 처음이지?

2.React Native 프로젝트 기본 구조, 디버깅 본문

React/React Native

2.React Native 프로젝트 기본 구조, 디버깅

오지고지리고알파고포켓몬고 2018. 7. 15. 02:27



지난 글에서 React Native 설치와, 기본 프로젝트 생성 및 가상 디바이스에서 실행하는 방법을 알아봤습니다.

그럼 본격적으로 디자인 작업에 들어가기 전에 지난번에 말씀드렸던 프로젝트 구조와 커맨드 창에 대한 간단한 설명, 디버깅에 대해 알아보겠습니다.


1. 커맨드 창


지난 글에서 react-native run-android 혹은 run-ios 명령을 통해 가상 디바이스에서 프로젝트를 실행해봤었죠?

이 명령어를 실행하면 새로운 커맨드 창이 등장하면서 뭔가 로딩되는 화면을 볼 수 있었는데요.

사실은 우리 프로젝트의 번들링 상황을 나타내는 것입니다.


react-native는 코드 변경시, 안드로이드/iOS 개발 환경처럼 새롭게 빌드를 할 필요 없이 변경사항이 자동으로 적용됩니다.

실질적으로 우리의 개발 환경이 서버가 되고, 프로젝트에서 수정된 코드를 즉각 기기로 반영합니다.

때문에 이 커맨드 창을 종료하면 디버그 서버가 종료되어 앱이 정상적으로 동작하지 않기도 합니다.

코드 수정 후 적용된 변경사항을 확인하려면,

가상 디바이스에서 안드로이드는 r + r(r키 두번), 아이폰에서는 cmd(ctrl) + r 키를 통해 새로고침(reload) 할 수 있습니다.


새로고침 시 위 화면처럼 업데이트된 번들(bundle)의 로딩이 보여지고, 만약 번들링 과정에서 문제가 생긴다면 아래처럼 에러에 관한 정보를 보여줍니다.

일종의 인터프리터의 역할도 한다고 볼 수 있죠?

실제 기기에서는 손에 쥐고 핫팩처럼 흔들면 하단에 개발자용 메뉴가 등장하는데, 이를 통해 새로고침 할 수 있습니다.

또한 변경사항 발생 시 스스로 새로고침하는 hot reloading이라는 기능도 존재합니다.

하지만 저는 개발환경에서 느려짐 현상과 약간의 버그가 발생할 수 있기 때문에 hot reloading을 자주 사용하지는 않습니다.



2. init 프로젝트의 구조

. ├── App.js ├── android/ ├── app.json ├── index.js ├── ios/ ├── node_modules/ ├── package.json └── yarn.lock

react-native init TestProject 명령으로 프로젝트를 생성하게 되면, 위와 같은 구조를 가지고 있는 것을 볼 수 있습니다.

하나씩 알아보겠습니다.


- 1. index.js


{$project_root}/index.js는 우리 프로젝트를 실행할 때 가장 먼저 실행되는 기점입니다.

index.js를 열어보면 App.js를 가져와서 컴포넌트로 등록하는 것을 볼 수 있습니다.

덕분에 우리가 프로젝트를 실행하면 App.js에 작성된 내용을 볼 수 있게됩니다.


그렇다면 화면의 개수가 늘어나면 어떻게 될까요?

화면 관리/이동은 navigation을 사용하여 쉽게 구현할 수 있고, 대표적으로 react-navigation과 react-native-navigation이 있습니다.

추후에 다시 다루겠지만, index.js를 navigation 사용법에 맞게 수정하면 됩니다.


- 2. App.js


react native에서는 View, Button, Text, ScrollView(사용 비권장 - 곧 제거될 예정입니다) 등 여러가지 기본 컴포넌트를 제공합니다.

이에 대한 내용은 이곳에서 확인할 수 있습니다.


1번에서 언급한 것처럼 실제 디바이스에 표시되는 코드는 App.js에 작성되어있고, App.js를 열어보면 View, Text 컴포넌트와 함께, 가상 디바이스에 떠있는 'Welcome to React Native!' 같은 낯익은 문자열을 볼 수 있습니다. 


< Welcome to React Native! >


그리고 App.js를 자세히 살펴보면 마치 프로그램 코드와 컴포넌트가 XML문서처럼 결합 되있는 것 같은 형상을 하고있는데요, 이를 JSX라고 부릅니다.


일단 App.js가 잘 실행되고 있는지 보기위해 Text 컴포넌트의 내용을 직접 수정해보고 새로고침(r + r 혹은 cmd + r) 해보시기 바랍니다.

성공적으로 수정되었다면, Platform과 StyleSheet 등 궁금한 것이 많지만, 글이 산으로 가는걸 막기 위해서 다음에 설명하도록 하고 다음 파일을 알아보겠습니다.


- 3. app.json


app.json에는 프로젝트의 이름과 앱의 이름이 작성 되어있습니다.

프로젝트 이름은 절대경로(TestProject/src/components/...) 접근에 사용할 수 있습니다.

아직 배포단계가 아니기 때문에 이 친구는 빠르게 넘어가겠습니다.


- 4. android/


안드로이드 네이티브 모듈을 담당하고 있는 부분입니다.

카카오톡으로 로그인하기처럼 react-native에서 지원하지 않는 기능들을 사용하기 위해서는 네이티브 모듈을 직접 구현해야 합니다.

혹은 이러한 것들을 누군가가 npm에 공개 모듈로 올려놓는데, 이를 사용하기 위해 dependency 등을 설정해야 할 수 있습니다.


주로 이러한 같은 경우에 이 폴더 안에 있는 소스를 수정하게 되겠습니다.


- 5. ios/


ios의 네이티브 모듈을 담당하고 있는 부분입니다.

4번과 동일한 역할을 수행합니다.


추후에 네이티브 모듈을 제작하고 값을 넣고 받아오는 부분도 포스팅 하겠습니다.


- 6. node_modules/


프로젝트와 관련된 모듈들입니다.

npm을 통해 설치한 모듈도 이곳에 위치하게 됩니다.


- 7. package.json


프로젝트와 관련된 모듈들이 기록된 파일입니다. 이를 통해 모듈들의 버전관리를 하게됩니다.


- 8. yarn.lock


7과 유사한 기능을 합니다.


3. 디버깅


react native는 기본적으로 크롬 브라우저를 통한 디버깅을 지원합니다.

가상 디바이스, 안드로이드에서 Ctrl (Command) + M, 아이폰에서 Ctrl (Command) + D를 누르면 개발자 메뉴가 나오는데, 여기서 Debug JS Remotely를 누르면 디버그용 창이 뜹니다.



안드로이드 디바이스에서 만약 아래 화면처럼 Unable to connect with remote debugger라는 에러가 나온다면, 크롬 창에서 http://10.0.2.2:8081/debugger-ui 주소를 http://localhost:8081/debugger-ui 로 변경하고, 디바이스의 앱을 완전종료 시킨 뒤 앱을 재실행하면 정상적으로 나오게 됩니다.

(오른쪽 아래 사각형 버튼을 누르면 실행중인 앱이 나오는데 이곳에서 종료시켜줍니다.)


(저는 빨간색 공포증이 있는데 가끔 개발하다 이 화면이 뜨면 심장이 막 뛰기 시작합니다..)


(여기서 앱을 종료해주세요)


이제 크롬 브라우저에서 디버깅이 가능합니다.

크롬을 자주 사용하시는 분은 아시겠지만 오른쪽 클릭 시 등장하는 메뉴에서 '검사'를 누르면 위와 같은 화면을 볼 수 있습니다.

단축키는 Windows에서 Ctrl + Shift + J, Mac에서 Command + Option + J로 콘솔창을 열 수 있습니다.


이 콘솔창에서는 javascript의 오랜 친구인 console.log()를 통해 메세지를 확인할 수 있습니다.




App.js의 render() 함수 안에 임의의 로그를 찍고 정상 출력되는지 확인해봅시다.

위와 같이 작성한 뒤, 디바이스를 새로고침하면 아래처럼 콘솔창에 log가 출력되는 것이 보입니다.

위의 'render!'가 잘 출력 되셨나요?

react에서 사용가능한 디버그 모듈도 많이 나와있다고 들었으나 당분간은 console.log를 사용할 계획입니다.

정상적으로 동작하지 않는다면 글 남겨주세요!


4. 요약


* 리액트 프로젝트 실행시 등장하는 커맨드 창은 빌드 없이 reload(새로고침)를 가능케 하는 번들링 서버라고 생각하면 된다.

* 리액트 프로젝트는 /index.js를 기점으로 시작된다. 이것은 개발자가 구상한 앱 구조에 따라 입맛대로 수정할 수 있다. 

* react native에서 지원하지 않는 기능은 네이티브 모듈로 구현하거나 모듈을 받아서 사용한다. 이때 각 디바이스에 대한 코드나 설정은 android/ 혹은 ios/에 작성된다.

* console.log를 통해 크롬에서 디버깅이 가능하다.


5. 마치며


설치와 실행을 다뤘던 전편에 비해서 비교적 간략한 내용들이였습니다.

하지만 본문 중 App.js를 열고 수정할 때, 여러가지 궁금증이 생기셨을거라 생각합니다.


Navigation이나 네이티브 모듈 제작은 약간 더 뒷 주제로 남겨두고, 다음 글에서는 App.js를 통해 컴포넌트를 이루는 코드와 JSX에 대해 알아보겠습니다.


Comming Soon!

9 Comments
  • 프로필사진 2018.07.20 22:40 비밀댓글입니다
  • 프로필사진 오지고지리고알파고포켓몬고 2018.07.20 22:45 신고 초대장 보냈습니다 :)
    화이팅하세요!!ㅎㅎ
  • 프로필사진 감사합니다! 2018.07.20 23:00 정말 감사드립니다!!
    초대장을 받게 되다니ㅠㅠ 뭐라 감사의 말씀을 드려야할지...
    늘 응원하고 자주 구경오겠습니다^^ 주말 잘 보내세요!!
  • 프로필사진 클라인STR 2018.11.04 12:52 신고 좋은 정보 감사합니다. ^^
  • 프로필사진 개린이 2019.07.22 14:00 좋은 정보 감사용 리액트네이티브 처음 하는데 도움 많이 됐어요
  • 프로필사진 ㅠㅠ 2019.08.25 17:03 console.log 찍는 게 안되는데... 구문이 올려주신거랑 좀 다른것같아요..
    제 app.js 내용입니다.
    /**
    * Sample React Native App
    * https://github.com/facebook/react-native
    *
    * @format
    * @flow
    */

    import React, {Fragment} from 'react';
    import {
    SafeAreaView,
    StyleSheet,
    ScrollView,
    View,
    Text,
    StatusBar,
    } from 'react-native';

    import {
    Header,
    LearnMoreLinks,
    Colors,
    DebugInstructions,
    ReloadInstructions,
    } from 'react-native/Libraries/NewAppScreen';

    const App = () => {
    return (
    <Fragment>
    <StatusBar barStyle="dark-content" />
    <SafeAreaView>
    <ScrollView
    contentInsetAdjustmentBehavior="automatic"
    style={styles.scrollView}>
    <Header />
    {global.HermesInternal == null ? null : (
    <View style={styles.engine}>
    <Text style={styles.footer}>Engine: Hermes</Text>
    </View>
    )}
    <View style={styles.body}>
    <View style={styles.sectionContainer}>
    <Text style={styles.sectionTitle}>Step One</Text>
    <Text style={styles.sectionDescription}>
    Edit <Text style={styles.highlight}>App.js</Text> to change this
    screen and then come back to see your edits.
    </Text>
    </View>
    <View style={styles.sectionContainer}>
    <Text style={styles.sectionTitle}>See Your Changes</Text>
    <Text style={styles.sectionDescription}>
    <ReloadInstructions />
    </Text>
    </View>
    <View style={styles.sectionContainer}>
    <Text style={styles.sectionTitle}>Debug</Text>
    <Text style={styles.sectionDescription}>
    <DebugInstructions />
    </Text>
    </View>
    <View style={styles.sectionContainer}>
    <Text style={styles.sectionTitle}>Learn More</Text>
    <Text style={styles.sectionDescription}>
    Read the docs to discover what to do next:
    </Text>
    </View>
    <LearnMoreLinks />
    </View>
    </ScrollView>
    </SafeAreaView>
    </Fragment>
    );


    };

    const styles = StyleSheet.create({
    scrollView: {
    backgroundColor: Colors.lighter,
    },
    engine: {
    position: 'absolute',
    right: 0,
    },
    body: {
    backgroundColor: Colors.white,
    },
    sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
    },
    sectionTitle: {
    fontSize: 24,
    fontWeight: '600',
    color: Colors.black,
    },
    sectionDescription: {
    marginTop: 8,
    fontSize: 18,
    fontWeight: '400',
    color: Colors.dark,
    },
    highlight: {
    fontWeight: '700',
    },
    footer: {
    color: Colors.dark,
    fontSize: 12,
    fontWeight: '600',
    padding: 4,
    paddingRight: 12,
    textAlign: 'right',
    },
    });

    export default App;

    어디서 console.log를 찍어야하나요?ㅠㅠㅠㅠㅠ
  • 프로필사진 오지고지리고알파고포켓몬고 2019.08.25 20:54 신고 함수형 컴포넌트 형태네요. 0.60.x버전을 사용하고 계신것 같습니다.

    본문에 작성된 패턴으로 사용하시려면, 본문에 render함수의 return에 App = () => 의 return 부분을 일치시켜주면 되시고,

    함수형 컴포넌트에서 사용하시려면 react hooks라는 키워드로 학습하시면 될 것 같습니다.
  • 프로필사진 MachineWoong 2020.01.07 22:22 혹시 가상머신이 아니라 USB로 실제 기기 연결해서 테스트 할때도 크롬 개발자 도구로 console.log 찍으면되나요 ??
    npx react-native run-android 실행시 node 창이 뜨는데 여기에는 로그가 안남는게 맞죠 ㅠㅠ?
    오늘 하루종일 시도하는데 안되서.. 글남겨봅니다.
  • 프로필사진 오지고지리고알파고포켓몬고 2020.01.28 20:33 신고 아이고 확인이 늦었습니다 ㅜㅜ
    usb로 연결할때도 마찬가지지만 크롬 디버깅 모드에서 로그를 보시려면 같은 네트워크에 연결되어있어야하고,

    rn버전에 따라 오락가락하는데 안드로이드 디바이스에서 노트북 ip와 디버깅 포트를 입력해야하는 경우가 있습니다ㅜㅜ
댓글쓰기 폼