Duelul: React Native vs. Cordova

Publicat: 2022-03-11

Ca urmare a faptului că smartphone-urile și aplicațiile mobile au devenit atât de populare, dezvoltatorii web au căutat modalități de a crea aplicații mobile folosind JavaScript. Această popularitate a dus la dezvoltarea multor cadre JavaScript capabile să ruleze aplicații native pe dispozitive mobile. În prezent, Cordova și React Native sunt cele mai populare alegeri. Cordova acceptă platformele mobile iOS, Android și Windows Phone. Cu React Native, pe de altă parte, Android, iOS și UWP sunt ținte pentru dezvoltatori. (UWP înseamnă Universal Windows Platform, platforma Microsoft care permite aceleiași aplicații să ruleze pe Windows Phone 10 Mobile, XBox One și Windows 10.)

De la suprafață, se pare că React Native și Cordova ocupă același spațiu. Cu toate acestea, ca și în cazul tuturor tehnologiilor, există aspecte în care una strălucește, iar cealaltă este scurtă. Așadar, pentru a obține o imagine mai bună a fiecărei tehnologii și pentru a afla avantajele și capcanele lor, ne vom scufunda în detalii despre fiecare și le vom compara în diferite discipline.

Diferențele de filozofie

Este important să ne amintim că sloganul lui React Native, „Învățați o dată, scrieți oriunde” diferă de mantra obișnuită pe mai multe platforme, „Scrieți o dată, alergați oriunde”. Acest lucru duce la două lucruri: în primul rând, nu putem să luăm baza noastră de cod React existentă din proiectul nostru web și să o transformăm într-o aplicație mobilă în doar câteva clicuri. Cu toate acestea, React și React Native împărtășesc o mulțime de concepte cheie, un exemplu fiind sistemele lor componente și, ca urmare, React Native se simte instantaneu familiar. În timp ce React are multe asemănări cu React Native, există unele diferențe de bază, care variază de la modul în care sunt gestionate foile de stil până la tipul de componente pe care le putem folosi.

În al doilea rând, s-ar putea să nu fim capabili să partajăm codul React Native atunci când vizează diferite platforme. Acest lucru se întâmplă atunci când preferăm ca elementele interfeței cu utilizatorul să se comporte nativ pe platforma lor specifică, oferind, la rândul său, utilizatorului o experiență mai bună și o senzație mai nativă a aplicației. Un exemplu evident este meniul lateral al sertarului din aplicațiile Android, care este foarte neobișnuit în aplicațiile iOS.

Cordova nu împărtășește această filozofie. Nu este neobișnuit să începem să dezvoltăm o aplicație web pură, să o grupăm ulterior ca o aplicație Cordova și să reutilizam cât mai mult cod posibil pentru toate platformele (mobile) pe care dorim să le țintim.

Libertatea de dezvoltare

Pe dispozitivele mobile, Cordova rulează o aplicație cu o singură pagină în interiorul browserului web mobil integrat, numită WebView, și apoi o împachetează ca o aplicație nativă. Deși pare o aplicație nativă din exterior, codul nostru web rulează în interiorul motorului de browser mobil. Pentru noi, asta înseamnă că nu suntem legați de o anumită bibliotecă sau cadru. Dacă folosim JavaScript vanilla, jQuery, Angular sau orice altceva, oricare dintre aceste opțiuni ar putea fi incluse într-o aplicație mobilă cu Cordova. Cordova nu impune stivei noastre de tehnologie. Atâta timp cât avem un fișier index.html , suntem gata. Un exemplu simplu ar fi următorul fragment de cod:

 <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>

Acest exemplu înseamnă că putem folosi aproape orice ne dorim, cum ar fi utilizarea unui manager de pachete precum NPM sau Bower, folosind un transpiler precum Babel, CoffeeScript sau TypeScript, un bundler precum Webpack sau Rollup sau cu totul altceva. Nu contează, atâta timp cât rezultatul este un fișier index.html care încarcă tot JavaScript și foile de stil de care avem nevoie.

React Native, după cum sugerează și numele, se bazează pe React. Este important să înțelegeți că partea React din React Native este una dintre caracteristicile sale de bază. Dacă nu sunteți un fan al naturii declarative a lui React, inclusiv JSX, componenta sa și fluxul de date, probabil că nu veți fi mulțumit de React Native. În timp ce React Native se simte instantaneu familiar pentru dezvoltatorii React, la prima vedere, există câteva diferențe de reținut. Cu React Native nu avem HTML sau CSS. În schimb, această tehnologie se concentrează pe partea JavaScript. Ca alternativă la CSS, stilurile sunt scrise inline, iar Flexbox este modelul de stil implicit.

Cea mai simplă aplicație React Native ar arăta similar cu acest exemplu:

 // 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 are propriul său pachet. Acesta reunește toate fișierele JavaScript într-un singur fișier gigant, care este apoi consumat și executat de JavaScriptCore, motorul JavaScript al Apple. JavaScriptCore este folosit pe iOS și Android, în timp ce ChakraCore alimentează aplicațiile React Native UWP. În mod implicit, React Native folosește transpilerul JavaScript Babel, permițându-ne să folosim sintaxa ECMAScript 2015+ (ECMAScript 6). Deși nu este necesar să utilizați sintaxa ECMAScript 2015+, aceasta este cu siguranță încurajată, deoarece toate exemplele oficiale și modulele terțe o adoptă. Deoarece React Native se ocupă de procesul de ambalare și transpilare, codul aplicației noastre și modulele terțe pot profita de aceste funcții fără a fi nevoie să configuram instrumentele pentru noi înșine.

Pentru a rezuma, React Native este o abordare cu opinie centrată pe React a dezvoltării mobile, în timp ce Cordova ne permite să grupăm tehnologii web în interiorul shell-ului WebView.

Aspect și simt nativ

Un lucru care este important pentru utilizatori este să aibă un aspect nativ al unei aplicații. Deoarece aplicațiile Cordova sunt de obicei simple aplicații web, există câteva lucruri care s-ar putea să pară ciudate la început. Problemele pot varia de la lipsa feedback-ului vizual pe zonele de atingere, la defilarea care nu se simte la fel de netedă ca în aplicațiile native, până la o întârziere de 300 de milisecunde la evenimentele de atingere. Deși există soluții pentru toate aceste probleme, ar trebui să ne amintim că ar putea fi nevoie să depunem un efort suplimentar dacă dorim ca aplicația noastră Cordova să se simtă cât mai aproape de aplicațiile native. În Cordova, nu avem acces la niciun control nativ. Dacă vrem să avem un aspect nativ, rămânem cu două opțiuni: fie recreăm controalele native, cum ar fi butoanele și elementele de intrare, cu HTML și CSS, fie implementăm module native care accesează direct acele controale native. Am putea face acest lucru singuri sau utilizând o bibliotecă terță parte, cum ar fi Ionic sau Onsen UI. Rețineți că este important să le țineți la zi cu actualizările sistemului de operare pe măsură ce apar. Uneori, aspectul unui sistem de operare mobil primește un lifting, așa cum sa întâmplat când a fost introdus iOS 7. Având o aplicație pe care nu o poate adapta, utilizatorii vor scoate din experiență. Am putea recurge și la includerea pluginurilor Cordova care ne conectează la partea nativă a lucrurilor. Una dintre cele mai complete controale native este biblioteca Microsoft Ace.

Cu React Native, pe de altă parte, avem acces la comenzi native și la interacțiune imediată. Componente precum Text , TextInput sau Slider se mapează cu omologii săi nativi. În timp ce unele componente sunt disponibile pentru toate platformele, alte componente funcționează numai pe anumite platforme. Cu cât dorim ca aplicația noastră să aibă un aspect nativ, cu atât mai mult trebuie să folosim componente care sunt disponibile numai pentru această platformă specifică și, prin urmare, cu atât baza noastră de cod diverge mai mult. Interacțiunile și gesturile cu atingerea minții fac parte și din React Native.

Compararea performanței

Având în vedere că Cordova are la dispoziție doar un WebView, suntem obligați să respectăm limitările WebView. De exemplu, după versiunea sa 4.0, Android a început în sfârșit să folosească (mult mai rapid) motorul Chrome ca WebView implicit. În timp ce cu iOS, pentru mult timp aplicația care rulează în motorul implicit WebView a fost semnificativ mai lentă decât aceeași aplicație din browserul mobil Safari. În plus, deoarece JavaScript are un singur thread, este posibil să întâmpinăm probleme dacă se întâmplă prea multe lucruri în codul aplicației noastre. Aceste limitări duc la animații lente și este posibil ca aplicația noastră să nu se simtă atât de receptivă pe cât ne-am dori să fie. Deși pot exista unele trucuri pe care le putem folosi ici și colo, în cele din urmă, suntem legați de limitele browserului mobil.

React Native utilizează mai multe fire de execuție, prin urmare redând elementele UI rulate în propriul fir de execuție. Deoarece componentele React se leagă la vizualizări native, JavaScript nu face munca grea în React Native.

Flux de lucru pentru dezvoltatori

Cordova oferă un utilitar de linie de comandă pentru a crea noi șabloane de proiect, pornind aplicația în simulator și construind aplicația pentru dispozitivul real într-un mod de producție. De cele mai multe ori, dezvoltăm aplicația pe un browser desktop și ulterior o putem grupa ca aplicație mobilă. Cu libertatea pe care o oferă Cordova, trebuie să ne ocupăm noi înșine de fluxul de lucru. Dacă dorim reîncărcare live pe dispozitiv, trebuie să o implementăm noi înșine. Pentru a depana aplicațiile Cordova, aplicăm aceleași principii folosite pentru depanarea unui site web. În iOS, de exemplu, ne-am conecta dispozitivul mobil prin USB, deschidem Safari și instrumentele sale de dezvoltare.

React Native oferă o interfață similară de linie de comandă și oferă un flux de lucru de dezvoltare familiar pentru dezvoltatorii web. Primim reîncărcarea live din cutie. Odată ce schimbăm o componentă React, aplicația noastră se reîncarcă cu modificările pe care le-am făcut. Una dintre cele mai interesante caracteristici este înlocuirea la cald a modulului, care reîncarcă parțial modificările aduse componentei pe care le-am făcut, fără a modifica starea aplicației. Ne-am putea chiar conecta la un dispozitiv real și să vedem dacă modificările noastre funcționează așa cum ne-am aștepta să facă pe un dispozitiv real. Aplicațiile noastre React Native pot fi depanate de la distanță cu Chrome pentru desktop. Gestionarea erorilor este evidentă în React Native; dacă întâlnim o eroare, aplicația noastră afișează un fundal roșu și este afișată urma stivei. Datorită hărților sursă, putem vedea locația exactă a erorii. Când facem clic pe el, editorul nostru ales se deschide în locația exactă a codului.

Extensibilitate și acces la caracteristicile native

Din partea JavaScript, suntem liberi să folosim orice bibliotecă JavaScript, inclusiv pachete de la NPM. Cu toate acestea, deoarece React Native nu este un mediu de browser, este posibil să ne fie dificilă utilizarea codului care se bazează pe DOM. React Native îmbrățișează modulele CommonJS și ES2015, astfel încât orice bibliotecă care utilizează aceste formate este ușor de integrat.

Atât Cordova, cât și React Native au capacitatea de a crea și utiliza pluginuri care se conectează la partea nativă a lucrurilor. Cordova oferă un API de nivel scăzut pentru crearea propriei noastre, care ne oferă mult control, dar duce la utilizarea mai multor modele native și JavaScript.

Dacă ar fi să scriem ipotetic un plugin iOS Cordova în Objective-C, ar putea arăta ca următorul fragment de cod. Pluginul nostru va înregistra doar parametrul de intrare.

 #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

Pentru a utiliza modulul, această bucată de cod JavaScript va ajuta:

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

Pentru a folosi pluginul, trebuie doar să apelăm funcția log :

 window.log('Hello native!');

React Native, pe de altă parte, urmează o altă filozofie; mapează automat tipurile JavaScript cu omologii săi nativi atunci când scrieți pluginuri, ceea ce face mai ușoară conectarea codului nativ cu JavaScript. Să aruncăm o privire la o bucată de cod care este necesară pentru a crea un modul nativ cu 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 leagă modulul pentru noi cu apelurile RCT_EXPORT_MODULE și RCT_EXPORT_METHOD . Acum îl putem accesa cu NativeModules.Log.log astfel:

 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);

În timp ce ne-am uitat doar cu atenție la crearea unui modul în iOS folosind Objective-C, aceleași principii se aplică și pentru crearea unui modul pentru Android folosind Java.

Trebuie să conectăm pluginuri native în fișierele de proiect pentru fiecare platformă. Cu iOS, de exemplu, aceasta înseamnă că trebuie să conectăm partea nativă compilată cu aplicația noastră și să adăugăm fișierele de antet corespunzătoare. Acesta poate fi un proces lung, mai ales dacă există o mulțime de module native. Din fericire, acest lucru este simplificat semnificativ prin utilizarea unui utilitar de linie de comandă numit rnpm, care a devenit parte a React Native în sine.

Concluzie: Reacționează Nativ sau Cordova?

React Native și Cordova au scopuri diferite și astfel răspund nevoilor diferite. Prin urmare, este greu de spus că o tehnologie este mai bună decât cealaltă în toate disciplinele.

Folosind Cordova, puteți transforma rapid aplicația existentă pe o singură pagină într-o aplicație mobilă pentru diferite platforme, cu prețul interacțiunilor care nu au neapărat sentimentul nativ față de platforma lor specifică.

Cu React Native, aplicațiile au un aspect mai nativ, dar cu prețul reimplementării bucăților de cod pentru anumite platforme țintă. Dacă ați practicat deja React și sunteți interesat să dezvoltați aplicații mobile, React Native se simte ca o extensie naturală.

Înrudit: Scufundare la rece în React Native: Tutorial pentru începători