{"id":"l-rn-1-2","courseId":"react-native-apps","lang":"ar","kind":"lesson","summary":"أنشئ مشروع Trailhead باستخدام create-expo-app، وشغّله على هاتفك وعلى محاكٍ، وأضف المكتبات بأمان، واعرف متى يتوقّف Expo Go عن أن يكون كافيًا.","html":"<p>توصي وثائق React Native ببدء التطبيقات الجديدة باستخدام إطار عمل (framework)، والإطار الذي تشير إليه هو <strong>Expo</strong>. يمنحك Expo قالب المشروع، وخادم التطوير، ومكتبة من واجهات الجهاز (الكاميرا، الموقع، التخزين، الإشعارات) تعمل كلها مع إصدار SDK واحد، وخدمة سحابية للبناء والإطلاق. ويبقى بإمكانك كتابة كود أصلي حين تحتاج إليه؛ فأنت لست مقيّدًا.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">أنشئ Trailhead</h2>\n<p>تحتاج إلى Node.js (إصدار LTS نشط) وهاتف أو محاكٍ. ثم:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npx</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> create-expo-app@latest</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> trailhead</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">cd</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> trailhead</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npx</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> start</span></span></code></pre></div>\n<p>يأتي القالب الافتراضي مع TypeScript و<strong>Expo Router</strong> (نظام التوجيه في Expo) مضبوطَين مسبقًا. هذه هي الأجزاء التي ستلمسها أولًا:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"text\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Text</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code>trailhead/\n  src/app/_layout.tsx    root layout: wraps every screen (navigation lives here)\n  src/app/index.tsx      the first screen, at route &quot;/&quot;\n  src/app/explore.tsx    a second example screen, at &quot;/explore&quot;\n  assets/                icons, splash image, fonts\n  app.json               app name, icons, bundle ids, plugin settings\n  package.json           dependencies, including &quot;expo&quot; (the SDK version)</code></pre></div>\n<p>كل ملف داخل <code dir=\"ltr\">src/app</code> يصبح شاشة. ستتعلّم كيف يعمل التوجيه في القسم 3؛ أما الآن فافتح <code dir=\"ltr\">src/app/index.tsx</code>، وغيّر بعض النص، واحفظ.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">شغّله على جهاز</h2>\n<p>يشغّل <code dir=\"ltr\">npx expo start</code> أداة <strong>Metro</strong>، وهي مُجمِّع (bundler) كود JavaScript، ويطبع رمز QR. أمامك ثلاث طرق للدخول:</p>\n<ul>\n<li><strong>هاتفك مع Expo Go.</strong> ثبّت Expo Go من الـ App Store أو Play Store، ثم امسح رمز QR (بتطبيق الكاميرا على iOS، وبتطبيق Expo Go نفسه على Android). يجب أن يصل الهاتف والحاسوب أحدهما إلى الآخر عبر الشبكة.</li>\n<li><strong>محاكي iOS</strong> (على macOS مع Xcode): اضغط <code dir=\"ltr\">i</code> في الطرفية.</li>\n<li><strong>محاكي Android</strong> (عبر Android Studio): اضغط <code dir=\"ltr\">a</code>.</li>\n</ul>\n<p>أثناء عمل Metro، تستحق بضعة مفاتيح أن تحفظها أصابعك: <code dir=\"ltr\">r</code> يعيد تحميل التطبيق، و<code dir=\"ltr\">m</code> يفتح قائمة التطوير داخل التطبيق، و<code dir=\"ltr\">j</code> يفتح React Native DevTools. وحفظ أي ملف يشغّل <strong>Fast Refresh</strong>، الذي يُدخل الكود الجديد دون أن تفقد الـ components الـ state الخاصة بها.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">نصيحة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>جرّب على هاتف حقيقي مبكرًا</span></p>\n<p>المحاكي يعمل على معالج حاسوبك المحمول، ويحاكي الكاميرا والـ GPS محاكاةً (أو لا يوفّرهما أصلًا)، ولا يعطيك إحساسًا بحجم هدف اللمس تحت إبهامك. لهذا السبب بالضبط تُبقي فرق كثيرة هاتف Android رخيصًا متوسط الفئة في متناول اليد: فهو يكشف الإطارات البطيئة التي يخفيها حاسوبك.</p>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">إضافة المكتبات على طريقة Expo</h2>\n<p>كل إصدار من Expo SDK يستهدف إصدارًا واحدًا من React Native، والمكتبات الأصلية يجب أن تتوافق معه. لذا، بدلًا من <code dir=\"ltr\">npm install</code>، تضيف المكتبات هكذا:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npx</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> install</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo-location</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo-image-picker</span></span></code></pre></div>\n<p>يبحث <code dir=\"ltr\">npx expo install</code> عن الإصدار المعروف أنه يعمل مع الـ SDK لديك ويثبّته. أما حزم JavaScript الخالصة (مكتبة للتواريخ مثلًا) فيمرّرها إلى مدير الحزم لديك، لذا يمكنك استخدامه لكل شيء.</p>\n<p>وحين تشعر أن شيئًا ليس على ما يرام بعد ترقية، شغّل فحص السلامة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npx</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo-doctor</span></span></code></pre></div>\n<p>يُبلغك عن الإصدارات غير المتوافقة، والوحدات الأصلية المكرّرة، ومشكلات الإعداد.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>تثبيت أحدث إصدار من مكتبة أصلية</span></p>\n<p>قد يجلب <code dir=\"ltr\">npm install react-native-something@latest</code> إصدارًا مبنيًّا لإصدار React Native أحدث من الذي يستخدمه مشروعك. سيُترجَم كود JavaScript دون مشكلة، ثم ينهار التطبيق حين يستدعي الكود الأصلي. استخدم <code dir=\"ltr\">npx expo install</code> ودعه يختار.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">Expo Go مقابل الـ development build</h2>\n<p><strong>Expo Go</strong> تطبيق من المتجر فيه مجموعة ثابتة من الوحدات الأصلية المدمجة: الـ Expo SDK وعدد قليل من المكتبات الشائعة. ويُحمَّل كود JavaScript الخاص بك داخله. هذا مثالي للتعلّم، وهو السبب في أنك استطعت تشغيل Trailhead بعد ثوانٍ من إنشائه.</p>\n<p>لكن حدوده تظهر بسرعة في المشاريع الحقيقية:</p>\n<ul>\n<li>لا يستطيع أن يضمّ إلا الكود الأصلي الذي تُرجم داخله. أي مكتبة خارج تلك المجموعة لن تعمل.</li>\n<li>يدعم إصدار SDK واحدًا في كل مرة (الأحدث عادةً)، فقد لا يفتح فيه مشروع قديم.</li>\n<li>بعض الميزات تحتاج إلى هوية تطبيقك الخاصة، مثل الإشعارات الفورية (push notifications) ومخطّطات الروابط المخصّصة (custom URL schemes).</li>\n</ul>\n<p>الـ <strong>development build</strong> (نسخة التطوير) هو تطبيقك أنت، باسم تطبيقك وأيقونته ومعرّف الحزمة (bundle identifier) ووحداته الأصلية، إضافةً إلى أدوات التطوير نفسها (Fast Refresh، قائمة التطوير، DevTools). تنشئه محليًا:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npx</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> run:ios</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npx</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> expo</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> run:android</span></span></code></pre></div>\n<p>أو في السحابة، دون Xcode أو Android Studio على جهازك، باستخدام EAS Build (القسم 5). بعد ذلك، يقدّم <code dir=\"ltr\">npx expo start</code> كود JavaScript إلى الـ development build تمامًا كما كان يقدّمه إلى Expo Go.</p>\n<p>القاعدة المعقولة: تعلّم وابنِ النماذج الأولية في Expo Go، ثم انتقل إلى development build في أول مرة تحتاج فيها إلى شيء لا يملكه Expo Go. في Trailhead ستبقى في Expo Go حتى القسم 4.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">تغييرات JavaScript مقابل التغييرات الأصلية</h2>\n<p>هذا التمييز يمتد على طول الدورة، فلنسمّه الآن. <strong>تغييرات JavaScript</strong> (الـ components، التنسيقات، المنطق) تصل إلى التطبيق العامل عبر Fast Refresh أثناء التطوير، ولاحقًا عبر التحديثات عبر الهواء (over-the-air) في بيئة الإنتاج. أما <strong>التغييرات الأصلية</strong> (إضافة وحدة أصلية، أو تغيير نص الأذونات، أو أيقونة التطبيق، أو معرّف الحزمة في <code dir=\"ltr\">app.json</code>) فتحتاج إلى ملف تطبيق جديد. وحين «لا يظهر» تغيير ما، اسأل نفسك: من أي نوع كان؟</p>\n<p>في الدرس التالي ستستبدل الشاشة التجريبية في القالب بأول واجهة حقيقية لـ Trailhead، مستخدمًا الـ components الأساسية في React Native.</p>\n","toc":[{"id":"sec-1","text":"أنشئ Trailhead","level":2},{"id":"sec-2","text":"شغّله على جهاز","level":2},{"id":"sec-3","text":"إضافة المكتبات على طريقة Expo","level":2},{"id":"sec-4","text":"Expo Go مقابل الـ development build","level":2},{"id":"sec-5","text":"تغييرات JavaScript مقابل التغييرات الأصلية","level":2}],"takeaways":["<code dir=\"ltr\">npx create-expo-app@latest</code> ينشئ مشروع TypeScript مع Expo Router ومسارات مبنية على الملفات داخل <code dir=\"ltr\">src/app</code>.","<code dir=\"ltr\">npx expo start</code> يشغّل خادم التطوير Metro؛ امسح رمز QR بتطبيق Expo Go، أو اضغط <code dir=\"ltr\">i</code> أو <code dir=\"ltr\">a</code> لتشغيل محاكي iOS أو Android.","ثبّت المكتبات باستخدام <code dir=\"ltr\">npx expo install</code>، فهو يختار الإصدار المتوافق مع إصدار Expo SDK في مشروعك.","Expo Go بيئة تعلّم تجريبية فيها مجموعة ثابتة من الوحدات الأصلية؛ أما الـ development build فهو تطبيقك أنت مع أدوات التطوير، والمشاريع الحقيقية تنتقل إليه مبكرًا."],"further":[{"title":"Create a project","url":"https://docs.expo.dev/get-started/create-a-project/"},{"title":"Start developing","url":"https://docs.expo.dev/get-started/start-developing/"},{"title":"Introduction to development builds","url":"https://docs.expo.dev/develop/development-builds/introduction/"}],"quiz":[{"q":"<p>تحتاج إلى <code dir=\"ltr\">expo-location</code> في Trailhead. أي أمر يجب أن تشغّل؟</p>","options":[{"text":"<code dir=\"ltr\">npm install expo-location@latest</code>","why":"قد يستهدف أحدث إصدار SDK أحدث من مشروعك، فيحدث عدم توافق في الكود الأصلي لا يظهر إلا وقت التشغيل."},{"text":"<code dir=\"ltr\">npx expo install expo-location</code>","why":"صحيح. يثبّت الإصدار المعروف أنه يعمل مع إصدار Expo SDK في مشروعك."},{"text":"<code dir=\"ltr\">npx expo add-module expo-location</code>","why":"لا يوجد أمر باسم <code dir=\"ltr\">add-module</code>. الأمر الذي يجب أن تتذكّره هو <code dir=\"ltr\">npx expo install</code>."}],"answer":1},{"q":"<p>أضاف Trailhead مكتبة فيها كود أصلي مخصّص ليس ضمن Expo Go. ما الخطوة التالية الصحيحة؟</p>","options":[{"text":"الاستمرار في استخدام Expo Go وانتظار أن يحمّل الوحدة عبر الشبكة.","why":"لا يستطيع Expo Go تنزيل كود أصلي. وحداته الأصلية ثابتة منذ لحظة بنائه ونشره في المتاجر."},{"text":"الخروج من Expo (eject) وصيانة مجلّدَي ios وandroid يدويًا.","why":"لا حاجة لذلك. مشاريع Expo يمكن أن تضمّ أي مكتبة أصلية؛ كل ما عليك أن تبني ملف تطبيقك الخاص."},{"text":"إنشاء development build، إما محليًا باستخدام <code dir=\"ltr\">npx expo run:ios</code> أو في السحابة باستخدام EAS Build.","why":"صحيح. الـ development build هو تطبيقك أنت بوحداتك الأصلية، إضافةً إلى أدوات التطوير التي كانت لديك في Expo Go."}],"answer":2},{"q":"<p>عدّلت نص العنوان في <code dir=\"ltr\">src/app/index.tsx</code> وحفظت الملف. ماذا يحدث على الهاتف الذي يشغّل التطبيق؟</p>","options":[{"text":"يُدخل Fast Refresh الكود الجديد ويحافظ على الـ state الخاصة بالـ components حيثما أمكن.","why":"صحيح. تغييرات JavaScript يُعاد تحميلها في مكانها في نحو ثانية؛ والتغييرات الأصلية وحدها تحتاج إلى build جديد."},{"text":"لا شيء حتى تعيد بناء ملف التطبيق.","why":"إعادة البناء مطلوبة فقط للتغييرات الأصلية، مثل إضافة وحدات أصلية جديدة أو إعدادات في app.json تغيّر الملف التنفيذي."},{"text":"يعيد التطبيق التشغيل من شاشة البداية ويفقد كل الـ state.","why":"هذه إعادة تحميل كاملة، ويمكنك تشغيلها بالضغط على <code dir=\"ltr\">r</code>، لكن حفظ الملف يستخدم Fast Refresh."}],"answer":0}],"exercise":{"kind":"fill","language":"bash","template":"# 1. Create the project\nnpx {{0}}@latest trailhead\ncd trailhead\n\n# 2. Start the dev server (Metro)\nnpx expo {{1}}\n\n# 3. Add GPS support at the version that matches your SDK\nnpx expo {{2}} expo-location\n\n# 4. Check the project for version mismatches\nnpx {{3}}\n\n# 5. Build and run a development build on the iOS Simulator\nnpx expo {{4}}","blanks":[{"answers":["create-expo-app"]},{"answers":["start"]},{"answers":["install"]},{"answers":["expo-doctor","expo-doctor@latest"]},{"answers":["run:ios"]}],"title":"أوامر Expo التي ستكتبها كل أسبوع","prompt":"<p>املأ الفراغات لتُنشئ جلسة الطرفية هذه مشروع Trailhead، وتشغّل خادم التطوير، وتضيف <code dir=\"ltr\">expo-location</code> بأمان، وتشغّل فحص السلامة، ثم تبني development build لمحاكي iOS.</p>\n","hints":["اسم حزمة مولّد المشروع هو ما ستبحث عنه في npm لإنشاء تطبيق Expo.","إضافة مكتبة أصلية تستخدم الفعل نفسه الذي في npm، لكن عبر <code dir=\"ltr\">npx expo</code>.","البناء المحلي لمنصّة ما يستخدم <code dir=\"ltr\">run:</code> متبوعًا باسم المنصّة."],"explanation":"<p><code dir=\"ltr\">npx create-expo-app@latest</code> يُنشئ هيكل المشروع، و<code dir=\"ltr\">npx expo start</code> يشغّل Metro، و<code dir=\"ltr\">npx expo install</code> يختار إصدار المكتبة المتوافق مع الـ SDK لديك. و<code dir=\"ltr\">npx expo-doctor</code> يفحص حالات عدم التوافق. أما <code dir=\"ltr\">npx expo run:ios</code> فيترجم ملف تطبيقك الخاص (development build) ويثبّته على المحاكي، وهو ما تحتاج إليه حين لا يملك Expo Go وحدة أصلية تستخدمها.</p>\n","checkLabels":{}},"words":702,"readMinutes":4}