본문 바로가기

App

[React Native] #1-2. 리액트 네이티브 프로젝트 생성하기

728x90
반응형

React Native 프로젝트를 보다 쉽게 개발할 수 있도록 도와주는 Expo를 사용하면 빠르게 앱을 설정하고 실행할 수 있다.

1. 리액트 네이티브 프로젝트 생성하기

1-1. Expo 프로젝트 생성

Expo React Native 개발을 더 간편하게 만들어주는 도구이다. 이를 위해 expo-cli(Expo Command Line Interface)를 사용하면 쉽게 프로젝트를 생성하고 실행할 수 있다. 이때 expo-cli는 Expo 프로젝트를 생성하고 관리할 수 있는 명령어 도구이다. React Native 앱을 빌드하거나, 실행하고, 테스트할 때 사용된다.

 

터미널에서 다음 명령어를 실행하여 expo-cli를 글로벌 패키지로 설치한다 : npm install -g expo-cli

이 명령어를 실행하면 expo-cli가 시스템 전역에서 사용할 수 있도록 설치된다.

 

npm의 주요 명령어는 다음과 같다.

 

명령어 설명
npm install -g expo-cli Expo CLI를 전역으로 설치
npm start Expo 개발 서버 실행
npm install [패키지명] 프로젝트에 패키지 추가
npm run [스크립트명] 프로젝트 내 package.json에 정의된 스크립트 실행

Expo 프로젝트 생성 (my-first-rn)

설치가 완료되면 다음 명령어를 실행하여 새로운 Expo 프로젝트를 생성할 수 있다 : expo init my-first-rn

실행하면 프로젝트 유형을 선택하는 옵션이 나타난다. 여기서 "blank"(빈 프로젝트)를 선택한 후 진행한다.

 

 

프로젝트가 생성되면 cd 명령어를 이용해 해당 폴더로 이동한다 : cd my-first-rn

이제 React Native 프로젝트가 준비되었으며, 실행할 수 있는 상태가 된다.

1-2. React Native 실행하기

npm start

Expo 프로젝트를 실행하려면 터미널에서 다음 명령어를 입력한다 : npm start

이 명령어를 실행하면 Expo 개발 서버가 시작되며, 아래와 같은 옵션이 제공된다.

  • w: 웹 브라우저에서 실행
  • a: Android 에뮬레이터에서 실행
  • i: iOS 시뮬레이터에서 실행

npm start

 

React Native 프로젝트에서 npm start 명령어를 실행하면 Expo 개발 서버가 시작된다. 실행 과정에서 Metro Bundler가 활성화되며, 해당 프로젝트를 Android, iOS, 또는 웹에서 실행할 수 있는 상태가 된다.

 

현재 터미널 출력을 보면 Expo 개발 서버가 정상적으로 실행되었지만, iOS 시뮬레이터 실행 과정에서 오류가 발생한 것을 알 수 있다. 오류 메시지는 xcrun simctl help exited with non-zero code: 72이며, 이는 Xcode 시뮬레이터 실행 권한이나 설정 문제로 인해 발생할 가능성이 높다.

 

Expo는 기본적으로 Metro Bundler를 사용하여 React Native 프로젝트를 번들링 하고 실행한다. 프로젝트가 실행되면 exp://172.30.1.21:8081과 같은 로컬 서버 주소가 생성되며, 이를 통해 연결된 기기에서 앱을 테스트할 수 있다.

Expo 개발 서버가 실행되면 다양한 옵션을 사용할 수 있다.
터미널에서는 다음과 같은 키를 입력하여 프로젝트를 다양한 환경에서 실행할 수 있다.


키 입력 기능 설명
s 개발(Build) 모드 변경
a Android 에뮬레이터에서 실행
i iOS 시뮬레이터에서 실행
w 웹 브라우저에서 실행
j 디버거(Debugger) 실행
r 앱 새로고침(리로드)
m 디버그 메뉴 표시
shift + m 추가 도구 표시
o 코드 에디터에서 프로젝트 열기
? 모든 명령어 확인

현재 실행 상태에서 Expo Go 앱을 이용하면 모바일 기기에서 프로젝트를 확인할 수 있다.
iOS 사용자의 경우 카메라 앱을 이용해 QR 코드를 스캔하면 Expo Go를 통해 프로젝트가 실행된다.
Android 사용자는 Expo Go 앱을 직접 실행하여 QR 코드를 입력하거나 스캔하여 실행할 수 있다.

Expo Go 앱 소개

Expo Go는 React Native 개발자들이 손쉽게 모바일 애플리케이션을 실행하고 테스트할 수 있도록 도와주는 공식 앱이다. iOS와 Android에서 모두 사용할 수 있으며, Expo CLI를 통해 개발 중인 프로젝트를 실시간으로 로드할 수 있다.

 

1. 별도의 빌드 없이 앱 실행 가능

Expo Go를 사용하면 iOS 및 Android 기기에서 직접 React Native 앱을 실행할 수 있다.

  • 일반적으로 React Native 앱을 테스트하려면 Xcode 또는 Android Studio를 사용하여 빌드해야 하지만, Expo Go를 이용하면 QR 코드 스캔만으로 앱을 바로 실행할 수 있다.
  • 빌드 과정이 필요하지 않으므로, 개발 속도를 대폭 향상시킬 수 있다.

2. 실시간 코드 업데이트

Expo Go는 Hot Reloading(핫 리로딩) 및 Fast Refresh 기능을 지원하여, 코드 변경 사항을 앱에서 즉시 반영할 수 있다.

  • 코드 수정 후 Expo 개발 서버가 실행 중이라면 즉시 변경 사항이 적용되므로, 빠르게 개발하고 테스트할 수 있다.
  • npm start 실행 후 앱을 다시 빌드할 필요 없이, Expo Go에서 바로 변경된 내용을 확인 가능하다.

3. 네이티브 코드 수정 없이 실행 가능

Expo 프로젝트에서는 기본적으로 네이티브 코드(iOS의 Swift/Objective-C, Android의 Java/Kotlin)를 직접 수정하지 않아도 된다.

  • 따라서 Expo Go를 사용하면 Xcode나 Android Studio 없이도 React Native 앱을 실행할 수 있다.
  • 단, 특정 네이티브 모듈을 직접 수정해야 하는 경우 expo eject를 통해 Expo 관리 환경에서 벗어나야 한다.

4. QR 코드 스캔을 통한 손쉬운 실행

  • npm start를 실행하면 Metro Bundler가 실행되며, QR 코드가 표시된다.
  • iOS에서는 기본 카메라 앱으로 QR 코드를 스캔하여 Expo Go 앱에서 실행할 수 있다.
  • Android에서는 Expo Go 앱 내에서 QR 코드를 직접 스캔하여 실행하면 된다.

Expo Go의 한계점

네이티브 코드 변경 불가

Expo Go는 Expo 관리 환경(Managed Workflow)에서 동작하므로, 네이티브 코드를 직접 수정할 수 없다.

특정 네이티브 모듈이 필요한 경우 expo eject를 실행해야 하며, 이 과정 이후에는 Xcode 또는 Android Studio에서 직접 빌드해야 한다.

 

네이티브 라이브러리 추가 제한

React Native에서 일부 서드파티 네이티브 라이브러리를 사용할 경우, Expo Go에서는 지원되지 않을 수도 있다.

expo install을 사용하여 Expo 지원 라이브러리만 설치할 수 있으며, 네이티브 라이브러리를 직접 추가하려면 Expo에서 벗어나야 한다.

 


터미널 에러 분석

React Native 프로젝트를 Expo를 이용해 실행하는 과정에서 iOS 시뮬레이터 실행 오류가 발생했다.
오류 메시지는 다음과 같았다.

Unable to run simctl:
Error: xcrun simctl help exited with non-zero code: 72

 

이는 Xcode Command Line Tools의 경로가 올바르지 않거나, 시뮬레이터가 비활성화된 경우 발생할 수 있다.
이를 해결하기 위한 과정은 아래와 같다.

 

1. Xcode Command Line Tools 경로 확인
먼저 xcode-select --print-path 명령어를 실행하여 현재 설정된 Xcode Command Line Tools 경로를 확인했다.

 

출력 결과가 /Library/Developer/CommandLineTools로 나타났으며, 이는 Xcode의 기본 개발 경로와 다를 수 있다.

 

xcode-select --print-path

 

2. Xcode 경로 변경
Xcode의 올바른 경로로 설정하기 위해 다음 명령어를 실행했다.

변경이 완료된 후 다시 경로를 확인했다.

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
xcode-select --print-path

 

3. Expo 프로젝트 실행
이후 npm start 명령어를 실행하여 프로젝트를 다시 실행했다 : npm start

Metro Bundler가 정상적으로 실행되었으며, 더 이상 xcrun simctl 오류가 발생하지 않았다.


터미널에서 i 버튼을 누르면 ios가 실행되고 a를 누르면 안드로이드가 실행되며 자동으로 EXPO 앱이 설치된다.

 

React Native에서 앱을 실행한 후 실물 기기를 흔들면 화면 왼쪽에 메뉴가 나타난다. 가상 기기를 사용할 경우 iOS에서는 Command + D, 안드로이드에서는 Command + M을 누르면 동일한 메뉴를 호출할 수 있다. Windows 환경에서는 Command 대신 Ctrl을 사용하면 된다. 실행 중인 터미널에서 키보드의 M 키를 눌러도 동일하게 메뉴가 표시된다.

 

React Native는 코드가 변경될 때 자동으로 새로고침되지만, 강제로 새로고침을 원한다면 메뉴를 열고 Reload 버튼을 클릭하면 된다. 가상 기기에서는 메뉴를 열지 않고도 iOS에서는 A 키를 한 번, 안드로이드에서는 R 키를 두 번 누르면 즉시 새로고침이 실행된다. 또한, 실행 중인 터미널에서 R 키를 입력하면 현재 실행 중인 모든 기기가 동시에 새로고침된다.

기기에서 React Native가 정상적으로 실행되는지 확인하고, 메뉴 호출 및 새로고침 기능이 제대로 작동하는지 테스트해 보면 개발 과정에서 더욱 효율적으로 앱을 수정하고 반영할 수 있다.

 

1-3. EXPO 로그인하기

메뉴 > GO Home을 클릭하면 최근 실행했던 프로젝트를 볼 수 있다.

Expo 앱에서 회원가입을 하고 앱에서 로그인 한 후 아래 명령어를 사용해 같은 계정으로 로그인하고 프로젝트를 다시 시작해 보자.

expo login

로그인한 후 다시 expo를 실행하면 다음과 같이 Home 화면을 확인하면 현재 컴퓨터에서 실행 중인 프로젝트가 development Sever에 뜨는 것을 볼 수 있다.

 

이 방법을 이용하면 굳이 QR코드를 이용할 필요 없이 현재 실행 중인 프로젝트를 앱에서 실행할 수 있다!


2. JSX 문법 알아보기

현재 프로젝트 디렉터리에서 터미널을 열고 다음 명령어를 입력하면 App.js 파일이 존재하는지 확인할 수 있다.

ls -l App.js

출력 결과로 App.js 파일이 존재하면 정상적으로 프로젝트 내에 포함되어 있는 것이다.
만약 파일이 존재하지 않는다면 프로젝트 디렉터리가 맞는지 확인해야 한다. 이때는 cd 명령어를 이용해 현재 앱 개발 프로젝트 디렉터리로 이동한다.

 

파일 내용을 터미널에서 직접 확인하려면 다음 명령어를 입력한다 : cat App.js

터미널에서 다음 명령어를 실행하면 VS Code에서 App.js 파일을 바로 열 수 있다 : code App.js

vscode에서 다음 코드를 확인할 수 있다.
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

 

자바스크립트 형식이지만 return 부분을 보면 HTML과 유사하다. 이런 코드를 JSX라고 한다.

JSX란?

JSX는 JavaScript 안에서 XML(HTML과 유사한 문법)을 사용할 수 있도록 한 문법 확장이다.
기존 JavaScript에서는 React.createElement() 함수를 사용해야 UI 요소를 생성할 수 있었지만, JSX를 사용하면 HTML과 유사한 문법으로 더욱 직관적으로 UI를 작성할 수 있다.

 

HTML와 유사한 구조 : JSX는 HTML과 비슷해 보이지만, 실제로는 JavaScript 코드이다.

- React Native에서는 <View>, <Text>와 같은 React Native 전용 컴포넌트를 JSX에서 사용한다.

자바스크립트 표현식 사용 가능 : {}(중괄호) 안에 JavaScript 변수를 넣으면 해당 값이 동적으로 반영.

단일 루트 엘리먼트 필요 : return 문 안에서는 반드시 하나의 최상위 엘리먼트만 포함.

React Native에서 JSX 활용

React Native에서 JSX를 사용할 때 일반적인 HTML 태그 대신 React Native 컴포넌트를 사용해야 한다.
예를 들어, 웹 개발에서 div, p, span을 사용했다면, React Native에서는 <View>, <Text> 등을 사용해야 한다.

웹 HTML React Native
<div> <View>
<p> <Text>
<span> <Text>
<h1> ~ <h6> <Text style={{ fontSize: 24 }}>

2-1. 코드 수정하기

React Native에서 UI를 구성할 때 태그와 컴포넌트를 활용하여 화면을 구성한다. 태그(Tag)는 HTML과 유사한 요소를 의미하며, 컴포넌트(Component)는 React에서 UI를 구성하는 독립적인 블록이다. React Native에서는 <Text>, <View> 등의 기본 컴포넌트가 제공되며, 이를 사용하여 화면을 구성할 수 있다.

태그 HTML과 유소한 요소
컴포넌트 React에서 UI를 구성하는 블록

 

React Native에서는 코드 수정 후 저장하면 자동으로 변경 사항이 반영된다.
하지만 경우에 따라 핫 리로딩(Hot Reloading)이 적용되지 않을 수도 있으므로, 아래 방법을 사용하여 변경 사항을 제대로 반영할 수 있다.

 

1. VS Code에서 App.js 파일을 열고 파일을 저장(Cmd + S 또는 Ctrl + S)

2. React Native 프로젝트가 실행 중이 아니라면 터미널을 열고 다음 명령어를 실행하여 Expo 개발 서버를 시작한다.

3. Expo Go앱을 실행하여 실행을 확인한다.

npm start

 

Text 태그 내용 변경 예제

기본적으로 App.js에는 <Text> 태그가 포함되어 있으며, 이 내용을 변경하면 UI가 즉시 반영된다.
예제에서 기존의 "Open up App.js to start working on your app!" 문구를 변경해 보자.

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Expo React Native</Text>
      <StatusBar style="auto" />
    </View>
  );
}

이제 터미널에서 npm start를 실행하고 Expo에서 을 확인하면 "Expo React Native"라는 새로운 문구가 출력되는 것을 볼 수 있다.

실시간으로 반영되는 것을 확인할 수 있다!

console.log()를 사용한 디버깅

JSX 내의 <Text> 태그 내용을 변경하는 것 외에도, console.log()를 사용하여 콘솔에서 변수 값을 확인할 수 있다.

export default function App() {
  const message = "Expo React Native";
  console.log(message);  // 터미널에 출력됨
  
  return (
    <View style={styles.container}>
      <Text>{message}</Text>
      <StatusBar style="auto" />
    </View>
  );
}

이 코드를 실행하면 터미널에 "Expo React Native"가 출력되며, 앱 화면에도 같은 문구가 표시된다.

 

<Text> 태그와 console.log()의 차이점

React Native에서 <Text> 태그console.log()는 모두 값을 출력하는 역할을 하지만, 사용하는 목적과 출력 위치가 다르다.

앞선 코드에서 console.log(message); 를 이용하는 방법은 message 변수를 <Text> 태그로 UI를 출력했기 때문에 렌더링에 반영된 것이다.

구분 태그 console.log()
출력 위치 앱 화면(UI) 터미널(Console)
용도 사용자에게 정보를 표시 개발자가 디버깅할 때 사용
동작 환경 React Native UI 내에서 렌더링됨 JavaScript 엔진에서 실행됨
사용 예시 <Text>Hello, World!</Text> console.log("Hello, World!")
실행 방식 화면에 표시되는 UI 요소 개발 도구(Console)에 출력

 

 

  • <Text> 태그는 사용자에게 정보를 제공하는 UI 요소로, 앱 화면에 직접 텍스트를 출력한다.
  • console.log()는 디버깅 용도로 사용되며, 터미널(Console)에만 출력된다.

2-2. 태그 닫기

React Native에서 모든 태그는 올바르게 닫혀야 한다. JSX에서 태그를 닫는 방식은 크게 두 가지가 있다.

  1. 여는 태그와 닫는 태그가 있는 경우
    • <Text> 내용 </Text>처럼 여는 태그와 닫는 태그가 한 쌍으로 존재해야 한다.
  2. 닫는 태그 없이 한 줄로 작성하는 경우
    • <StatusBar style="auto" />와 같이 />로 끝나는 경우는 self-closing tag(자기 닫기 태그)라고 한다.
    • React Native에서는 <Image />, <TextInput />, <StatusBar /> 같은 태그들이 이를 따른다.

만약 태그를 닫지 않으면 JSX 파서에서 오류가 발생하므로, 모든 태그는 닫아야 한다는 점을 반드시 유의해야 한다.

만약 여러 개의 태그를 반환해야 하는 경우 JSX Fragment를 사용하면 불필요한 <View> 태그를 추가하지 않고도 그룹화할 수 있다.

 

 

<>... </> 형태는 key 속성을 가질 수 없다.

리스트를 렌더링 할 때 key 속성을 지정해야 하는 경우 <React.Fragment>를 사용해야 한다.

 

JSX Fragment는 단순히 그룹화 역할만 한다.

<View>처럼 레이아웃을 구성하는 스타일을 적용할 수 없다.

UI 스타일링이 필요한 경우 <View>를 사용해야 한다.

2-3. 자바스크립트 사용

JSX 내부에서 자바스크립트 표현식을 사용할 때는 중괄호 {}로 감싸야한다.
이를 통해 변수나 연산 결과를 UI에 반영할 수 있다.

App.js 수정 예시

export default function App() {
  const message = "Oldcast1e's React Native!";
  console.log(message);  // 터미널에 출력됨
  
  const name = "Heonseong";
  const isFullname = true;

  const add = (a,b) => {return a+ b};
  
  return (
    <View style={styles.container}>
      <Text>{message}</Text>
      <Text>My name is {name}</Text>
      <Text>1 + 2 = {add(1,2)}</Text>
      <Text>{isFullname == true ? name + ' Lee' : 'Not Full Name'}</Text>
      <StatusBar style="auto" />
    </View>
  );
}

 

실제 아이폰의 화면은 다음과 같이 갱신되는 것을 확인할 수 있다!

이거 신기하네요
 

 

 

2-6. 주석 사용 방법

JSX에서 주석을 사용할 때는 JavaScript의 주석 방식과 차이가 있다.
아래 표는 JSX에서 사용할 수 있는 주석 방식과 각각의 차이점을 정리한 것이다.

 

주석 방식 설명 예제
// JavaScript에서 사용하는 한 줄 주석 (JSX 외부) // 이 코드는 실행되지 않음
{/* */} JSX 내부에서 사용할 수 있는 주석 {/* 이 부분은 JSX 주석입니다. */}
/* */ JavaScript에서 사용하는 여러 줄 주석 (JSX 외부) /* 여러 줄 주석 사용 가능 */

예제 코드는 아래와 같다.

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function App() {
  // JavaScript 코드에서 한 줄 주석
  const name = "React Native"; 

  /* 
   JavaScript에서 여러 줄 주석 
   - 이 부분은 JSX 외부에서만 사용 가능
   - JSX 내부에서는 사용할 수 없음
  */

  return (
    <>
      {/* JSX 내부에서 사용하는 주석 */}
      <View style={styles.container}>
        <Text>Hello, {name}!</Text> 

        {/* 
          여러 줄 주석도 JSX 내부에서는 이런 방식으로 작성해야 한다. 
          JSX 내부에서 /* */ 를 직접 사용할 경우 오류가 발생함
        */}
        
        <Text>Welcome to JSX!</Text>
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1, // 한 줄 주석: flex 속성을 1로 설정
    backgroundColor: '#fff', /* 여러 줄 주석: 배경색 설정 */
    alignItems: 'center',
    justifyContent: 'center',
  },
});

 

위 코드에서 //는 JavaScript 코드에서만 사용할 수 있으며, JSX 내부에서는 {/* 주석 내용 */}과 같은 방식으로 주석을 작성해야 한다.


3. Prettier와 ESLint

3-1. prettier

1. settings > Format On Save 체크

2. Default Formatter를 Prettier - Code formatter로 변경

3. 설정이 완료되면 프로젝트 폴더에. prettierrc라는 파일을 만들고 다음과 같이 작성한다.

{
  "singleQuote": true,
  "arrowParens": "always",
  "tabWidth": 2,
  "printWidth": 80
}

 

"singleQuote": true → 문자열을 작은따옴표(')로 통일

"arrowParens": "always" → 화살표 함수에서 괄호(())를 항상 사용

"tabWidth": 2 → 들여 쓰기를 공백 2칸으로 설정

"printWidth": 80 → 한 줄의 최대 길이를 80자로 제한

 

 

기존 설정은 <Format On Save 체크 해지> & <Default Formatter - null>이다.

 

위 설정은 필수는 아니며, 개인 스타일에 맞춰 수정할 수 있다. App.js 파일에서 문자열을 큰따옴표(" ")로 변경하거나, 들여쓰기를 일부 수정한 후 저장하면 Prettier가 자동으로 설정한 스타일대로 포맷팅을 수행한다.

3-2. ESLint 설정하기

ESLint코드의 잠재적 오류를 방지하고, 코드 스타일을 유지할 수 있도록 도와주는 도구이다.
Prettier가 코드 형식을 자동으로 맞춘다면, ESLint는 잘못된 코드 패턴을 감지하여 경고를 제공한다.

 

1. ESLint 확장 프로그램 설치 : VS Code에서 ESLint 확장 프로그램을 설치한다.

2. 터미널에서 다음 명령어를 실행한다(ESLint 초기화) : npx eslint --init

설치 과정에서 몇 가지 질문이 나오며, 아래와 같이 선택하면 된다.

이때 개발 경로로 들어가 한다는 것을 유의하자.

 /Users/apple/Desktop/RN/my-first-rn

질문 선택 항목
How would you like to use ESLint? To check syntax and find problems
What type of modules does your project use? JavaScript modules (import/export)
Which framework does your project use? React
Does your project use TypeScript? No
Where does your code run? Node (Browser 선택 해제)
What format do you want your config file to be in? JSON
Would you like to install them now with npm? Yes

위 설정이 완료되면 프로젝트 폴더에. eslintrc.json 파일이 생성된다.


‼️ ESLint 초기화 시. eslintrc.json 대신 eslint.config.mjs가 생성되는 문제 발생

최근 ESLint의 기본 설정 방식이 변경되면서, 기존의. eslintrc.json 파일 대신 eslint.config.mjs 파일이 생성되는 경우가 있다.

 

이 문제를 해결하고. eslintrc.json을 사용하려면, npx eslint --init 실행 시 설정 파일 포맷 선택 단계에서 JSON을 명확히 선택해야 한다. 그러나 최신 버전에서는 기본적으로. mjs 형식이 선택되므로 이를 직접 변경해야 한다.

 

1. .eslintrc.json을 직접 생성하여 사용하는 방법

현재 /Users/apple/Desktop/RN/my-first-rn/ 경로에. eslintrc.json이 없기 때문에, 직접 생성하여 설정을 적용할 수 있다.

 

1) .eslintrc.json 파일 생성

터미널에서 다음 명령어를 실행하여 파일을 생성한다.

cd /Users/apple/Desktop/RN/my-first-rn touch .eslintrc.json

 

2) .eslintrc.json 내용 추가

.eslintrc.json 파일을 VS Code에서 열고 다음 내용을 추가한다.

{
  "env": {
    "browser": false,
    "node": true,
    "es2021": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react/jsx-runtime"
  ],
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": [
    "react"
  ],
  "rules": {
    "no-console": "warn",
    "react/react-in-jsx-scope": "off"
  }
}

 

2. 기존 eslint.config.mjs 삭제 (선택 사항)

만약. eslintrc.json을 사용하고 싶다면 eslint.config.mjs를 삭제하는 것이 좋다.

rm /Users/apple/Desktop/RN/my-first-rn/eslint.config.mjs

설정 항목 설명
"env" 프로젝트가 실행될 환경을 정의
"browser": false 브라우저 환경 비활성화
"node": true Node.js 환경 활성화
"es2021": true 최신 ES2021 기능을 지원
"extends" 적용할 기본 규칙을 정의
"eslint:recommended" ESLint 기본 권장 규칙 사용
"plugin:react/recommended" React 관련 권장 규칙 적용
"plugin:react/jsx-runtime" React 17 이상에서 JSX 사용 시 React import 불필요
"parserOptions" JavaScript 코드 해석 방식 설정
"ecmaVersion": "latest" 최신 ECMAScript 버전 지원
"sourceType": "module" JavaScript 모듈(import/export) 사용 설정
"plugins" ESLint 플러그인 목록
"react" React 관련 규칙 활성화
"rules" 프로젝트 내에서 적용할 규칙 정의
"no-console": "warn" console.log() 사용 시 경고 표시
"react/react-in-jsx-scope": "off" React 17 이상에서 import React from 'react'; 생략 가능하도록 설정

3. .eslintrc.json 파일이 적용되는지 확인하는 방법

터미널에서 ESLint 실행하여 적용 확인 : npx  --print-config App.js

ESLint 검사 실행 (경고 및 오류 확인) : npx eslint App.js

 

이제. eslintrc.json이 정상적으로 생성되었으며, ESLint가 설정한 규칙에 따라 코드 스타일을 검사하고 경고 메시지를 제공한다.

 

🤯 하지만 이 방법이 틀렸다는 것을 발견 ‼️


< "React must be in scope when using JSX"  문제 발생 >

현재 "React must be in scope when using JSX" 오류가 발생하는 이유는 ESLint가 React 17+ 환경에서 JSX 사용 시 React를 import 하지 않아도 된다는 것을 인식하지 못하기 때문이다.

 

  • React 17+에서는 import React from 'react'; 없이 JSX를 사용할 수 있지만, ESLint의 react/react-in-jsx-scope 규칙이 여전히 필요하다고 인식하고 있다.
  • 이 문제를 해결하려면 ESLint 설정 파일에 plugin:react/jsx-runtime을 추가해야 한다.
  • 또한, Warning: React version not specified 오류가 발생했으므로 React 버전을 명시적으로 설정해야 한다.

< ESLint v9.0.0 이후. eslintrc.json 미적용 문제 해결 > 

📌📌📌

 

ESLint v9.0.0 이상 버전에서는 기본 설정 파일이 eslint.config.js로 변경되었으며, 기존의. eslintrc.json을 그대로 사용할 수 없다.
따라서,. eslintrc.json을 새 포맷인 eslint.config.js로 변환해야 한다. 

 

1. 해결 방법:. eslintrc.json을 eslint.config.js로 변환

현재 프로젝트에서. eslintrc.json을 삭제하고, 새로운 eslint.config.js 파일을 생성해야 한다.

 

1) 기존. eslintrc.json 삭제

rm /Users/apple/Desktop/RN/my-first-rn/.eslintrc.json

 

2) eslint.config.js 생성 및 설정

새로운 ESLint 설정 파일을 프로젝트 루트 (/Users/apple/Desktop/RN/my-first-rn/)에 생성한다.

touch /Users/apple/Desktop/RN/my-first-rn/eslint.config.js

이제 eslint.config.js 파일을 열고, 다음과 같이 설정한다.

 

✅ eslint.config.js 설정

import js from "@eslint/js";
import react from "eslint-plugin-react";

export default [
  js.configs.recommended,
  react.configs.recommended,
  {
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module"
    },
    plugins: {
      react
    },
    settings: {
      react: {
        version: "detect"
      }
    },
    rules: {
      "no-console": "warn",
      "react/react-in-jsx-scope": "off"
    }
  }
];

 

📌 해결 방법은 아래에 따로 정리해 두었습니다 📌

 

최종적으로 해결된 핵심 포인트는 다음과 같다.

  1. JSX 파서를 명확하게 지정
    • @babel/eslint-parser를 JSX를 해석할 파서로 설정
    • parserOptions에 babelOptions.presets: ['@babel/preset-react'] 추가
  2. no-console을 off로 설정
    • console.log() 관련 경고를 비활성화
  3. react/react-in-jsx-scope를 off로 설정
    • React 17+에서는 import React from 'react' 없이 JSX를 사용할 수 있도록 설정

3-3. ESLint 적용 확인 및 테스트

이제 App.js 파일을 수정하여 ESLint가 정상적으로 동작하는지 확인한다.

export default function App() {
  console.log('Expo React Native'); // 경고 메시지 발생
  const test = 10; // 사용되지 않는 변수 경고 발생

  return (
    <View>
      <Text>Hello, React Native!</Text>
    </View>
  );
}

 

기존에는,

- console.log('Expo React Native'); → no-console 규칙에 의해 경고(warning) 표시

- const test = 10; → 사용되지 않는 변수에 대한 경고 발생

 

하지만 ESLint를 이용해 오류를 방지하고 불필요한 터미널 경고를 막을 수 있다!

 

ESLint를 사용하면 코드 오류를 사전에 방지하고, 코드 스타일을 통일할 수 있다. 이와 같이 Prettier와 ESLint는 React Native 개발에서 코드 품질을 유지하는 데 필수적인 도구이다.

  • Prettier는 코드 스타일을 자동으로 정리하고,
  • ESLint는 코드 오류를 사전에 감지하여 코드 품질을 개선한다.

이제 개발 환경이 정리되었으므로, 본격적으로 React Native 프로젝트를 진행할 수 있다.
다음 단계에서는 앱 개발을 시작하면서 다양한 React Native 기능을 활용하는 방법을 배워보자.


 

my-first-rn 작업 영역 변경

현재 my-first-rn 프로젝트를 /Users/apple/Desktop/RN 하위 폴더로 이동하려면 다음 단계를 수행해야 한다.

 

1) 기존 프로젝트를 새로운 경로로 이동

터미널에서 프로젝트를 새로운 위치로 이동 : mv ~/my-first-rn /Users/apple/Desktop/RN/

 

2) VS Code에서 새 경로의 프로젝트 열기

터미널에서 다음 명령어를 실행 : code /Users/apple/Desktop/RN/my-first-rn

 

3) Expo 개발 서버 설정 변경

Expo는 프로젝트 경로를 기반으로 실행되므로, 새로운 경로에서 개발 서버를 실행해야 한다.

cd /Users/apple/Desktop/RN/my-first-rn
npm start

기존 프로젝트 경로가 저장되어 있을 수 있으므로 Expo Go 앱을 재시작하거나 캐시를 삭제하는 것이 좋다.

 

> iOS: Expo Go 앱을 완전히 종료 후 다시 실행

> Android: Expo Go 앱 내의 캐시를 삭제 (설정 > 앱 > Expo Go > 저장공간 > 캐시 삭제)

 

4) .eslintrc.json 및 .prettierrc가 정상적으로 존재 & 실행되는지 확인

터미널에서 다음 명령어를 실행하여 설정 파일이 존재하는지 확인한다.

ls -l /Users/apple/Desktop/RN/my-first-rn/. eslintrc.json
ls -l /Users/apple/Desktop/RN/my-first-rn/. prettierrc

 

 

- Settings > Default Formatter가 Prettier - Code Formatter로 설정되어 있는지 확인

- Format On Save 옵션이 활성화되어 있는지 확인


ESLint 설정 문제 해결 과정 정리

리액트 네이티브 프로젝트에서 ESLint를 설정하는 과정에서. eslintrc.json이 적용되지 않는 문제가 발생했다.
이 문제를 해결하는 과정에서 ESLint v9의 새로운 Flat Config 방식을 반영해야 했으며, JSX 파서 설정도 추가해야 했다.
아래는 이 문제를 해결한 전체 과정이다.


1. 문제 발생: ESLint가 .eslintrc.json을 적용하지 않음

처음에는 기존 방식대로 .eslintrc.json을 생성하여 ESLint 설정을 적용하려 했으나, npx eslint App.js 실행 시 ESLint가 .eslintrc.json을 감지하지 못하는 문제가 발생했다.

❌ 발생한 오류

 
// npx eslint App.js 실행 시:

Oops! Something went wrong! :(

ESLint: 9.19.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.

 

🚨 ESLint v9 이상부터 .eslintrc.json을 지원하지 않고 eslint.config.js만 지원하는 것이 원인이었다.

✅ 해결 방법

.eslintrc.json을 삭제 : rm/Users/apple/Desktop/RN/my-first-rn/. eslintrc.json

eslint.config.js를 새로 생성 : touch /Users/apple/Desktop/RN/my-first-rn/eslint.config.js


2. 문제 발생: ESLint가 plugins 형식을 잘못 인식

이제 eslint.config.js를 적용하려고 했으나, Flat Config 방식에서 plugins 설정이 기존 방식과 달라 오류 발생.

❌ 발생한 오류

 
// npx eslint App.js 실행 시:
A config object has a "plugins" key defined as an array of strings.

Flat config requires "plugins" to be an object in this form:
{
    plugins: {
        react: pluginObject
    }
}

 

🚨 Flat Config에서는 plugins을 배열이 아닌 객체 형태로 지정해야 함.

✅ 해결 방법

  1. eslint.config.js의 plugins 부분을 배열에서 객체 형태로 변경
  2. reactPlugin.configs.recommended 적용을 제거

수정된 파일은 다음과 같았다.

import js from "@eslint/js";
import reactPlugin from "eslint-plugin-react";

export default [
  {
    files: ["**/*.{js,jsx,mjs,cjs}"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module"
    },
    plugins: {
      react: reactPlugin
    },
    settings: {
      react: {
        version: "detect"
      }
    },
    rules: {
      "no-console": "warn",
      "react/react-in-jsx-scope": "off"
    }
  }
];

 


3. 문제 발생: JSX를 해석하지 못하는 오류

이제 ESLint가 정상적으로 실행되었지만, JSX 문법을 포함한 코드를 해석하지 못하는 오류가 발생했다.

❌ 발생한 오류

 
// npx eslint App.js 실행 시 :
Parsing error: Unexpected token <

 

🚨 ESLint가 JSX를 인식하지 못하는 것이 원인.
이는 JSX를 해석하는 parser를 설정하지 않았기 때문이다.

✅ 해결 방법

  1. @babel/eslint-parser를 ESLint 파서로 지정
  2. @babel/preset-react을 ESLint가 사용할 수 있도록 추가

다음과 같이 코드를 수정한다.

import js from "@eslint/js";
import reactPlugin from "eslint-plugin-react";
import babelParser from "@babel/eslint-parser";

export default [
  {
    files: ["**/*.{js,jsx,mjs,cjs}"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      parser: babelParser, // JSX 파서 추가
      parserOptions: {
        requireConfigFile: false,
        babelOptions: {
          presets: ["@babel/preset-react"]
        }
      }
    },
    plugins: {
      react: reactPlugin
    },
    settings: {
      react: {
        version: "detect"
      }
    },
    rules: {
      "no-console": "warn",
      "react/react-in-jsx-scope": "off"
    }
  }
];

 

📌 추가적으로 필요한 패키지를 꼭 설치한다

npm install @babel/eslint-parser @babel/preset-react --save-dev

 


4. 문제 발생: no-console 경고

이제 ESLint가 정상적으로 동작했지만, console.log() 사용 시 no-console 경고가 발생했다.

❌ 발생한 경고

 
// npx eslint App.js 실행 시:
36:3  warning  Unexpected console statement  no-console

 

🚨 ESLint 기본 설정에서 console.log()를 경고하도록 되어 있었음.

✅ 해결 방법 : eslint.config.js에서 "no-console": "off"로 변경

최종 수정된 eslint.config.js은 다음과 같다.

필자는 두 가지를 골라서 사용하기 위해 주석처리로 남겨두었다.

import js from '@eslint/js';
import reactPlugin from 'eslint-plugin-react';
import babelParser from '@babel/eslint-parser';

export default [
  {
    files: ['**/*.{js,jsx,mjs,cjs}'],
    languageOptions: {
      ecmaVersion: 'latest',
      sourceType: 'module',
      parser: babelParser, // JSX 파서 추가
      parserOptions: {
        requireConfigFile: false,
        babelOptions: {
          presets: ['@babel/preset-react'],
        },
      },
    },
    plugins: {
      react: reactPlugin,
    },
    settings: {
      react: {
        version: 'detect',
      },
    },
    rules: {
      //   'no-console': 'warn',
      'no-console': 'off', // 🔹 console.log 허용
      'react/react-in-jsx-scope': 'off',
    },
  },
];

 

최종적으로 ESLint 정상 작동 확인

✅ 실행 명령어

npx eslint App.js

 

아무런 오류 없이 ESLint가 실행됨! 🎉

  1. ESLint v9 이상에서는 .eslintrc.json 대신 eslint.config.js 사용
  2. Flat Config 방식에 맞춰 plugins을 배열이 아닌 객체 형식으로 변경
  3. JSX를 해석할 수 있도록 @babel/eslint-parser 추가
  4. 필요한 패키지 설치 (@babel/eslint-parser @babel/preset-react)
  5. console.log() 경고 제거 ("no-console": "off")
  6. ESLint 정상 작동 확인 (npx eslint App.js)

이제 ESLint가 정상적으로 동작하며, React Native 프로젝트에서도 문제없이 사용할 수 있다! 🚀

 

728x90
반응형
댓글