Tutorial de Apache Cordova: desarrollo de aplicaciones móviles con Cordova
Publicado: 2022-03-11Las aplicaciones móviles están apareciendo en todas partes, desde los teléfonos inteligentes y las tabletas hasta los relojes inteligentes, y pronto también se encontrarán en otros dispositivos portátiles. Sin embargo, desarrollar para cada plataforma móvil por separado puede ser una tarea exhaustiva, especialmente si sus recursos son limitados o si es un desarrollador único en lugar de una empresa de desarrollo de aplicaciones móviles.
Aquí es donde convertirse en un desarrollador de Apache Cordova bien versado puede ser útil al proporcionar una forma de desarrollar aplicaciones móviles utilizando tecnologías web estándar: HTML5, CSS3 y JavaScript.
En 2009, una startup llamada Nitobi creó PhoneGap, una API de código abierto para acceder a recursos móviles nativos, con el objetivo de permitir a los desarrolladores crear aplicaciones móviles utilizando tecnologías web estándar. Según la visión de Nitobi, la mayoría de las aplicaciones móviles pronto se desarrollarían utilizando PhoneGap, pero los desarrolladores aún tendrían la opción de escribir código nativo cuando fuera necesario, ya sea por problemas de rendimiento o por la falta de un método para acceder a hardware específico.
Cordova PhoneGap?
No hay tal cosa, de verdad. Lo que sucedió fue que Adobe adquirió Nitobi en 2011 y donó el núcleo de código abierto a Apache Software Foundation, que lo rebautizó como Apache Cordova. Una analogía común con la que te encontrarás a menudo es que Cordova es para PhoneGap lo que WebKit es para Chrome o Safari.
Obviamente, las diferencias entre Cordova y PhoneGap fueron mínimas al principio. Con el tiempo, Adobe PhoneGap desarrolló su propio conjunto de características patentadas, mientras que Cordova fue y sigue siendo compatible con la comunidad de código abierto. Esta revisión y tutorial de Apache Cordova examinará el desarrollo de la aplicación Cordova con más detalle y, aunque parte de esto puede aplicarse a PhoneGap, no debe considerarse un tutorial de PhoneGap per se .
Capacidades de Apache Cordova
En esencia, Cordova no tiene limitaciones en relación con las aplicaciones desarrolladas de forma nativa. Lo que obtiene con Cordova es simplemente una API de JavaScript, que sirve como contenedor para el código nativo y es consistente en todos los dispositivos. Puede considerar a Cordova como un contenedor de aplicaciones con una vista web, que cubre toda la pantalla del dispositivo. La vista web utilizada por Cordova es la misma vista web utilizada por el sistema operativo nativo. En iOS, esta es la UIWebView
de Objective-C predeterminada o una clase WKWebView
personalizada; en Android, esto es android.webkit.WebView
.
Apache Cordova viene con un conjunto de complementos predesarrollados que brindan acceso a la cámara, el GPS, el sistema de archivos, etc. del dispositivo. A medida que evolucionan los dispositivos móviles, agregar soporte para hardware adicional es simplemente una cuestión de desarrollar nuevos complementos.
Finalmente, las aplicaciones de Cordova se instalan igual que las aplicaciones nativas. Esto significa que compilar su código para iOS generará un archivo IPA, para Android un archivo APK y compilar para Windows Phone generará un archivo XAP. Si pone suficiente esfuerzo en el proceso de desarrollo, es posible que sus usuarios ni siquiera se den cuenta de que no están utilizando una aplicación nativa.
Flujos de trabajo de desarrollo de Apache Cordova
Hay dos caminos básicos que puede seguir al desarrollar con Cordova:
- Cuando su intención es implementar una aplicación en tantas plataformas como sea posible, con poco o ningún desarrollo específico de la plataforma, debe usar el flujo de trabajo multiplataforma. La herramienta principal que admite este flujo de trabajo es la interfaz de línea de comandos (CLI) de Cordova, que sirve como una abstracción de nivel superior para configurar y crear su aplicación para diferentes plataformas. Esta es la vía de desarrollo más utilizada.
- Si planea desarrollar su aplicación con una plataforma específica en mente, debe usar el flujo de trabajo centrado en la plataforma. De esta manera, podrá ajustar y modificar su código a un nivel inferior mezclando componentes nativos con componentes de Cordova. Aunque podría usar este enfoque para el desarrollo multiplataforma, el proceso será más largo y tedioso.
Por lo general, se recomienda comenzar con el flujo de trabajo de desarrollo multiplataforma, ya que cambiar al desarrollo centrado en la plataforma es bastante sencillo. Sin embargo, si inicialmente comienza con el flujo de trabajo centrado en la plataforma, no podrá cambiar al desarrollo multiplataforma ya que la CLI sobrescribirá sus personalizaciones una vez que ejecute el proceso de compilación.
Requisitos previos e instalación de Cordova
Antes de instalar y ejecutar cualquier cosa relacionada con Cordova, deberá instalar el SDK para cada plataforma para la que desee crear su aplicación. Nos centraremos en la plataforma Android en este artículo; sin embargo, el proceso que involucra a otras plataformas es similar.
Debe descargar el SDK de Android que se encuentra aquí. Para Windows, el SDK viene como un instalador, mientras que para Linux y OSX viene como un archivo que puede extraerse fácilmente. Después de extraer/instalar el paquete, deberá agregar los directorios sdk/tools
y sdk/platform-tools
a su variable PATH
. Cordova utiliza la variable PATH
para buscar los binarios que necesita para el proceso de compilación. Si no tiene instalado Java, debe continuar e instalar el JDK junto con Ant. ANT_HOME
y JAVA_HOME
deben configurarse en las carpetas bin de JDK y Ant, y después de instalar el SDK de Android, configure la variable ANDROID_HOME
en Android/Sdk
. Todas las ubicaciones en las tres variables *_HOME
también deben estar en su variable PATH
.
Después de instalar, el comando android
SDK estará disponible en su línea de comandos. Ejecútelo para abrir el administrador de SDK e instalar las últimas herramientas y la API de Android. Es probable que necesite Android SDK Tools, Android SDK Platform tools, Android SDK Build-tools, SDK Platform, Google API Intel x86 Atom System Image, Sources for Android SDK and Intel x86 Emulator Accelerator (HAXM installer) . Después de eso, podrá crear un emulador con android avd
.
La CLI de Cordova depende de Node.js y del cliente Git, así que adelante, descargue e instale Node desde nodejs.org y Git desde git-scm.com. Usará npm para instalar Cordova CLI, así como para instalar complementos adicionales, y Cordova usará git detrás de escena para descargar las dependencias requeridas. Finalmente, ejecuta
npm install -g cordova
…para instalar Cordova CLI globalmente ( npm install cordova
no es suficiente por sí solo).
A modo de resumen, estos son los paquetes que necesitarás:
- Java
- Hormiga
- SDK de Android
- NodoJS
- Git
Y estas variables de entorno deberán actualizarse:
-
PATH
-
JAVA_HOME
-
ANT_HOME
-
ANDROID_HOME
Bootstrapping de una aplicación
Siempre que haya instalado Cordova correctamente, ahora debería tener acceso a la utilidad de línea de comandos de Cordova. Abra su terminal o línea de comandos y navegue a un directorio donde le gustaría crear su primer proyecto de Cordova. Para iniciar una aplicación, escriba el siguiente comando:
cordova create toptal toptal.hello HelloToptal
La línea de comando consta del nombre del comando cordova
, seguido del subcomando create
. El subcomando se invoca con tres parámetros adicionales: la carpeta donde se colocará la aplicación, el espacio de nombres de la aplicación y su nombre para mostrar. Esto arranca la aplicación en una carpeta con la siguiente estructura:
toptal/ |-- hooks/ |-- platforms/ |-- plugins/ |-- www/ `-- config.xml
La carpeta www
contiene el núcleo de su aplicación. Aquí es donde colocará el código de su aplicación, que es común para todas las plataformas.
Si bien Cordova le permite desarrollar fácilmente una aplicación para diferentes plataformas, a veces necesita agregar personalizaciones. Al desarrollar para múltiples plataformas, no desea modificar los archivos de origen en los directorios de varias platforms/[platform-name][assets]/www
, porque se sobrescriben regularmente con los archivos www
de nivel superior.
En este punto, también puede abrir el archivo config.xml
y cambiar los metadatos de su aplicación, como el autor y la descripción.
Agrega tu primera plataforma usando:
cordova platform add android
Si cambia de opinión más adelante, puede eliminar fácilmente una plataforma del proceso de compilación:
cordova platform rm android
Al inspeccionar el directorio de plataformas, notará la carpeta de android
dentro de él. Para cada plataforma que agregue, Cordova creará un nuevo directorio en plataformas y duplicará la carpeta www
dentro de él. Si, por ejemplo, desea personalizar su aplicación para Android, puede modificar los archivos en platforms/android/assets/www
y cambiar a las herramientas de shell específicas de la plataforma.
Sin embargo, recuerde que si reconstruye su aplicación con la CLI (utilizada para el desarrollo multiplataforma), Cordova sobrescribirá los cambios que haya realizado para cada plataforma, así que asegúrese de tenerlos bajo el control de versiones o haga cambios específicos de la plataforma. cambios después de haber terminado con el desarrollo multiplataforma. Como mencionamos anteriormente, pasar del desarrollo multiplataforma al desarrollo específico de la plataforma es fácil. Moverse en la otra dirección no lo es.
Si desea seguir usando el flujo de trabajo multiplataforma y aún realizar personalizaciones específicas de la plataforma, debe usar la carpeta de combinación de nivel superior. A partir de la versión 3.5 de Cordova, esta carpeta se eliminó de la plantilla de aplicación predeterminada, pero si la necesita, simplemente puede crearla junto con los otros directorios de nivel superior ( hooks
, platforms
, plugins
y www
).
Las personalizaciones específicas de la plataforma se colocan en merges/[platform-name]
y se aplican después de los archivos de origen en la carpeta www
de nivel superior. De esta manera, puede agregar nuevos archivos de origen para ciertas plataformas o puede anular archivos de origen de nivel superior completos con archivos específicos de la plataforma. Tomemos como ejemplo la siguiente estructura:
merges/ |-- wp8/ | `-- app.js |-- android/ | `-- android.js |-- www/ `-- app.js
En este caso, el archivo de salida para Android contendrá los archivos app.js
y android.js
, pero el archivo de salida para Windows Phone 8 solo contendrá el archivo app.js
que se encuentra en la carpeta merges/wp8
, ya que el los archivos en merges/[platform]
anulan los archivos en www
.
El directorio de complementos contiene información para los complementos de cada plataforma. En este punto, solo debe tener el archivo android.json
que debe tener la siguiente estructura:
{ "prepare_queue": { "installed": [], "uninstalled": [] }, "config_munge": { "files": {} }, "installed_plugins": {}, "dependent_plugins": {} }
Construyamos la aplicación e implementémosla en un dispositivo Android. También puede usar el emulador, si lo desea.
Cordova proporciona varios pasos de CLI para crear y ejecutar sus aplicaciones: cordova prepare
, cordova compile
, cordova build
(que es un atajo para los dos anteriores), cordova emulate
y cordova run
(que incorpora build
y también puede ejecutar el emulador). Esto no debería confundirte, porque en la mayoría de los casos te gustaría compilar y ejecutar tu aplicación en el emulador:
cordova run --emulator
Si lo desea, puede conectar su dispositivo a través del puerto USB, habilitar el modo de depuración USB e implementar su primera aplicación Apache Cordova directamente en su dispositivo simplemente ejecutando:
cordova run
Esto copiará todos sus archivos en platforms/*
y ejecutará todas las tareas requeridas.
Puede limitar el alcance del proceso de compilación especificando el nombre de la plataforma para la que desea compilar la aplicación y/o incluso el emulador específico, por ejemplo:
cordova run android --emulator
o
cordova run ios --emulator --target="iPhone-8-Plus"
Tutorial práctico de Apache Cordova
Vamos a crear una aplicación de tutorial simple para demostrar el uso de Cordova y sus complementos. La demostración completa se puede encontrar en este repositorio de GitHub para que pueda descargarla y revisar partes junto con este breve tutorial de Cordova.
Usaremos la configuración inicial que creó y agregaremos código adicional. Digamos que queremos agregar nuevos proyectos a una base de datos Toptal imaginaria, así como ver los existentes. Abra index.html y configure dos pestañas de la siguiente manera:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" /> <link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css" /> <link rel="stylesheet" type="text/css" href="css/toptal.css" /> <title>Hello Toptal</title> </head> <body> <div> <div> </div> </div> <footer> <ul> <li class="tab-button active" data-tab="#search-tab">Search Projects</li> <li class="tab-button" data-tab="#add-tab">Post a Project</li> </ul> </footer> <div></div> <script src="js/lib/jquery-1.11.1.min.js"></script> <script src="js/lib/jquery.mobile-1.4.5.min.js"></script> <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="js/SQLiteStorageService.js"></script> <script type="text/javascript" src="js/Controller.js"></script> <script type="text/javascript" src="js/index.js"></script> </body> </html>
Tenga en cuenta que he agregado Bootstrap y jQuery Mobile como dependencias. Tenga en cuenta que se han desarrollado soluciones y marcos mucho mejores para crear aplicaciones híbridas modernas, pero dado que la mayoría (si no todos) los desarrolladores web están familiarizados con estas dos bibliotecas, tiene sentido usarlas para un tutorial para principiantes. Puede descargar las hojas de estilo de GitHub o usar las suyas propias, si lo prefiere.

Pasemos al archivo index.js
y lo reduzcamos a lo siguiente:
var app = { // Application Constructor initialize: function() { if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { document.addEventListener("deviceready", this.onDeviceReady, false); } else { this.onDeviceReady(); } }, onDeviceReady: function() { // We will init / bootstrap our application here }, }; app.initialize();
Recuerde que la arquitectura recomendada para las aplicaciones de Cordova es configurar una aplicación de página única (SPA). De esta forma, todos los recursos solo se cargan una vez cuando se inicia la aplicación y pueden permanecer en la vista web mientras la aplicación se esté ejecutando. Además, con los SPA, el usuario no tendrá recargas de página que no son simplemente típicas de las aplicaciones nativas. Teniendo eso en cuenta, configuremos un controlador simple para cambiar entre las dos pestañas:
var Controller = function() { var controller = { self: null, initialize: function() { self = this; this.bindEvents(); self.renderSearchView(); }, bindEvents: function() { $('.tab-button').on('click', this.onTabClick); }, onTabClick: function(e) { e.preventDefault(); if ($(this).hasClass('active')) { return; } var tab = $(this).data('tab'); if (tab === '#add-tab') { self.renderPostView(); } else { self.renderSearchView(); } }, renderPostView: function() { $('.tab-button').removeClass('active'); $('#post-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); $("#tab-content").load("./views/post-project-view.html", function(data) { $('#tab-content').find('#post-project-form').on('submit', self.postProject); }); }, renderSearchView: function() { $('.tab-button').removeClass('active'); $('#search-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); var $projectTemplate = null; $("#tab-content").load("./views/search-project-view.html", function(data) { $projectTemplate = $('.project').remove(); // Load projects here }); } } controller.initialize(); return controller; }
El controlador tiene dos métodos hasta ahora, uno para representar la Vista de búsqueda y otro para representar la vista Posterior al proyecto. Vamos a inicializarlo en nuestro archivo index.js
declarándolo primero en la parte superior y construyéndolo en el método onDeviceReady:
// top of index.js var controller = null
// inside onDeviceReady method controller = new Controller();
Finalmente, agregue una referencia de secuencia de comandos en index.html
arriba de la referencia a index.js
. Puede descargar las vistas Buscar y Publicar directamente desde GitHub. Dado que las vistas parciales se leen de un archivo, algunos navegadores como Chrome, al intentar mostrar su página, se quejarán de las solicitudes entre dominios.
La posible solución aquí sería ejecutar un servidor estático local, por ejemplo, utilizando el módulo npm node-static
. Además, aquí puedes empezar a pensar en usar algún framework como PhoneGap y/o Ionic. Todos ellos proporcionan una variedad de herramientas de desarrollo, incluida la emulación en el navegador, la recarga en caliente y la generación de código (scaffolding).
Por ahora, simplemente implementemos en un dispositivo Android ejecutando lo siguiente:
cordova run android
En este punto, su aplicación debe tener dos pestañas. La primera pestaña permite buscar proyectos:
La segunda pestaña permite publicar nuevos proyectos:
Todo lo que tenemos ahora es una aplicación web clásica que se ejecuta dentro de una vista web. Realmente no hemos usado ninguna de las funciones nativas, así que intentemos hacerlo ahora. Una pregunta común es cómo almacenar datos localmente en el dispositivo o, más precisamente, qué tipo de almacenamiento usar. Hay varias formas de ir:
- Almacenamiento local
- Web SQL
- Base de datos indexada
- Almacenamiento del lado del servidor al que se accede a través de un servicio web
- Complementos de terceros que ofrecen otras opciones
LocalStorage está bien para almacenar pequeñas cantidades de datos, pero no será suficiente si está creando una aplicación de uso intensivo de datos, ya que el espacio disponible varía de 3 a 10 MB. IndexedDB puede ser una mejor solución para este caso. WebSQL está en desuso y no es compatible con algunas plataformas. Finalmente, el uso de servicios web para obtener y modificar datos se ajusta bien al paradigma SPA, pero falla cuando la aplicación se desconecta. Las técnicas de PWA junto con Service Workers han llegado recientemente al mundo de Cordova para ayudar con esto.
Además, hay muchos complementos adicionales de terceros que vienen para llenar los vacíos en el núcleo de Cordova. El complemento Archivo puede ser bastante útil ya que le brinda acceso al sistema de archivos del dispositivo, lo que le permite crear y almacenar archivos. Por ahora, probemos SQLitePlugin que le proporciona una base de datos SQLite local. Puede agregarlo a su proyecto ejecutando:
cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin
SQLitePlugin proporciona una API a la base de datos SQLite del dispositivo y sirve como un verdadero mecanismo de persistencia. Podemos crear un servicio de almacenamiento simple de la siguiente manera:
SQLiteStorageService = function () { var service = {}; var db = window.sqlitePlugin ? window.sqlitePlugin.openDatabase({name: "demo.toptal", location: "default"}) : window.openDatabase("demo.toptal", "1.0", "DB para FactAV", 5000000); service.initialize = function() { // Initialize the database var deferred = $.Deferred(); db.transaction(function(tx) { tx.executeSql( 'CREATE TABLE IF NOT EXISTS projects ' + '(id integer primary key, name text, company text, description text, latitude real, longitude real)' ,[], function(tx, res) { tx.executeSql('DELETE FROM projects', [], function(tx, res) { deferred.resolve(service); }, function(tx, res) { deferred.reject('Error initializing database'); }); }, function(tx, res) { deferred.reject('Error initializing database'); }); }); return deferred.promise(); } service.getProjects = function() { // fetch projects } service.addProject = function(name, company, description, addLocation) { // add a new project } return service.initialize(); }
Puede descargar el código para obtener y agregar proyectos de GitHub y pegarlo en los marcadores de posición respectivos. No olvide agregar SQLiteStorageService.js a su archivo index.html arriba de Controller.js e inicialícelo en su controlador modificando la función de inicio del controlador:
initialize: function() { self = this; new SQLiteStorageService().done(function(service) { self.storageService = service; self.bindEvents(); self.renderSearchView(); }).fail(function(error) { alert(error); }); }
Si echa un vistazo a service.addProject(), notará que hace una llamada al método navigator.geolocation.getCurrentPosition(). Cordova tiene un complemento de geolocalización que puede usar para obtener la ubicación actual del teléfono, e incluso puede usar el método navigator.geolocation.watchPosition() para recibir actualizaciones cuando cambia la posición del usuario.
Finalmente, agreguemos los identificadores de eventos del controlador para agregar y obtener proyectos de la base de datos:
renderPostView: function() { $('.tab-button').removeClass('active'); $('#post-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); $("#tab-content").load("./views/post-project-view.html", function(data) { $('#tab-content').find('#post-project-form').on('submit', self.postProject); }); }, postProject: function(e) { e.preventDefault(); var name = $('#project-name').val(); var description = $('#project-description').val(); var company = $('#company').val(); var addLocation = $('#include-location').is(':checked'); if (!name || !description || !company) { alert('Please fill in all fields'); return; } else { var result = self.storageService.addProject( name, company, description, addLocation); result.done(function() { alert('Project successfully added'); self.renderSearchView(); }).fail(function(error) { alert(error); }); } }, renderSearchView: function() { $('.tab-button').removeClass('active'); $('#search-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); var $projectTemplate = null; $("#tab-content").load("./views/search-project-view.html", function(data) { $('#addressSearch').on('click', function() { alert('Not implemented'); }); $projectTemplate = $('.project').remove(); var projects = self.storageService.getProjects().done(function(projects) { for(var idx in projects) { var $div = $projectTemplate.clone(); var project = projects[idx]; $div.find('.project-name').text(project.name); $div.find('.project-company').text(project.company); $div.find('.project-description').text(project.description); if (project.location) { var url = '<a target="_blank" href="https://www.google.com.au/maps/preview/@' + project.location.latitude + ',' + project.location.longitude + ',10z">Click to open map</a>'; $div.find('.project-location').html(url); } else { $div.find('.project-location').text("Not specified"); } $tab.append($div); } }).fail(function(error) { alert(error); }); }); }
Para agregar la consola y los complementos de diálogo, ejecute lo siguiente:
cordova plugin add org.apache.cordova.dialogs cordova plugin add org.apache.cordova.console
El complemento cordova.console lo ayudará en la depuración al habilitar la función console.log()
dentro de los emuladores.
Puede depurar fácilmente las aplicaciones de Android a través del depurador remoto de Chrome. Una vez que haya conectado su dispositivo, haga clic en el menú desplegable en la esquina superior derecha (debajo del botón X), expanda Más herramientas y haga clic en Inspeccionar dispositivos. Debería ver su dispositivo en la lista y debería poder abrir su consola de depuración.
Safari proporciona la misma funcionalidad para depurar aplicaciones de iOS que se ejecutan en un dispositivo o emulador conectado por USB. Simplemente habilite las Herramientas para desarrolladores en la pestaña Configuración de Safari > Avanzado.
El complemento cordova.dialogs habilita las notificaciones nativas. Una práctica común es redefinir el método windows.alert
usando la API cordova.dialogs de la siguiente manera:
overrideBrowserAlert: function() { if (navigator.notification) { // Override default HTML alert with native dialog window.alert = function (message) { navigator.notification.alert( message, // message null, // callback "Toptal", // title 'OK' // buttonName ); }; } }
La función overrideBrowserAlert
debe llamarse dentro del controlador de eventos deviceready
.
Ahora debería poder agregar nuevos proyectos y ver los existentes desde la base de datos. Si selecciona la casilla de verificación "Incluir ubicación", el dispositivo realizará una llamada a la API de geolocalización y agregará su ubicación actual al proyecto.
Agreguemos un toque final a la aplicación configurando un ícono y una pantalla de inicio. Agregue lo siguiente a su archivo config.xml
:
<platform name="android"> <icon src="www/img/logo.png" /> <splash src="www/img/logo.png" density="mdpi"/> <splash src="www/img/logo.png" density="hdpi"/> <splash src="www/img/logo.png" density="xhdpi"/> </platform>
Finalmente, coloque una imagen de logotipo en la carpeta www/img
.
Tu propia aplicación Cordova
Pasamos por los pasos básicos del desarrollo de la aplicación Apache Cordova y usamos nuestra propia arquitectura JavaScript y hoja de estilo CSS. Este tutorial de Cordova fue un intento de mostrar el potencial de Apache Cordova como un medio para desarrollar aplicaciones móviles usando tecnologías familiares, reduciendo tanto el tiempo de desarrollo como el esfuerzo requerido para construir múltiples aplicaciones para diferentes plataformas.
Sin embargo, al crear aplicaciones que entrarán en producción, se recomienda utilizar un marco existente. Además de estructurar su aplicación en una arquitectura predefinida, esto también podría proporcionarle un conjunto de componentes que ayudarán a que su aplicación se acerque más a la apariencia nativa. Algunos marcos que vale la pena mencionar son Ionic, Framework7, Weex, Ratchet, Kendo UI y Onsen UI. ¡La mejor de las suertes!