فهم بنية المشروع
تعرّف إلى بنية مجلدات مشروع Expo، وتعلّم أدوار app.json وpackage.json ومكوّن App، ونفّذ أول تغيير لك في الشيفرة.
فهم بنية المشروع درس مجاني في React Native Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في 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.tspackage.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_Storebabel.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=1ios/ 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.gradleExpo 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) وفتح باقي دورة React Native Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Native Academy 4 دروس في المجموع.
ماذا ستتعلم في «فهم بنية المشروع»؟
تعرّف إلى بنية مجلدات مشروع Expo، وتعلّم أدوار app.json وpackage.json ومكوّن App، ونفّذ أول تغيير لك في الشيفرة. تتمرن على React Native Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ React Native Academy؟
لا تُشترط خبرة سابقة. React Native Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «فهم بنية المشروع»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس React Native Academy هذا؟
نعم. كل درس في React Native Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.