0Pricing
React Native Academy · 강의

프로젝트 구조 이해하기

Expo 프로젝트의 폴더 구성을 살펴보고, app.json, package.json, App 컴포넌트의 역할을 익힌 뒤 첫 코드 변경을 수행합니다.

프로젝트 구조 이해하기은(는) CoddyKit의 무료 React Native Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Native Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

The Root of Every Expo Project

Every Expo project has a tidy layout that splits config, code, assets, and dependencies. Config files sit at the root, your code in App.js or src/, and packages in node_modules/.

MyFirstApp/
├── App.js             # Entry component
├── app.json           # Expo configuration
├── package.json       # Dependencies + scripts
├── package-lock.json  # Locked dependency tree
├── babel.config.js    # Transpiler config
├── .gitignore         # Files to exclude from git
├── assets/            # Static files
│   ├── icon.png
│   ├── splash.png
│   └── adaptive-icon.png
└── node_modules/      # Installed packages (auto-managed)

The assets/ Folder

The assets/ folder holds static files bundled with your app — images, fonts, audio. Reference a local image with require(), and Expo optimizes it during the build. See the code.

import { Image } from 'react-native';

// Referencing a local asset
<Image source={require('./assets/icon.png')} />

// Referencing a remote image
<Image source={{ uri: 'https://example.com/photo.jpg' }} />

// Loading a font from assets/
import * as Font from 'expo-font';
await Font.loadAsync({
  'Roboto-Bold': require('./assets/fonts/Roboto-Bold.ttf'),
});

App.js as the Entry Point

React Native needs one entry point: App.js, which must export a default component. As your app grows, App.js becomes a thin shell wiring up navigation, state, and themes.

// A typical App.js as the project grows
import { NavigationContainer } from '@react-navigation/native';
import { Provider } from 'react-redux';
import { ThemeProvider } from './context/ThemeContext';
import RootNavigator from './navigation/RootNavigator';
import store from './store';

export default function App() {
  return (
    <Provider store={store}>
      <ThemeProvider>
        <NavigationContainer>
          <RootNavigator />
        </NavigationContainer>
      </ThemeProvider>
    </Provider>
  );
}

Organizing Source Files in src/

Small apps live at the root, but as yours grows, add a src/ folder. Common subfolders: screens/, components/, navigation/, hooks/, and services/. It keeps things easy to find.

src/
├── screens/
│   ├── HomeScreen.tsx
│   ├── ProfileScreen.tsx
│   └── SettingsScreen.tsx
├── components/
│   ├── Button.tsx
│   ├── Card.tsx
│   └── Avatar.tsx
├── navigation/
│   └── RootNavigator.tsx
├── hooks/
│   └── useFetchUser.ts
├── services/
│   └── api.ts
└── utils/
    └── formatDate.ts

package.json Deep Dive

package.json is your project manifest: dependencies for runtime, devDependencies for tooling, and scripts for shortcuts. Never edit node_modules — npm install rebuilds it.

// package.json structure
{
  'name': 'my-first-app',
  'version': '1.0.0',
  'main': 'node_modules/expo/AppEntry.js',
  'scripts': {
    'start': 'expo start',
    'test': 'jest',
    'lint': 'eslint .'
  },
  'dependencies': {
    'expo': '~50.0.0',
    'react': '18.2.0',
    'react-native': '0.73.6'
  },
  'devDependencies': {
    '@types/react': '~18.2.0',
    'typescript': '^5.1.3',
    'jest': '^29.0.0'
  }
}

app.json vs app.config.js

Need dynamic config — like reading env variables at build time? Swap app.json for app.config.js, a JS file that exports your config using process.env.

// app.config.js (dynamic configuration)
export default {
  name: 'My App',
  slug: 'my-app',
  version: '1.0.0',
  extra: {
    apiUrl: process.env.API_URL || 'https://api.myapp.com',
    environment: process.env.APP_ENV || 'production',
  },
  ios: {
    bundleIdentifier: 'com.mycompany.myapp',
  },
  android: {
    package: 'com.mycompany.myapp',
  },
};

.gitignore and What to Exclude

The .gitignore file tells Git what to skip. Always exclude node_modules/ (npm rebuilds it), .expo/, and any secret files like .env. Committing node_modules bloats your repo.

# Default .gitignore for Expo
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/

# Environment files with secrets
.env
.env.local
.env.production

# macOS
.DS_Store

babel.config.js and Transpilation

The babel.config.js file controls how Babel transpiles your code. The babel-preset-expo preset covers the basics; you extend it with plugins like path aliases.

// babel.config.js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      // Path aliases: @/components → src/components
      ['module-resolver', {
        root: ['./src'],
        alias: { '@': './src' },
      }],
      // Reanimated plugin MUST be last
      'react-native-reanimated/plugin',
    ],
  };
};

The node_modules Directory

node_modules/ holds every package you depend on — often hundreds of megabytes. Never edit it directly. If things break, the classic fix is delete it and run npm install.

# If things break, a clean install often fixes it:
rm -rf node_modules
npm install

# Also clear the Metro cache
npx expo start --clear

# Check how many packages are installed
ls node_modules | wc -l

# See the dependency tree
npm list --depth=1

ios/ and android/ Folders in Bare Workflow

The managed workflow hides the ios/ and android/ folders — Expo handles native code. Run expo prebuild to generate them: the Xcode project and the Gradle build files.

# Generate native folders (bare workflow)
npx expo prebuild

# This creates:
ios/
├── MyApp/
│   ├── AppDelegate.swift
│   ├── Info.plist
│   └── Images.xcassets/
└── MyApp.xcodeproj/

android/
├── app/
│   ├── src/main/
│   │   ├── AndroidManifest.xml
│   │   └── java/.../MainApplication.kt
│   └── build.gradle
└── build.gradle

Expo Router and the app/ Directory

Newer projects use Expo Router, file-based routing like Next.js. Each file in app/ becomes a route — index.tsx is /, profile.tsx is /profile. No manual navigator needed.

// With Expo Router, file structure = routes:
app/
├── _layout.tsx     // Root layout (NavigationContainer)
├── index.tsx       // Screen at route '/'
├── profile.tsx     // Screen at route '/profile'
└── settings/
    ├── _layout.tsx // Settings-section layout
    └── index.tsx   // Screen at '/settings'

// app/index.tsx
import { Text, View } from 'react-native';
export default function HomeScreen() {
  return <View><Text>Home</Text></View>;
}

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

You mapped the project: assets/ holds media, app.json controls config, and src/screens and src/components organize your growing code. Next: the View component! 📦

자주 묻는 질문

“프로젝트 구조 이해하기” 강의는 무료인가요?

네 — “프로젝트 구조 이해하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Native Academy 강의 전체를 잠금 해제할 수 있습니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“프로젝트 구조 이해하기”에서 뭘 배우나요?

Expo 프로젝트의 폴더 구성을 살펴보고, app.json, package.json, App 컴포넌트의 역할을 익힌 뒤 첫 코드 변경을 수행합니다. 브라우저에서 직접 실행하는 실습 코드로 React Native Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Native Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Native Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“프로젝트 구조 이해하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Native Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Native Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Node, Expo CLI 및 시뮬레이터 설치
  2. 첫 Expo 프로젝트 만들기
  3. 기기와 에뮬레이터에서 실행하기
  4. 프로젝트 구조 이해하기
← React Native Academy(으)로 돌아가기