التنقيح في React Native

من موسوعة حسوب

التنقيح (Debugging) عمليّةٌ لا بد منها لإصلاح الأخطاء والعلل البرمجيّة، سنتعرف في هذه الصفحة على كيفية تنقيح تطبيقات React Native وبعض الأساليب والحيل المفيدة.

تمكين اختصارات لوحة المفاتيح

يدعم React Native بعض اختصارات لوحة المفاتيح في محاكي iOS. لتمكينها، افتح قائمة Hardware، واختر Keyboard، وتأكد من تحديد "Connect Hardware Keyboard". الاختصارات موصوفة أسفله.

الوصول إلى قائمة المطوّرين داخل التطبيق (In-App Developer Menu)

يمكنك الوصول إلى قائمة المطورين عبر هزّ الهاتف (أو رجِّه) أو عن طريق تحديد "Shake Gesture" داخل قائمة Hardware في محاكي iOS. يمكنك كذلك استخدام اختصار لوحة المفاتيح ‎⌘D عند تشغيل التطبيق في محاكي iOS، أو ‎⌘M عند تشغيله في محاكي Android على نظام التشغيل Mac OS و Ctrl+M على Windows و Linux. وكبديلٍ آخر في نظام التشغيل Android، يمكنك تنفيذ الأمر ‎adb shell input keyevent 82‎ لفتح قائمة المطورين (82 هو رمز مفتاح القائمة).

قائمة المطورين معطّلة في بناءات الإصدارات (أو بناءات الإنتاج: production builds).

إعادة تحميل JavaScript

بدلاً من إعادة تجميع (recompiling) تطبيقك في كل مرة تجري فيها تغييرًا، يمكنك إعادة تحميل شيفرة JavaScript لتطبيقك فورًا. للقيام بذلك، حدد "Reload" من قائمة المطورين. يمكنك أيضًا الضغط على ‎⌘R في محاكي iOS أو النقر فوق R مرتين على محاكيات Android.

إعادة التحميل المباشر

يمكنك تسريع وقت التطوير من خلال إعادة تحميل تطبيقك تلقائيًا في أي وقت تتغير فيه الشيفرة. يمكن تمكين إعادة التحميل المباشر عن طريق تحديد "Enable Live Reload" من قائمة المطورين.

يمكنك حتى الحفاظ على التطبيق مُشغّلًا أثناء قدوم نسخٍ جديدة من ملفاتك وحقنها تلقائيا داخل حزمة JavaScript عبر تمكين إعادة التحميل الساخن Hot Reloading من قائمة المطورين. سيتيح لك هذا إبقاء حالة التطبيق كما هي حتى بعد إعادة التحميل.

ملاحظة: هناك بعض الحالات التي لا يمكن فيها إعادة التحميل الساخن بشكل مثالي. إذا واجهتك مشكلة فاستخدم إعادة تحميل كاملة لإعادة ضبط تطبيقك.

ستحتاج إلى إعادة بناء (rebuild) تطبيقك لتفعيل التغييرات في حالات معينة:

  • عند إضافة موارد (resources) جديدة إلى حزمة تطبيقك الأصيل، كصورةٍ في Images.xcassets على iOS أو مجلد ‎res/drawable‎ على Android.
  • عند تعديل شيفرةٍ أصيلة (Objective-C أو Swift على iOS أو Java أو C++‎ على Android).

الأخطاء والتحذيرات داخل التطبيق

تُعرَض الأخطاء والتحذيرات داخل تطبيقك في بناءات التطوير (development builds).

الأخطاء

تُعرَض الأخطاء داخل التطبيق في نافذة تنبيه تملؤ الشاشة مع خلفية حمراء داخل تطبيقك. تُعرف هذه الشاشة باسم الصندوق الأحمر RedBox. يمكنك استخدام‎console.error() ‎ لإطلاقها يدويا.

التحذيرات

تُعرَض التحذيرات داخل التطبيق في نافذة تملؤ الشاشة مع خلفية صفراء داخل تطبيقك. تُعرف هذه الشاشة باسم الصندوق الأصفر YellowBox. انقر على التنبيهات لعرض المزيد من المعلومات أو لإغلاقها.

كما هو الحال مع الصناديق الحمراء، يمكنك استخدام‎console.warn() ‎ لإطلاق صندوق أصفر يدويا.

يمكن تعطيل الصناديق الصفراء أثناء التطوير باستخدام ‎console.disableYellowBox = true;‎ يمكن تجاهل تحذيراتٍ محدّدة برمجيًا عن طريق تعيين مصفوفة من السابقات (prefixes) التي يجب تجاهلها:

import {YellowBox} from 'react-native';
YellowBox.ignoreWarnings(['Warning: ...']);

في CI أو Xcode، يمكن أيضًا تعطيل الصناديق الصفراء عن طريق تعيين متغير البيئة IS_TESTING.

ملاحظة: تُعطَّلُ الصناديق الصفراء والحمراء تلقائيًا في بناءات الإصدارات (بناءات الإنتاج).

أدوات مطوري Chrome

لتنقيح شيفرة JavaScript في Chrome، حدّد "Debug JS Remotely" من قائمة المطورين. سيفتح هذا علامة تبويب جديدة تشير إلى العنوان ‎http://localhost:8081/debugger-ui‎.

حدّد ‎Tools → Developer Tools‎ من قائمة Chrome لفتح أدوات المطور. يمكنك كذلك الوصول إلى أدوات المطور باستخدام اختصارات لوحة المفاتيح (‎⌘⌥I‎ على macOS و ‎Ctrl+Shift+I‎ في Windows). قد ترغب كذلك بتمكين خيار "Pause On Caught Exceptions" للحصول على تجربة تنقيح أفضل.

ملاحظة: لا تعمل إضافة React Developer Tools مع React Native، لكن يمكنك استخدام الإصدار المستقل منها (standalone version) بدلاً من الإضافة. انظر هذا القسم لكيفيّة القيام بهذا.

تصحيح الأخطاء باستخدام منقح JavaScript مخصص

لاستخدام منقح JavaScript مخصص بدلاً من أدوات مطوري Chrome، اضبط متغيرَ البيئة REACT_DEBUGGER ليشير إلى أمرٍ يُشغِّل المنقّح المخصص. يمكنك بعد ذلك تحديد "Debug JS Remotely" من قائمة المطورين لبدء التنقيح.

سيستقبل المنقح قائمةً بكافة جذور المشروع، مفصولة بمسافة. على سبيل المثال، إذا ضبطتَ المتغيِّر على الشكل ‎REACT_DEBUGGER="node /path/to/launchDebugger.js --port 2345 --type ReactNative"‎ فهذا يعني أنّ الأمر ‎node /path/to/launchDebugger.js --port 2345 --type ReactNative /path/to/reactNative/app‎ هو الذي سيُستخدَم لتشغيل المنقح الخاص بك.

ملاحظة: يجب أن تكون أوامر المنقّح المخصص التي تنفَّذ بهذه الطريقة عملياتٍ سريعة، ويجب ألا تتعدى المُخرجاتُ أكثر من 200 كيلوبايت.

أدوات مطوري Safari

يمكنك استخدام متصفح Safari لتنقيح نسخة iOS من تطبيقك دون الحاجة إلى تمكين خيار "Debug JS Remotely".

  • مكِّن قائمة المطورين في Safari: عبر ‎Preferences → Advanced → "Show Develop menu in menu bar"
  • حدد سياق JSContext الخاص بتطبيقك: عبر ‎Develop → Simulator → JSContext
  • سيُفتَح مفتش الويب (Web Inspector) الخاص بمتصفّح Safari الذي يحتوي على لوحة تحكّم (Console) ومنقّح (Debugger).

لكن لهذه الطريقة بعض العيوب:

  • لا توجد خرائط مصدرٍ (sourcemaps) عند تصحيح الأخطاء.
  • في كل مرة يُعاد فيها تحميل التطبيق (باستخدام إعادة التحميل المباشر، أو بإعادة التحميل يدويًا)، يُنشأُ سياقُ JSContext جديد. يسمح لك خيار "Automatically Show Web Inspectors for JSContexts" بتجنّب الاضطرار إلى تحديد أحدث سياق JSContext يدويًا.

أدوات تطوير React

يمكنك استخدام الإصدار المستقل من أدوات تطوير React لتنقيح تسلسل مكونات React الهرميّ. من أجل هذا، ثبِّت حزمة react-devtools تثبيتا عامًّا (globally):

npm install -g react-devtools

شغّل الآن react-devtools من الطرفية لتشغيل تطبيق DevTools المستقل:

react-devtools

سيتصل التطبيق بجهاز المحاكاة الخاص بك في غضون ثوان قليلة.

ملاحظة: إذا كنت تفضل تجنب التثبيت العمومي، فيمكنك إضافة ‎react-devtools‎ كاعتماديّة (dependency) من اعتماديات المشروع. أضف حزمة ‎react-devtools‎ إلى مشروعك باستخدام الأمر ‎npm install --save-dev react-devtools‎، ثم أضف ‎"react-devtools": "react-devtools"‎ إلى قسم ‎scripts‎ في ملفّ package.json، ثم نفّذ الأمر ‎npm run react-devtools‎ من مجلد المشروع الخاص بك لفتح أدوات DevTools.

الدمج مع مفتش React Native

افتح قائمة المطوّرين داخل التطبيق واختر "Toggle Inspector". سيظهر لك تراكبٌ (overlay) يتيح لك النقر على أي عنصر من عناصر واجهة المستخدم والاطلاع على معلومات حوله:

لكن أثناء تشغيل ‎react-devtools‎، سيدخل المفتش في وضعِ طيٍّ (collapsed mode) خاص، وسيستخدم أداة DevTools كواجهة مستخدم أساسية. في هذا الوضع، سيؤدي النقر على جزءٍ ما من أجزاء التطبيق في جهاز المحاكاة إلى إظهار المكونات ذات الصلة في أدوات DevTools:

يمكنك اختيار "Toggle Inspector" في نفس القائمة للخروج من هذا الوضع.

تفتيش نسخ المكون (Component Instances)

عند تنقيح JavaScript في متصفّح Chrome، يمكنك تفحّص الخاصيّات وحالة مكونات React في وحدة تحكم المتصفح (browser console).

أولاً ، اِتّبع إرشادات التنقيح في Chrome لفتح وحدةِ تحكمِ متصفّحِ Chrome.

تأكد من أن القائمة المنسدلة في الجانب العلوي الأيسر من وحدة تحكم Chrome تحتوي على اسم debuggerWorker.js. هذه الخطوة ضرورية.

بعدها حدّد مكون React في أدوات React DevTools. هناك مربع بحث في الأعلى سيساعدك على العثور على مكوّنٍ باسمه. بمجرد تحديد المكون، سيكون متاحًا عبر المتغيّر ‎$r‎ في وحدة تحكم Chrome، مما يسمح لك بفحص خاصيّاته والحالة وخاصيات النسخة.

مراقبة الأداء

يمكنك تمكين شاشة تراكب (overlay) لمراقبة أداء التطبيق لمساعدتك على إصلاح مشاكل الأداء عن طريق تحديد "Perf Monitor" في قائمة المطورين.

تنقيح التطبيقات المُخرجَة (Ejected Apps)

المشاريع ذات شيفرة أصيلة فقط

ما تبقى من هذا الدليل ينطبق فقط على المشاريع التي بُدِأَت باستخدام الأمر ‎react-native init‎ أو على المشاريع المبدوءة بالأمر ‎expo init‎ أو أداة Create React Native App التي أُخرِجت عبر الأمر ‎eject‎. لمزيد من المعلومات حول عمليّة الإخراج، انظر هذا الدليل الموجود في مستودع أداة Create React Native App.

الوصول إلى سجلات وحدة التحكم (console logs)

يمكنك عرض سجلات وحدة التحكم لتطبيق iOS أو Android باستخدام الأوامر التالية في طرفيّةٍ أثناء تشغيل التطبيق:

$ react-native log-ios
$ react-native log-android

يمكنك كذلك الوصول إلى هذه الملفات عبر ‎Debug → Open System Log...‎ في محاكي iOS أو عن طريق تنفيذ الأمر ‎adb logcat *:S ReactNative:V ReactNativeJS:V‎ في الطرفيّة أثناء تشغيل تطبيق Android على جهازٍ أو محاكٍ.

  • إذا كنت تستخدم أداة Create React Native App أو Expo CLI، فستظهر السّجلات تلقائيًّا في نفس الطرفيّة التي تحتوي على مُخرَجات المُحزّم.

التنقيح على جهاز باستخدام أدوات مطوري Chrome

ملاحظة: إذا كنت تستخدم Create React Native App أو Expo CLI، فالإعدادات مضبوطة مسبقًا، لذا لا حاجة لاتباع هذه الخطوات.

على أجهزة iOS، افتح الملف RCTWebSocketExecutor.m وغيّر "localhost" إلى عنوان IP الخاص بحاسوبك، ثم حدد "Debug JS Remotely" من قائمة المطورين.

على أجهزة Android 5.0+‎ المتصلة عبر USB، يمكنك استخدام أداة سطر الأوامر adb لإعداد توجيه المنفذ (port forwarding) من الجهاز إلى حاسوبك:

adb reverse tcp:8081 tcp:8081

كبديل، حدّد "Dev Settings" من قائمة المطورين، ثم حدِّث إعداد "Debug server host for device" ليُطابِق عنوان IP الخاص بحاسوبك.

  • إذا واجهتك أي مشاكل، فمن الممكن أنّ أحد إضافات Chrome الخاصة بك تتفاعل مع المنقّح بطرق غير متوقعة. جرِّب تعطيل جميع الإضافات وإعادة تمكينها واحدة تلو الأخرى حتى تعثر على الإضافة المعطوبة.

تصحيح الأخطاء باستخدام Stetho على Android

اتبع هذا الدليل لتمكين Stetho في وضع التنقيح (Debug mode):

  • 1: أضف الأسطر التاليّة في قسم ‎android/app/build.gradle‎ في ملف ‎dependencies‎:
 debugCompile 'com.facebook.stetho:stetho:1.5.0'
 debugCompile 'com.facebook.stetho:stetho-okhttp3:1.5.0'

ملاحظة: ستضبط الشيفرة أعلاه Stetho v1.5.0. انظر صفحة المشروع لترى ما إذا توفر إصدار أحدث.

  • 2: أنشئ أصناف Java التالية لتغليف (wrap) استدعاء Stetho، واحدٌ للإصدار (release) وآخر من أجل التنقيح:
// android/app/src/release/java/com/{yourAppName}/StethoWrapper.java

public class StethoWrapper {

    public static void initialize(Context context) {
        // NO_OP
    }

    public static void addInterceptor() {
        // NO_OP
    }
}
// android/app/src/debug/java/com/{yourAppName}/StethoWrapper.java

public class StethoWrapper {
    public static void initialize(Context context) {
      Stetho.initializeWithDefaults(context);
    }

    public static void addInterceptor() {
      final OkHttpClient baseClient = OkHttpClientProvider.createClient();
      OkHttpClientProvider.setOkHttpClientFactory(new OkHttpClientFactory() {
        @Override
        public OkHttpClient createNewNetworkModuleClient() {
          return baseClient.newBuilder()
              .addNetworkInterceptor(new StethoInterceptor())
              .build();
        }
      });
    }
}
  • 3: افتح ‎android/app/src/main/java/com/{yourAppName}/MainApplication.java‎ واستبدل دالّة onCreate الأصليّة:
  public void onCreate() {
      super.onCreate();

      if (BuildConfig.DEBUG) {
          StethoWrapper.initialize(this);
          StethoWrapper.addInterceptor();
      }

      SoLoader.init(this, /* native exopackage */ false);
    }
  • 4: افتح المشروع في Android Studio وحل أي مشكلات تتعلق بالاعتماديات. سترشدك بيئة التطوير (IDE) أثناء تنفيذ هذه الخطوات بعد تحريك المؤشر فوق الخطوط الحمراء.
  • 5: نفّذ الأمر ‎react-native run-android‎.
  • 6: افتح علامة تبويب جديدة في متصفّح Chrome، ثمّ افتح العنوان ‎chrome://inspect‎، ثم انقر على عنصر "Inspect device" الموجود بجوار جملة "Powered by Stetho".

تنقيح الشيفرة الأصيلة

عند التطوير باستخدام الشيفرة الأصيلة، ككتابة وحداتٍ أصيلة مثلًا، يمكنك تشغيل التطبيق من Android Studio أو Xcode والاستفادة من ميّزات التنقيح التي توفرها هذه الأدوات الأصيلة (مثل إعداد نقاط توقفٍ (breakpoints) وما إلى ذلك)، بنفس الطريقة التي قد تتبّعها في حالة إنشاء تطبيق أصيل عاديّ.

مصادر