The Duel: React Native vs. Cordova

Pubblicato: 2022-03-11

Poiché gli smartphone e le applicazioni mobili sono diventati così popolari, gli sviluppatori web hanno cercato modi per creare applicazioni mobili utilizzando JavaScript. Questa popolarità ha portato allo sviluppo di molti framework JavaScript in grado di eseguire applicazioni native su dispositivi mobili. Attualmente, Cordova e React Native sono le scelte più popolari. Cordova supporta piattaforme mobili iOS, Android e Windows Phone. Con React Native, invece, Android, iOS e UWP sono obiettivi per gli sviluppatori. (UWP sta per Universal Windows Platform, la piattaforma di Microsoft che consente alla stessa applicazione di essere eseguita su Windows Phone 10 Mobile, XBox One e Windows 10.)

Dalla superficie, sembra che React Native e Cordova occupino lo stesso spazio. Tuttavia, come con tutte le tecnologie, ci sono aspetti in cui una brilla e l'altra non è all'altezza. Quindi, per avere un quadro migliore di ciascuna tecnologia e per apprenderne vantaggi e insidie, analizzeremo i dettagli di ciascuna e le confronteremo tra diverse discipline.

Differenze in filosofia

È importante ricordare che lo slogan di React Native, "Impara una volta, scrivi ovunque" differisce dal solito mantra multipiattaforma, "Scrivi una volta, corri ovunque". Questo porta a due cose: in primo luogo, non possiamo semplicemente prendere la nostra base di codice React esistente dal nostro progetto web e trasformarla in un'applicazione mobile in pochi clic. Tuttavia, React e React Native condividono molti concetti chiave con un esempio che sono i loro sistemi componenti e, di conseguenza, React Native sembra immediatamente familiare. Sebbene React condivida molte somiglianze con React Native, ci sono alcune differenze fondamentali, che vanno dal modo in cui i fogli di stile vengono gestiti al tipo di componenti che possiamo utilizzare.

In secondo luogo, potremmo non essere in grado di condividere il codice React Native quando ci rivolgiamo a piattaforme diverse. Ciò accade quando preferiamo che gli elementi dell'interfaccia utente si comportino in modo nativo sulla loro piattaforma specifica, offrendo a sua volta all'utente un'esperienza migliore e una sensazione più nativa dell'app. Un esempio ovvio è il menu a lato del cassetto nelle app Android, che è molto raro nelle app iOS.

Cordova non condivide questa filosofia. Non è raro iniziare a sviluppare un'applicazione Web pura, in seguito raggrupparla come un'applicazione Cordova e riutilizzare quanto più codice possibile per tutte le piattaforme (mobili) a cui vogliamo rivolgerci.

Libertà di sviluppo

Sui dispositivi mobili, Cordova esegue un'applicazione a pagina singola all'interno del browser Web mobile integrato, denominata WebView, e quindi la avvolge come un'applicazione nativa. Anche se dall'esterno sembra un'applicazione nativa, il nostro codice web è in esecuzione all'interno del motore del browser mobile. Per noi, ciò significa che non siamo legati a una libreria o un framework specifico. Se utilizziamo JavaScript vanilla, jQuery, Angular o qualsiasi altra cosa, una qualsiasi di queste opzioni potrebbe essere raggruppata in un'applicazione mobile con Cordova. Cordova non si impone sul nostro stack tecnologico. Finché abbiamo un file index.html , siamo a posto. Un semplice esempio potrebbe essere il seguente frammento di codice:

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

Questo esempio significa che possiamo utilizzare praticamente tutto ciò che desideriamo, ad esempio un gestore di pacchetti come NPM o Bower, un transpiler come Babel, CoffeeScript o TypeScript, un bundler come Webpack o Rollup o qualcos'altro. Non importa, purché il risultato sia un file index.html che carica tutto il JavaScript e i fogli di stile di cui abbiamo bisogno.

React Native, come suggerisce il nome, si basa su React. È importante capire che la parte React in React Native è una delle sue caratteristiche principali. Se non sei un fan della natura dichiarativa di React, incluso JSX, la sua componentizzazione e il flusso di dati, è probabile che probabilmente non sarai soddisfatto di React Native. Sebbene React Native sia immediatamente familiare agli sviluppatori di React, a prima vista ci sono alcune differenze da ricordare. Con React Native non abbiamo HTML o CSS. Invece, questa tecnologia è focalizzata sul lato JavaScript. In alternativa ai CSS, gli stili vengono scritti in linea e Flexbox è il modello di stile predefinito.

L'applicazione React Native più barebone sarebbe simile a questo esempio:

 // 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 ha il suo packager. Raggruppa tutti i file JavaScript in un unico file gigante, che viene quindi consumato ed eseguito da JavaScriptCore, il motore JavaScript di Apple. JavaScriptCore viene utilizzato su iOS e Android, mentre ChakraCore alimenta le applicazioni UWP native di React. Per impostazione predefinita, React Native utilizza il transpiler JavaScript Babel, consentendoci di utilizzare la sintassi ECMAScript 2015+ (ECMAScript 6). Sebbene non sia necessario utilizzare la sintassi ECMAScript 2015+, è decisamente incoraggiato, poiché tutti gli esempi ufficiali e i moduli di terze parti la stanno abbracciando. Poiché React Native si occupa del processo di confezionamento e traspiling, il codice dell'applicazione e i moduli di terze parti possono sfruttare queste funzionalità senza la necessità di configurare gli strumenti da soli.

Per riassumere, React Native è un approccio supponente incentrato su React allo sviluppo mobile, mentre Cordova ci consente di raggruppare le tecnologie web all'interno della shell WebView.

Aspetto e sensazione nativi

Una cosa che è importante per gli utenti è avere un aspetto nativo di un'applicazione. Poiché le applicazioni Cordova sono generalmente semplici applicazioni Web, all'inizio ci sono alcune cose che potrebbero sembrare strane. I problemi possono variare dalla mancanza di feedback visivo sulle aree di tocco, allo scorrimento che non sembra così fluido come nelle applicazioni native, a un ritardo di 300 millisecondi sugli eventi di tocco. Sebbene ci siano soluzioni per tutti questi problemi, dovremmo ricordare che potrebbe essere necessario fare uno sforzo in più se vogliamo che la nostra applicazione Cordova sia il più vicino possibile alle applicazioni native. In Cordova, non abbiamo accesso a nessun controllo nativo. Se vogliamo avere un aspetto nativo, ci restano due opzioni: ricreare i controlli nativi, come pulsanti ed elementi di input, con HTML e CSS, o implementare moduli nativi che accedono direttamente a quei controlli nativi. Potremmo farlo da soli o utilizzando una libreria di terze parti come Ionic o Onsen UI. Nota, è importante tenerli aggiornati con gli aggiornamenti del sistema operativo man mano che arrivano. A volte, l'aspetto di un sistema operativo mobile viene rinnovato, come è successo quando è stato introdotto iOS 7. Avere un'app che non è in grado di adattare porterà gli utenti fuori dall'esperienza. Potremmo anche ricorrere all'inclusione di plug-in Cordova che ci collegano al lato nativo delle cose. Uno dei controlli nativi più completi è la libreria Ace di Microsoft.

Con React Native, invece, abbiamo accesso ai controlli nativi e all'interazione fuori dagli schemi. Componenti come Text , TextInput o Slider mappano le sue controparti native. Mentre alcuni componenti sono disponibili per tutte le piattaforme, altri componenti funzionano solo su piattaforme specifiche. Più vogliamo che la nostra applicazione abbia un aspetto nativo, più abbiamo bisogno di usare componenti che sono disponibili solo per questa piattaforma specifica e quindi più la nostra base di codice diverge. Anche le interazioni e i gesti con il tocco mentale fanno parte di React Native.

Confronto delle prestazioni

Con Cordova che ha a sua disposizione solo una WebView, siamo vincolati ai limiti della WebView. Ad esempio, dopo la sua versione 4.0, Android ha finalmente iniziato a utilizzare il motore Chrome (molto più veloce) come visualizzazione Web predefinita. Mentre con iOS, per lungo tempo l'applicazione in esecuzione all'interno del motore WebView predefinito è stata significativamente più lenta della stessa applicazione nel browser mobile Safari. Inoltre, poiché JavaScript è a thread singolo, potremmo riscontrare problemi se ci sono troppe cose in corso nel codice dell'applicazione. Queste limitazioni portano a animazioni lente e la nostra applicazione potrebbe non essere reattiva come vorremmo. Sebbene possano esserci alcuni trucchi che possiamo utilizzare qua e là, alla fine, siamo vincolati dai limiti del browser mobile.

React Native utilizza più thread, quindi il rendering degli elementi dell'interfaccia utente viene eseguito nel proprio thread. Poiché i componenti di React si collegano alle viste native, JavaScript non sta facendo il lavoro pesante in React Native.

Flusso di lavoro per sviluppatori

Cordova offre un'utilità della riga di comando per creare nuovi modelli di progetto, avviare l'applicazione nel simulatore e creare l'applicazione per il dispositivo effettivo in una modalità di produzione. La maggior parte delle volte, stiamo sviluppando l'applicazione su un browser desktop e in seguito potremmo raggrupparla come applicazione mobile. Con la libertà offerta da Cordova, dobbiamo affrontare noi stessi il flusso di lavoro di sviluppo. Se vogliamo ricaricare in tempo reale sul dispositivo, dobbiamo implementarlo noi stessi. Per eseguire il debug delle applicazioni Cordova, applichiamo gli stessi principi utilizzati per il debug di un sito Web. In iOS, ad esempio, collegheremmo il nostro dispositivo mobile tramite USB, apriremmo Safari e i suoi strumenti di sviluppo.

React Native offre un'interfaccia a riga di comando simile e offre un flusso di lavoro di sviluppo familiare agli sviluppatori web. Otteniamo la ricarica dal vivo fuori dagli schemi. Dopo aver modificato un componente React, la nostra applicazione si ricarica con le modifiche apportate. Una delle funzionalità più interessanti è la sostituzione del modulo a caldo, che ricarica parzialmente le modifiche apportate al componente, senza alterare lo stato dell'applicazione. Potremmo anche connetterci a un dispositivo reale e vedere se le nostre modifiche funzionano come ci aspetteremmo su un dispositivo reale. Le nostre applicazioni React Native possono essere sottoposte a debug da remoto con Chrome for Desktop. La gestione degli errori è ovvia in React Native; se si verifica un errore, la nostra applicazione mostra uno sfondo rosso e viene mostrata la traccia dello stack. Grazie a sourcemaps, possiamo vedere la posizione esatta dell'errore. Quando ci clicchiamo sopra, il nostro editor preferito si apre nella posizione precisa del codice.

Estendibilità e accesso alle funzionalità native

Dal lato JavaScript, siamo liberi di utilizzare qualsiasi libreria JavaScript, inclusi i pacchetti di NPM. Tuttavia, poiché React Native non è un ambiente browser, potremmo trovare difficile utilizzare il codice che si basa su DOM. React Native abbraccia i moduli CommonJS ed ES2015, quindi tutte le librerie che utilizzano questi formati sono facili da integrare.

Sia Cordova che React Native hanno la capacità di creare e utilizzare plugin che si connettono al lato nativo delle cose. Cordova fornisce un'API di basso livello per la creazione della nostra, che ci dà molto controllo, ma porta all'uso di standard più nativi e JavaScript.

Se dovessimo ipoteticamente scrivere un plug-in Cordova iOS in Objective-C, potrebbe sembrare il prossimo frammento di codice. Il nostro plugin registrerà semplicemente il parametro di input.

 #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

Per utilizzare il modulo, questo pezzo di codice JavaScript aiuterà:

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

Per utilizzare il plugin, dobbiamo solo chiamare la funzione log :

 window.log('Hello native!');

React Native, invece, segue una filosofia diversa; mappa automaticamente i tipi JavaScript alle sue controparti native durante la scrittura di plug-in, il che semplifica la connessione del codice nativo con JavaScript. Diamo un'occhiata a un pezzo di codice necessario per creare un modulo nativo con 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 associa il modulo per noi con le chiamate RCT_EXPORT_MODULE e RCT_EXPORT_METHOD . Ora possiamo accedervi con NativeModules.Log.log in questo modo:

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

Mentre abbiamo solo esaminato da vicino la creazione di un modulo in iOS utilizzando Objective-C, gli stessi principi si applicano alla creazione di un modulo per Android utilizzando Java.

Dobbiamo collegare i plugin nativi all'interno dei file di progetto per ciascuna piattaforma. Con iOS, ad esempio, ciò significa che dobbiamo collegare la parte nativa compilata con la nostra applicazione e aggiungere i file di intestazione corrispondenti. Questo può essere un processo lungo, soprattutto se ci sono molti moduli nativi. Fortunatamente, questo è notevolmente semplificato utilizzando un'utilità della riga di comando chiamata rnpm che è diventata parte dello stesso React Native.

Conclusione: Reagire Native o Cordova?

React Native e Cordova hanno scopi diversi e quindi soddisfano esigenze diverse. Pertanto, è difficile dire che una tecnologia sia migliore dell'altra in tutte le discipline.

Utilizzando Cordova, puoi trasformare rapidamente la tua applicazione a pagina singola esistente in un'applicazione mobile per piattaforme diverse, a costo di interazioni che non hanno necessariamente la sensazione nativa della loro piattaforma specifica.

Con React Native, le applicazioni hanno un aspetto più nativo, ma a costo di reimplementare parti di codice per determinate piattaforme di destinazione. Se ti sei già dilettato in React e sei interessato allo sviluppo di applicazioni mobili, React Native sembra un'estensione naturale.

Correlati: Cold Dive into React Native: un tutorial per principianti