En este post vamos a ver paso a paso como crear una aplicación móvil híbrida utilizando Apache Cordova y Vue.js 2.
Los pasos que verás a continuación, describen el proceso de configuración de una plataforma de desarrollo en la que podrás crear aplicaciones móviles híbridas utilizando Cordova + Vue.js 2
Esto incluye:
Instalación y configuración de Cordova + Webpack + Vue.js.
Vista previa de la aplicación en el navegador.
Hot / Live: Recarga tu aplicación en el navegador automáticamente al detectar nuevos cambios.
Ejecutar la aplicación en dispositivos móviles Android / iOS (Utilizaremos los emuladores respectivos).
Antes de empezar, debo definirles lo que es una aplicación móvil hibrida:
¿Qué es una aplicación móvil híbrida?
Las aplicaciones híbridas son aplicaciones móviles diseñadas en un lenguaje de programación web empleando tecnologías como HTML5, CSS y JavaScript, y que gracias a un framework (en nuestro caso Cordova), permite adaptar la vista de nuestra aplicación web a cualquier vista de un dispositivo móvil mediante un navegador empotrado ( WebView).
Adicionalmente, este framework ( Cordova), mediante plugins, nos permite acceder a los componentes nativos de los dispositivos tales como la cámara, GPS, Wifi, Acelerómetros, Libreta de Contactos, entre otros.
Lo interesante de todo esto es que cada día el look and feel de una aplicación híbrida es casi igual al de una nativa, esto gracias a que poco a poco esta tecnología ha ido madurando y haciendo que sea más fácil integrar estas aplicaciones en los dispositivos móviles.
Otro aspecto importante es que estas aplicaciones híbridas se distribuyen igual que una nativa, mediante los markets como Google Play Store y el App Store.
Y por último y no menos importante está el hecho de que las aplicaciones híbridas brindan ventajas notables frente a las nativas, algunas de estas son:
El costo de desarrollo es muchisimo inferior al de una aplicación nativa ya que el código se escribe una sola vez y es compilado hacia las distintas plataformas deseadas.
No se requiere de sólidos conocimientos nativos para cada plataforma ya que la curva de aprendizaje y de implementación es muy corta.
El mantenimiento de nuestras aplicaciones es muchisimo mas eficiente ya que solo tenemos que cambiar el código una sola vez y luego compilar hacia las distintas plataformas.
No se requiere conocimiento de lenguajes de programación natívos como Java (Android), Swift u Objective C (iOS), entre otros.
Pre-Requisitos
Para llevar a cabo este ejemplo, debemos tener instalado los siguientes pre-requisitos:
Sistema Operativo macOS — High Sierra 10.13.2
Node.js — v9.2.1-Ir a la web oficial para instalar Node.js
Apache Cordova — 8.0.0 — npm install -g cordova
Vue-CLI — 2.9.3 —
npm install-g vue-cli
Gradle — 4.5.1 — brew install gradle — ¿Cómo Instalar Homebrew?
Android SDK — brew tap caskroom/cask — brew cask install android-sdk
Android Platform Tools — brew cask install android-platform-tools
Xcode-xcode-select -install- Descargar Xcode
ios-deploy-npm install -g ios-deploy
Iniciando el proyecto con Cordova + Vue.js + Webpack
Antes de todo, debemos situarnos en el path donde deseamos que se cree nuestro proyecto.
- Creamos el proyeto Cordova:
# Creating a new cordova project.
cordova create mi-app-hibrida com.franciscougalde.apps
- Creamos el proyecto Vue.js + Webpack:
vue init webpack mi-app-hibrida
Vue te preguntará:
? Target directory exists. Continue? (Y/n) **Y**
A lo que debemos contestar “Y” para aceptar y continuar ya que el directorio fué creado y configurado previamente por el proyecto de cordova en el paso anterior.
Seguidamente, vue te pedirá información para configurar el proyecto, los datos que yo introduje son los siguientes:
? Target directory exists. Continue? **Yes**
? Project name **mi-app-hibrida**
? Project description **Mi Aplicación Móvil Hibrida con Cordova + Vue.js 2**
? Author **Francisco Ugalde**
? Vue build **standalone**
? Install vue-router? **Yes**
? Use ESLint to lint your code? **No**
? Set up unit tests **No**
? Setup e2e tests with Nightwatch? **No**
? Should we run `npm install` for you after the project has been created? (recommended) **npm**
vue-cli · Generated "mi-app-hibrida".
# Installing project dependencies ...
# ========================
Unir los procesos de “build” del proyecto Cordova y Vue.js-WebPack
El directorio ./www de tu proyecto Cordova debe lucir actualmente así:
www
├── css
│ └── index.css
├── img
│ └── logo.png
├── index.html
└── js
└── index.js
Lo primero que debemos hacer es eliminar el contenido de la carpeta ./www de Cordova, ya que construiremos este contenido con WebPack en su lugar.
Tendremos que eliminar el directorio ./www ya que este es el código que Cordova integrará en el dispositivo móvil.
cd mi-app-hibrida
sudo rm -r www/*
# Password: ************
Ahora debemos abrir el archivo de configuación de Webpack: ./config/index.js y actualiza los siguientes paths:
Cambia los paths de index y
**assestsRoot
** para apuntar al directorio ./www y así el código de nuestra aplicación se genere en la ruta ./www/dist antes de ser empaquetado en el dispositivo móvil.Cambia el valor del path de
**assetsPublicPath **para que sea una cadena vacía
. Esto va a permitir a tu móvil servir la vista vía el protocolo file:///. Esto es importante puesto que no estaremos ejecutando un servidor web en nuestro dispositivo móvil (usualmente).
Actualiza tu ./config/index.js para que luzca de la siguiente manera:
build: {
// Template for index.html
index: path.resolve(__dirname, '../www/dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../www/dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '',
}
Abre el archivo config.xml en tu IDE preferido y actializa el punto de entrada del WebView de Cordova.
<content src=”dist/index.html” />
Ahora procedemos a crear el paquete de distribución de nuestra aplicación:
npm run build
mi-app-hibrida@1.0.0 build /Users/fjugaldev/Sites/mi-app-hibrida
node build/build.js
Hash: 0faab7ddba58ce23a830
Version: webpack 3.11.0
Time: 16236ms
Asset Size Chunks Chunk Names
static/js/vendor.5973cf24864eecc78c48.js 111 kB 0 [emitted] vendor
static/js/app.b22ce679862c47a75225.js 11.6 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest
static/css/app.30790115300ab27614ce176899523b62.css 432 bytes 1 [emitted] app
static/css/app.30790115300ab27614ce176899523b62.css.map 828 bytes [emitted]
static/js/vendor.5973cf24864eecc78c48.js.map 548 kB 0 [emitted] vendor
static/js/app.b22ce679862c47a75225.js.map 22.2 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest
index.html 516 bytes [emitted]
Build complete.
Tip: built files are meant to be served over an HTTP server.
Opening index.html over file:// won't work.
El directorio ./www/dist
debe lucir ahora algo parecido a esto:
www
└── dist
├── index.html
└── static
├── css
│ ├── app.30790115300ab27614ce176899523b62.css
│ └── app.30790115300ab27614ce176899523b62.css.map
└── js
├── app.b22ce679862c47a75225.js|
├── app.b22ce679862c47a75225.js.map
├── manifest.2ae2e69a05c33dfc65f8.js
├── manifest.2ae2e69a05c33dfc65f8.js.map
├── vendor.5973cf24864eecc78c48.js
└── vendor.5973cf24864eecc78c48.js.map
Abre el archivo **./www/dist/index.html
** en tu navegador para verificar que todo funciona perfectamente vía el protocolo file:///.
open ./www/dist/index.html
Puedes notar en la barra de dirección el protocolo file:///
Seguidamente debemos abrir el archivo ./index.html de Vue.js en tu IDE y actualiza el meta tag “Content-Security-Policy” para permitir los sockets web locales. Puedes hacer esto agregando: connect-src ‘self’ ws:;. Esto permitirá a Webpack conocer cuando se ha creado el paquete de distribución de la aplicación y cuando se ha recargado o actualizado el codigo en la vista previa del navegador. Esto deberá suceder cada vez que hagas un cambio en el codigo fuente.
<meta http-equiv=”Content-Security-Policy” content=”default-src ‘self’ data: gap: <a href="[https://ssl.gstatic.com/](https://ssl.gstatic.com/)" target="_blank" rel="nofollow noopener noopener" data-href="[https://ssl.gstatic.com](https://ssl.gstatic.com)" data-mce-href="[https://ssl.gstatic.com/](https://ssl.gstatic.com/)">[https://ssl.gstatic.com](https://ssl.gstatic.com)</a> ‘unsafe-eval’; style-src ‘self’ ‘unsafe-inline’; media-src *; img-src ‘self’ data: content:; connect-src ‘self’ ws:;”>
Ahora podemos probar que el modo dev funciona correctamente:
npm run dev
mi-app-hibrida@1.0.0 dev /Users/fjugaldev/Sites/mi-app-hibrida
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
95% emitting
DONE Compiled successfully in 8968ms 1:37:22 AM
I Your application is running here: http://localhost:8080
Ahora el Servidor hot-reload de Vue-Webpack esta online, Entra en http://localhost:8080 para ver la aplicación.
Deberas ver la siguiente pantalla:
Nótese el mensaje de web-sockets en el log de la consola, y el host:puerto en la barra de direcciones del navegador.
Ejecutando la aplicación en Android
Vamos ahora a probar que todo funciona en un dispositivo móvil Android. Asegurate que tienes conectado uno en tu computador.
Procedemos a agregar a Android como plataforma en Cordova:
cordova platform add android
Using cordova-fetch for cordova-android@~7.0.0
Adding android project...
Creating Cordova project for the Android platform:
Path: platforms/android
Package: com.franciscougalde.apps
Name: HelloCordova
Activity: MainActivity
Android target: android-26
Subproject Path: CordovaLib
Subproject Path: app
Android project created with cordova-android@7.0.0
Android Studio project detected
Android Studio project detected
Discovered plugin "cordova-plugin-whitelist" in config.xml. Adding it to the project
Installing "cordova-plugin-whitelist" for android
This plugin is only applicable for versions of cordova-android greater than 4.0. If you have a previous platform version, you do *not* need this plugin since the whitelist will be built in.
Adding cordova-plugin-whitelist to package.json
Saved plugin info for "cordova-plugin-whitelist" to config.xml
--save flag or autosave detected
Saving android@~7.0.0 into config.xml file ...
Luego de esto procedemos a ejecutar la aplicación en nuestro dispositivo Android:
cordova run android
Android Studio project detected
ANDROID_HOME=/usr/local/Caskroom/android-sdk/3859397
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
studio
Subproject Path: CordovaLib
Subproject Path: app
publishNonDefault is deprecated and has no effect anymore. All variants are now published.
The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
at build_8u9efqela5ohwabjwm0tr50nm.run(/Users/fjugaldev/Sites/mi-app-hibrida/platforms/android/app/build.gradle:143)
:CordovaLib:preBuild UP-TO-DATE
:CordovaLib:preDebugBuild UP-TO-DATE
:CordovaLib:compileDebugAidl UP-TO-DATE
:CordovaLib:compileDebugRenderscript UP-TO-DATE
:CordovaLib:checkDebugManifest UP-TO-DATE
:CordovaLib:generateDebugBuildConfig UP-TO-DATE
:CordovaLib:prepareLintJar UP-TO-DATE
:CordovaLib:generateDebugResValues UP-TO-DATE
:CordovaLib:generateDebugResources UP-TO-DATE
:CordovaLib:packageDebugResources UP-TO-DATE
:CordovaLib:platformAttrExtractor UP-TO-DATE
:CordovaLib:processDebugManifest UP-TO-DATE
:CordovaLib:processDebugResources UP-TO-DATE
:CordovaLib:generateDebugSources UP-TO-DATE
:CordovaLib:javaPreCompileDebug UP-TO-DATE
:CordovaLib:compileDebugJavaWithJavac UP-TO-DATE
:CordovaLib:processDebugJavaRes NO-SOURCE
:CordovaLib:transformClassesAndResourcesWithPrepareIntermediateJarsForDebug UP-TO-DATE
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:compileDebugAidl UP-TO-DATE
:CordovaLib:packageDebugRenderscript NO-SOURCE
:app:compileDebugRenderscript UP-TO-DATE
:app:checkDebugManifest UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:prepareLintJar UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:createDebugCompatibleScreenManifests UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:splitsDiscoveryTaskDebug UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:javaPreCompileDebug UP-TO-DATE
:app:compileDebugJavaWithJavac UP-TO-DATE
:app:compileDebugNdk NO-SOURCE
:app:compileDebugSources UP-TO-DATE
:CordovaLib:mergeDebugShaders UP-TO-DATE
:CordovaLib:compileDebugShaders UP-TO-DATE
:CordovaLib:generateDebugAssets UP-TO-DATE
:CordovaLib:mergeDebugAssets UP-TO-DATE
:app:mergeDebugShaders UP-TO-DATE
:app:compileDebugShaders UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:extractTryWithResourcesSupportJarDebug UP-TO-DATE
:app:transformClassesWithStackFramesFixerForDebug UP-TO-DATE
:app:transformClassesWithDesugarForDebug UP-TO-DATE
:app:transformClassesWithDexBuilderForDebug UP-TO-DATE
:app:transformDexArchiveWithExternalLibsDexMergerForDebug UP-TO-DATE
:app:transformDexArchiveWithDexMergerForDebug UP-TO-DATE
:CordovaLib:compileDebugNdk NO-SOURCE
:CordovaLib:mergeDebugJniLibFolders UP-TO-DATE
:CordovaLib:transformNativeLibsWithMergeJniLibsForDebug UP-TO-DATE
:CordovaLib:transformNativeLibsWithIntermediateJniLibsForDebug UP-TO-DATE
:app:mergeDebugJniLibFolders UP-TO-DATE
:app:transformNativeLibsWithMergeJniLibsForDebug UP-TO-DATE
:app:processDebugJavaRes NO-SOURCE
:app:transformResourcesWithMergeJavaResForDebug UP-TO-DATE
:app:validateSigningDebug
:app:packageDebug UP-TO-DATE
:app:assembleDebug UP-TO-DATE
:app:cdvBuildDebug UP-TO-DATE
BUILD SUCCESSFUL in 2s
47 actionable tasks: 1 executed, 46 up-to-date
Built the following apk(s):
/Users/fjugaldev/Sites/mi-app-hibrida/platforms/android/app/build/outputs/apk/debug/app-debug.apk
ANDROID_HOME=/usr/local/Caskroom/android-sdk/3859397
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
No target specified, deploying to device '634034256815'.
none
Skipping build...
Built the following apk(s):
/Users/fjugaldev/Sites/mi-app-hibrida/platforms/android/app/build/outputs/apk/debug/app-debug.apk
Using apk: /Users/fjugaldev/Sites/mi-app-hibrida/platforms/android/app/build/outputs/apk/debug/app-debug.apk
Package name: com.franciscougalde.apps
LAUNCH SUCCESS
Luego de esto deberás ver la aplicación corriendo en tu dispositivo Android.
Ejecutando la aplicación en iOS
Es tiempo de verificar cosas en un dispositivo iOS. Asegúrate de que lo hayas conectado a tu computador.
Primero, Agreguemos la plataforma iOS a nuestro proyecto Cordova:
cordova platform add ios
Using cordova-fetch for cordova-ios@~4.5.4
Adding ios project...
Creating Cordova project for the iOS platform:
Path: platforms/ios
Package: com.franciscougalde.apps
Name: HelloCordova
iOS project created with cordova-ios@4.5.4
Installing "cordova-plugin-whitelist" for ios
--save flag or autosave detected
Saving ios@~4.5.4 into config.xml file ...
Abre el proyecto de nuestra aplicación en el Xcode ejecutando lo siguiente:
Lo siguiente será seleccionar el certificado de Equipo (Team certificate) en el menú desplegable “Build Signing”.
Crear el paquete para iOS.
cordova build ios
Building project: /Users/fjugaldev/Sites/mi-app-hibrida/platforms/ios/HelloCordova.xcworkspace
Configuration: Debug
Platform: device
User defaults from command line:
IDEArchivePathOverride = /Users/fjugaldev/Sites/mi-app-hibrida/platforms/ios/HelloCordova.xcarchive
Build settings from command line:
CONFIGURATION_BUILD_DIR = /Users/fjugaldev/Sites/mi-app-hibrida/platforms/ios/build/device
SHARED_PRECOMPS_DIR = /Users/fjugaldev/Sites/mi-app-hibrida/platforms/ios/build/sharedpch
Build settings from configuration file '/Users/fjugaldev/Sites/mi-app-hibrida/platforms/ios/cordova/build-debug.xcconfig':
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
CODE_SIGN_ENTITLEMENTS = $(PROJECT_DIR)/$(PROJECT_NAME)/Entitlements-$(CONFIGURATION).plist
CODE_SIGN_IDENTITY = iPhone Developer
ENABLE_BITCODE = NO
GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1
HEADER_SEARCH_PATHS = "$(TARGET_BUILD_DIR)/usr/local/lib/include" "$(OBJROOT)/UninstalledProducts/include" "$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include" "$(BUILT_PRODUCTS_DIR)"
OTHER_LDFLAGS = -ObjC
SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h
=== BUILD TARGET CordovaLib OF PROJECT CordovaLib WITH CONFIGURATION Debug ===
Check dependencies
Write auxiliary files
...
** ARCHIVE SUCCEEDED **
Non-system Ruby in use. This may cause packaging to fail.
If you use RVM, please run `rvm use system`.
If you use chruby, please run `chruby system`.
2018-02-01 16:43:32.249 xcodebuild[82807:848721] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path '/var/folders/kw/5t8w91_n6rb0z8b2z2grsj1r0000gn/T/HelloCordova_2018-02-01_16-43-32.247.xcdistributionlogs'.
Exported HelloCordova.xcarchive to: /Users/fjugaldev/Sites/mi-app-hibrida/platforms/ios/build/device
** EXPORT SUCCEEDED **
Procedemos a ejecutar la aplicación en nuestro dispositivo iOS:
cordova run ios
Deberías poder ver la aplicación Vue.js en tu dispositivo iOS tal como se muestra a continuación:
Y ya con esto hemos logrado entonces combinar dos tecnologías ideales para el desarrollo de aplicaciones móviles híbridas de una forma sencilla y que estoy seguro que a muchos de ustedes les va a servir para iniciarse en este mundo de las aplicaciones móviles.
Si gustas revisar el código resultante de nuestra aplicación de ejemplo, puedes clonarlo desde mi repositorio en github.com
Si te gustó este post, ayúdame a que pueda servirle a muchas más personas, compartiendo mis contenidos en tus redes sociales.
Espero que este post haya sido de gran ayuda para ti, y como siempre, cualquier inquietud o duda que tengas, puedes contactarme por cualquiera de las vías disponibles, o dejando tus comentarios al final de este post. También puedes sugerir que temas o post te gustaría leer a futuro.