المبارزة: رد فعل السكان الأصليين مقابل كوردوفا

نشرت: 2022-03-11

نتيجة لازدياد شعبية الهواتف الذكية وتطبيقات الهاتف المحمول ، كان مطورو الويب يبحثون عن طرق لإنشاء تطبيقات الهاتف المحمول باستخدام JavaScript. أدت هذه الشعبية إلى تطوير العديد من أطر عمل JavaScript القادرة على تشغيل تطبيقات شبيهة بالتطبيقات الأصلية على الأجهزة المحمولة. في الوقت الحالي ، تعد كوردوفا و React Native أكثر الخيارات شيوعًا. تدعم كوردوفا الأنظمة الأساسية للهواتف المحمولة التي تعمل بأنظمة iOS و Android و Windows Phone. مع React Native ، من ناحية أخرى ، تعد Android و iOS و UWP أهدافًا للمطورين. (UWP تعني Universal Windows Platform ، منصة Microsoft التي تسمح لنفس التطبيق بالعمل على Windows Phone 10 Mobile و XBox One و Windows 10.)

من السطح ، يبدو أن React Native و Cordova يشغلان نفس المساحة. ومع ذلك ، كما هو الحال مع جميع التقنيات ، هناك جوانب يضيء فيها أحدهما ويقصر الآخر. لذلك ، للحصول على صورة أفضل لكل تقنية ، وللتعرف على مزاياها ومخاطرها ، سنغوص في تفاصيل كل منها ومقارنتها عبر التخصصات المختلفة.

الاختلافات في الفلسفة

من المهم أن تتذكر أن شعار React Native ، "تعلم مرة واحدة ، واكتب في أي مكان" يختلف عن الشعار المعتاد عبر الأنظمة الأساسية ، "اكتب مرة واحدة ، اركض في أي مكان." يؤدي هذا إلى شيئين: أولاً ، لا يمكننا فقط أخذ قاعدة أكواد React الحالية من مشروع الويب الخاص بنا وتحويلها إلى تطبيق جوال ببضع نقرات فقط. ومع ذلك ، فإن React و React Native يشتركان بالفعل في الكثير من المفاهيم الأساسية مع أحد الأمثلة على الأنظمة المكونة لهما ، ونتيجة لذلك ، يبدو React Native مألوفًا على الفور. بينما تشترك React في الكثير من أوجه التشابه مع React Native ، إلا أن هناك بعض الاختلافات الجوهرية ، والتي تتراوح من طريقة التعامل مع أوراق الأنماط إلى نوع المكونات التي يمكننا استخدامها.

ثانيًا ، قد نجد أنفسنا غير قادرين على مشاركة كود React Native عند استهداف منصات مختلفة. يحدث هذا عندما نفضل أن تتصرف عناصر واجهة المستخدم بشكل أصلي مع نظامها الأساسي المحدد ، مما يمنح المستخدم بدوره تجربة أفضل وشعورًا أصليًا بالتطبيق. مثال واضح على ذلك هو القائمة الجانبية للدرج في تطبيقات Android ، وهو أمر غير شائع في تطبيقات iOS.

قرطبة لا تشارك هذه الفلسفة. ليس من غير المألوف البدء في تطوير تطبيق ويب خالص ، ثم تجميعه لاحقًا كتطبيق كوردوفا ، وإعادة استخدام أكبر قدر ممكن من التعليمات البرمجية لجميع الأنظمة الأساسية (المحمولة) التي نريد استهدافها.

حرية التنمية

على الأجهزة المحمولة ، تقوم كوردوفا بتشغيل تطبيق من صفحة واحدة داخل متصفح الويب المدمج للهاتف المحمول ، يسمى WebView ، ثم يقوم بتغليفه كتطبيق أصلي. بينما يبدو أنه تطبيق أصلي من الخارج ، يعمل كود الويب الخاص بنا داخل محرك متصفح الجوال. بالنسبة لنا ، هذا يعني أننا لسنا مقيدين بمكتبة أو إطار عمل معين. إذا كنا نستخدم Vanilla JavaScript أو jQuery أو Angular أو أي شيء آخر ، فيمكن تجميع أي من هذه الخيارات في تطبيق جوال مع Cordova. كوردوفا لا تفرض على كومة التكنولوجيا لدينا. طالما لدينا ملف index.html ، فنحن على ما يرام. أحد الأمثلة البسيطة هو مقتطف الشفرة التالي:

 <html> <head> <title>My Cordova App</title> </head> <body> <div>Tap me</div> <script> // Select our element var element = document.getElementById('tapme'); // Send an alert once it was tapped/clicked element.addEventListener('click', function() { alert('Hello there!'); }); </script> </body> </html>

يعني هذا المثال أنه يمكننا استخدام أي شيء نرغب فيه إلى حد كبير ، مثل استخدام مدير الحزم مثل NPM أو Bower ، أو استخدام محول مثل Babel أو CoffeeScript أو TypeScript ، أو مجمع مثل Webpack أو Rollup ، أو أي شيء آخر تمامًا. لا يهم ، طالما أن النتيجة هي ملف index.html يقوم بتحميل جميع JavaScript وأوراق الأنماط التي نحتاجها.

React Native ، كما يوحي الاسم ، يبني على React. من المهم أن نفهم أن جزء React في React Native هو أحد ميزاته الأساسية. إذا لم تكن من المعجبين بالطبيعة التصريحية لـ React ، بما في ذلك JSX وتكوينها وتدفق البيانات ، فمن المحتمل أنك لن تكون سعيدًا بـ React Native. بينما تشعر React Native على الفور أنها مألوفة لمطوري React ، للوهلة الأولى ، هناك بعض الاختلافات التي يجب تذكرها. مع React Native ليس لدينا أي HTML أو CSS. بدلاً من ذلك ، تركز هذه التقنية على جانب JavaScript. كبديل لـ CSS ، تتم كتابة الأنماط مضمنة ، و Flexbox هو نموذج التصميم الافتراضي.

قد يبدو التطبيق الأكثر مجردة من React Native مشابهًا لهذا المثال:

 // Import the React module for JSX conversion import { React } from 'react'; // Import React Native's components import { View, Text, AppRegistry, TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Define our press handler const onPress = () => alert('Hello there!'); // Compose the components we are going to render return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);

React Native لها حزمة خاصة بها. يقوم بتجميع جميع ملفات JavaScript في ملف عملاق واحد ، والذي يتم استهلاكه وتنفيذه بواسطة JavaScriptCore ، محرك JavaScript من Apple. يتم استخدام JavaScriptCore على iOS و Android ، بينما تشغل ChakraCore تطبيقات React Native UWP. بشكل افتراضي ، يستخدم React Native مترجم JavaScript Babel ، مما يسمح لنا باستخدام صيغة ECMAScript 2015+ (ECMAScript 6). على الرغم من أنه ليس من الضروري استخدام بناء الجملة ECMAScript 2015+ ، إلا أنه يتم تشجيعه بالتأكيد ، حيث أن جميع الأمثلة الرسمية ووحدات الطرف الثالث تتبناها. نظرًا لأن React Native تهتم بعملية التغليف والترحيل ، يمكن أن تستفيد كود التطبيق ووحدات الطرف الثالث من هذه الميزات دون الحاجة إلى تكوين الأدوات لأنفسنا.

باختصار ، يُعد React Native منهجًا متمحورًا حول رد الفعل لتطوير الأجهزة المحمولة ، بينما يسمح لنا كوردوفا بتجميع تقنيات الويب داخل غلاف WebView.

الشكل والمظهر الأصلي

الشيء الوحيد المهم للمستخدمين هو أن يكون لديهم شكل وأسلوب أصليين للتطبيق. نظرًا لأن تطبيقات كوردوفا عادةً ما تكون تطبيقات ويب بسيطة ، فهناك بعض الأشياء التي قد تبدو غريبة في البداية. قد تتراوح المشاكل من الملاحظات المرئية المفقودة على مناطق النقر ، إلى التمرير الذي لا يبدو سلسًا كالحرير كما هو الحال في التطبيقات الأصلية ، إلى وجود تأخير 300 مللي ثانية في أحداث النقر. على الرغم من وجود حلول لجميع هذه المشكلات ، يجب أن نتذكر أننا قد نحتاج إلى بذل بعض الجهد الإضافي إذا أردنا أن يشعر تطبيق كوردوفا بأنه قريب من التطبيقات المحلية قدر الإمكان. في كوردوفا ، لا يمكننا الوصول إلى أي عناصر تحكم أصلية. إذا أردنا الحصول على مظهر ومظهر أصليين ، فلدينا خياران: إما إعادة إنشاء عناصر التحكم الأصلية ، مثل الأزرار وعناصر الإدخال ، باستخدام HTML و CSS ، أو تنفيذ الوحدات الأصلية التي تصل مباشرةً إلى عناصر التحكم الأصلية. يمكننا القيام بذلك بأنفسنا أو باستخدام مكتبة تابعة لجهة خارجية مثل Ionic أو Onsen UI. لاحظ أنه من المهم إبقائهم على اطلاع دائم بتحديثات نظام التشغيل فور ظهورها. في بعض الأحيان ، يتم تحسين مظهر نظام التشغيل المحمول ، كما حدث عندما تم تقديم iOS 7. سيؤدي وجود تطبيق غير قادر على تكييفه إلى إخراج المستخدمين من التجربة. يمكننا أيضًا اللجوء إلى تضمين مكونات كوردوفا الإضافية التي تربطنا بالجانب الأصلي للأشياء. تعد مكتبة Ace من Microsoft واحدة من عناصر التحكم الأصلية الأكثر اكتمالا.

مع React Native ، من ناحية أخرى ، لدينا وصول إلى عناصر التحكم الأصلية والتفاعل خارج الصندوق. يتم تعيين مكونات مثل Text أو TextInput أو Slider إلى نظيراتها الأصلية. بينما تتوفر بعض المكونات لجميع الأنظمة الأساسية ، تعمل المكونات الأخرى فقط على أنظمة أساسية محددة. كلما اقتربنا من أن يكون لتطبيقنا مظهر وشعور أصليان ، زادت حاجتنا إلى استخدام المكونات المتوفرة فقط لهذا النظام الأساسي المحدد ، وبالتالي كلما تباعدت قاعدة التعليمات البرمجية الخاصة بنا. تعد تفاعلات اللمس والإيماءات جزءًا من React Native أيضًا.

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

نظرًا لأن كوردوفا ليس لديها سوى WebView تحت تصرفها ، فنحن ملزمون بقيود WebView. على سبيل المثال ، بعد إصدار 4.0 ، بدأ Android أخيرًا في استخدام محرك Chrome (الأسرع بكثير) باعتباره WebView الافتراضي. أثناء استخدام iOS ، كان التطبيق الذي يتم تشغيله داخل محرك WebView الافتراضي أبطأ بشكل ملحوظ من نفس التطبيق في متصفح Safari للجوال لفترة طويلة. علاوة على ذلك ، نظرًا لأن JavaScript عبارة عن سلسلة واحدة ، فقد نواجه مشكلات إذا كان هناك الكثير من الأشياء التي تحدث في كود التطبيق الخاص بنا. تؤدي هذه القيود إلى رسوم متحركة بطيئة ، وقد لا يشعر تطبيقنا بالاستجابة كما نود أن يكون. بينما قد تكون هناك بعض الحيل التي يمكننا استخدامها هنا وهناك ، في النهاية ، نحن ملزمون بحدود متصفح الهاتف المحمول.

تستخدم React Native سلاسل رسائل متعددة ، وبالتالي يتم تشغيل عناصر واجهة المستخدم في سلسلة المحادثات الخاصة بها. نظرًا لأن مكونات React ترتبط بالعروض الأصلية ، فإن JavaScript لا يقوم بالمهمة الصعبة في React Native.

سير عمل المطور

تقدم Cordova أداة مساعدة لسطر الأوامر لإنشاء قوالب مشروع جديدة ، وبدء التطبيق في المحاكي وبناء التطبيق للجهاز الفعلي في وضع الإنتاج. في معظم الأحيان ، نقوم بتطوير التطبيق على متصفح سطح المكتب وقد نجمعه لاحقًا كتطبيق للهاتف المحمول. مع الحرية التي توفرها كوردوفا ، نحتاج إلى معالجة سير عمل التطوير بأنفسنا. إذا أردنا إعادة التحميل المباشر على الجهاز ، فنحن بحاجة إلى تنفيذه بأنفسنا. لتصحيح أخطاء تطبيقات كوردوفا ، نطبق نفس المبادئ المستخدمة لتصحيح أخطاء موقع الويب. في iOS ، على سبيل المثال ، سنقوم بتوصيل أجهزتنا المحمولة عبر USB ، وفتح Safari وأدوات المطور الخاصة به.

تقدم React Native واجهة سطر أوامر مماثلة وتقدم سير عمل تطوير مألوفًا لمطوري الويب. نحصل على إعادة شحن مباشرة من خارج منطقة الجزاء. بمجرد تغيير مكون React ، يتم إعادة تحميل تطبيقنا بالتغييرات التي أجريناها. إحدى أكثر الميزات إثارة هي استبدال الوحدة النمطية الساخنة ، والتي تعيد جزئيًا تحميل التغييرات في المكون الذي قمنا به ، دون تغيير حالة التطبيق. يمكننا حتى الاتصال بجهاز حقيقي ومعرفة ما إذا كانت التغييرات التي أجريناها تعمل كما نتوقعها على جهاز حقيقي. يمكن تصحيح أخطاء تطبيقات React Native الخاصة بنا عن بُعد باستخدام Chrome لسطح المكتب. معالجة الخطأ واضحة في React Native ؛ إذا واجهنا خطأ ، فإن تطبيقنا يعرض خلفية حمراء ، ويظهر تتبع المكدس. بفضل خرائط المصادر ، يمكننا رؤية موقع الخطأ بالضبط. عندما نضغط عليه ، يفتح محررنا المفضل في الموقع الدقيق للكود.

القابلية للتوسعة والوصول إلى الميزات الأصلية

من جانب JavaScript للأشياء ، نحن أحرار في استخدام أي مكتبة JavaScript ، بما في ذلك الحزم من NPM. ومع ذلك ، نظرًا لأن React Native ليست بيئة متصفح ، فقد نجد صعوبة في استخدام التعليمات البرمجية التي تعتمد على DOM. تضم React Native وحدتي CommonJS و ES2015 ، لذلك يسهل دمج أي مكتبات تستخدم هذه التنسيقات.

يمتلك كل من Cordova و React Native القدرة على إنشاء واستخدام المكونات الإضافية التي تتصل بالجانب الأصلي للأشياء. يوفر Cordova واجهة برمجة تطبيقات منخفضة المستوى لإنشاء واجهتنا الخاصة ، والتي تمنحنا قدرًا كبيرًا من التحكم ، ولكنها تؤدي إلى استخدام المزيد من النصوص المعيارية الأصلية وجافا سكريبت.

إذا أردنا أن نكتب افتراضيًا مكونًا إضافيًا لـ Cordova iOS في Objective-C ، فقد يبدو مثل مقتطف الشفرة التالي. سيقوم المكون الإضافي الخاص بنا بتسجيل معلمة الإدخال فقط.

 #import <Cordova/CDVPlugin.h> // Create a class that inherits from CDVPlugin @interface Log : CDVPlugin - (void)log:(CDVInvokedUrlCommand*)command; @end // The actual implementation of the class we just defined @implementation Log - (void)log:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; // We are getting all parameters and taking the first one NSString* echo = [command.arguments objectAtIndex:0]; // We are checking for the validity of the parameters if (echo != nil && [echo length] > 0) { // We are just printing the parameter using the native log method NSLog(echo); // Let's create a result for the plugin pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo]; } // Let's send a signal back with the plugin's result [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end

من أجل استخدام الوحدة ، سيساعد هذا الجزء من كود JavaScript في:

 window.log = function(str, callback) { cordova.exec(callback, function(err) { callback('Nothing to echo.'); }, "Log", "log", [str]); };

لاستخدام المكون الإضافي ، نحتاج فقط إلى استدعاء وظيفة log :

 window.log('Hello native!');

من ناحية أخرى ، تتبع React Native فلسفة مختلفة ؛ يقوم تلقائيًا بتعيين أنواع JavaScript إلى نظيراتها الأصلية عند كتابة المكونات الإضافية ، مما يسهل توصيل التعليمات البرمجية الأصلية بجافا سكريبت. دعنا نلقي نظرة على جزء من التعليمات البرمجية الضرورية لإنشاء وحدة نمطية باستخدام React Native:

 #import "RCTBridgeModule.h" @interface Log : NSObject <RCTBridgeModule> @end @implementation Log RCT_EXPORT_MODULE(); // This makes this method available NativeModules.Log.log RCT_EXPORT_METHOD(log:(NSString *)message) { NSLog(message); } @end

React Native يربط الوحدة بالنسبة لنا باستدعاءات RCT_EXPORT_MODULE و RCT_EXPORT_METHOD . يمكننا الآن الوصول إليه باستخدام NativeModules.Log.log على النحو التالي:

 import { React } from 'react'; import { View, Text, AppRegistry, NativeModules TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Log with our module once we tap the text const onPress = () => NativeModules.Log.log('Hello there'); return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);

بينما ألقينا نظرة فاحصة فقط على إنشاء وحدة نمطية في iOS باستخدام Objective-C ، تنطبق نفس المبادئ على إنشاء وحدة لنظام Android باستخدام Java.

نحتاج إلى ربط المكونات الإضافية الأصلية داخل ملفات المشروع لكل منصة. مع نظام التشغيل iOS ، على سبيل المثال ، هذا يعني أنه يجب علينا ربط الجزء الأصلي المترجم بتطبيقنا وإضافة ملفات الرأس المقابلة. يمكن أن تكون هذه عملية طويلة ، خاصة إذا كان هناك الكثير من الوحدات النمطية الأصلية. لحسن الحظ ، تم تبسيط ذلك بشكل كبير باستخدام أداة سطر أوامر تسمى rnpm والتي أصبحت جزءًا من React Native نفسها.

الخلاصة: هل تتفاعل مع السكان الأصليين أم كوردوفا؟

لكل من React Native و Cordova أغراض مختلفة ولذلك فهي تلبي الاحتياجات المختلفة. لذلك ، من الصعب القول إن إحدى التقنيات أفضل من الأخرى في جميع التخصصات.

باستخدام كوردوفا ، يمكنك تحويل تطبيق الصفحة الواحدة الحالي سريعًا إلى تطبيق جوال لمنصات مختلفة ، على حساب التفاعلات التي ليس بالضرورة أن يكون لها الشعور الأصلي لمنصتها المحددة.

باستخدام React Native ، تتمتع التطبيقات بمظهر وإحساس أكثر أصالة ولكن على حساب إعادة تنفيذ أجزاء من التعليمات البرمجية لبعض الأنظمة الأساسية المستهدفة. إذا كنت قد انخرطت بالفعل في React وكنت مهتمًا بتطوير تطبيقات الهاتف المحمول ، فإن React Native تشعر وكأنها امتداد طبيعي.

الموضوعات ذات الصلة: الغوص البارد في التفاعل الأصلي: برنامج تعليمي للمبتدئين