Como unir AngularJS y Cordova para generar aplicaciones móviles (parte 1)
By ercobo | Published | 1 comentario
Si que hace tiempo que no escribía…
Bueno, hoy vuelvo con un pequeño tutorial en castellano sobre como conseguir un proyecto Cordova (https://cordova.apache.org/) que podamos utilizar con los componentes de angular. Se que hay tutoriales muy buenos por ahi (de hecho así lo conseguí yo) pero os voy a contar mi experiencia. La mayoría de los tutoriales que encontraba son para frameworks como Ionic, React, NativeScript… pero no encontraba una formula sencilla de como conseguir lograrlo solo con Cordova y Angular. Así que aquí os cuento mi pequeña peripecia.
Basándome en éste artículo (https://medium.com/@nacojohn/convert-your-angular-project-to-mobile-app-using-cordova-f0384a7711a6) conseguí hacerlo funcionar. Os voy contando los pasos.
Creación de los proyectos.
Lo primero es tener Angular, Cordova y las herramientas necesarias. No me extenderé, pero básicamente es seguir los pasos de aqui, aqui y aqui.
Como siempre, os voy a contar mi experiencia, puede que a alguno los pasos que sigo no le parezcan lógicos o los haga de otra manera.
Bien, vamos a partir del caso de que queremos crear una aplicación nueva (después abordaré el caso de una migración)
Lo primero será crear los dos proyectos (uno para cordova y otro para angular), así que en una carpeta que vamos a utilizar temporalmente como mezclador creamos los dos proyectos.
1 |
[crayon-674f78ef4b00d732156020 ]cordova create proyecto com.example.hello NombreProyecto |
Con este comando creamos el proyecto de cordova. Sus particularidades son:
El primer parámetro «proyecto» es el nombre de la carpeta donde se creara el proyecto de Cordova.
El segundo parámetro «com.example.hello» es el identificador de nuestra app (un identificador para distinguirla en los dispositivos y stores)
El tercer parámetro «NombreProyecto» es el nombre que se le dará internamente a la aplicación.
1 |
ng new PROYECTO_ANGULAR |
Con este comando generamos el proyecto de Angular, unicamente le damos el nombre de la carpeta donde se va a crear.
Uniendo Angular y Cordova.
Bien, ahora es cuando comenzamos la magia.
Lo primero será unir los dos proyectos en una carpeta. Para ello, al menos en mi caso, lo más sencillo es coger todos los archivos del proyecto de angular, salvo las carpetas node_module, dist, y los archivos package.json y package.json.lock. Estos últimos efectuaremos una unión «manual».
Así que, en la carpeta del proyecto cordova, que tendrá un aspecto parecido a este:
1 2 3 4 5 6 7 |
-rwxrwxrwx config.xml drwxrwxrwx hooks -rwxrwxrwx package.json drwxrwxrwx platforms drwxrwxrwx plugins drwxrwxrwx res drwxrwxrwx www |
Copiamos todos los archivos del proyecto angular menos los comentados (los marco los que no hay que copiar):
1 2 3 4 5 6 7 8 9 |
-rwxrwxrwx angular.json drwxrwxrwx e2e drwxrwxrwx node_modules -> Este NO -rwxrwxrwx package.json -> Este NO -rwxrwxrwx package-lock.json -> Este NO -rwxrwxrwx README.md drwxrwxrwx src -rwxrwxrwx tsconfig.json -rwxrwxrwx tslint.json |
Y acabaremos con algo así:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-rwxrwxrwx angular.json -rwxrwxrwx config.xml drwxrwxrwx e2e drwxrwxrwx hooks -rwxrwxrwx package.json drwxrwxrwx platforms drwxrwxrwx plugins -rwxrwxrwx README.md drwxrwxrwx res drwxrwxrwx src -rwxrwxrwx tsconfig.json -rwxrwxrwx tslint.json drwxrwxrwx www |
Vale, ahora continuemos.
Cordova utiliza la carpeta «www» para obtener los archivos html, javascript, css, etc… que después traspasa a las diferentes plataformas (android, ios…). Así que nuestra misión es hacer que cuando Angular compile los archivos los haga en esta carpeta. Por defecto genera una carpeta «dist», pero esa configuración está en el archivo «angular.json», así que entramos a editarlo y debería quedar algo parecido a lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "proyecto": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "app", "schematics": {}, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "www", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.css" ], "scripts": [] }, "configurations": { "production": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "optimization": true, "outputHashing": "all", "sourceMap": false, "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true } } }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "proyecto:build" }, "configurations": { "production": { "browserTarget": "proyecto:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "proyecto:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.spec.json", "karmaConfig": "src/karma.conf.js", "styles": [ "src/styles.css" ], "scripts": [], "assets": [ "src/favicon.ico", "src/assets" ] } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": [ "src/tsconfig.app.json", "src/tsconfig.spec.json" ], "exclude": [ "/node_modules/" ] } } } }, "proyecto-e2e": { "root": "e2e/", "projectType": "application", "architect": { "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { "protractorConfig": "e2e/protractor.conf.js", "devServerTarget": "proyecto:serve" }, "configurations": { "production": { "devServerTarget": "proyecto:serve:production" } } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": "e2e/tsconfig.e2e.json", "exclude": [ "/node_modules/" ] } } } } }, "defaultProject": "proyecto" } |
Como podeis ver, hemos referenciado todo lo que antes dijera «PROYECTO_ANGULAR» por «proyecto» (el nombre de la carpeta donde está cordova)
Ahora es el momento de combinar los dos package.json. El de Cordova es como el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "name": "com.example.hello", "displayName": "HelloWorld", "version": "1.0.0", "description": "A sample Apache Cordova application that responds to the deviceready event.", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Apache Cordova Team", "license": "Apache-2.0" } |
Y el de Angular es como este:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
{ "name": "angularbase", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^6.1.0", "@angular/common": "^6.1.0", "@angular/compiler": "^6.1.0", "@angular/core": "^6.1.0", "@angular/forms": "^6.1.0", "@angular/http": "^6.1.0", "@angular/platform-browser": "^6.1.0", "@angular/platform-browser-dynamic": "^6.1.0", "@angular/router": "^6.1.0", "core-js": "^2.5.4", "rxjs": "^6.0.0", "zone.js": "~0.8.26" }, "devDependencies": { "@angular-devkit/build-angular": "~0.7.0", "@angular/cli": "~6.1.5", "@angular/compiler-cli": "^6.1.0", "@angular/language-service": "^6.1.0", "@types/jasmine": "~2.8.6", "@types/jasminewd2": "~2.0.3", "@types/node": "~8.9.4", "codelyzer": "~4.2.1", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", "karma": "~1.7.1", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "~2.0.0", "karma-jasmine": "~1.1.1", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.4.0", "ts-node": "~5.0.1", "tslint": "~5.9.1", "typescript": "~2.7.2" } } |
Al final debería quedar algo similar a lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
{ "name": "com.example.hello", "displayName": "HelloWorld", "version": "1.0.0", "description": "A sample Apache Cordova application that responds to the deviceready event.", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Apache Cordova Team", "license": "Apache-2.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^6.1.0", "@angular/common": "^6.1.0", "@angular/compiler": "^6.1.0", "@angular/core": "^6.1.0", "@angular/forms": "^6.1.0", "@angular/http": "^6.1.0", "@angular/platform-browser": "^6.1.0", "@angular/platform-browser-dynamic": "^6.1.0", "@angular/router": "^6.1.0", "core-js": "^2.5.4", "rxjs": "^6.0.0", "zone.js": "~0.8.26" }, "devDependencies": { "@angular-devkit/build-angular": "~0.7.0", "@angular/cli": "~6.1.5", "@angular/compiler-cli": "^6.1.0", "@angular/language-service": "^6.1.0", "@types/jasmine": "~2.8.6", "@types/jasminewd2": "~2.0.3", "@types/node": "~8.9.4", "codelyzer": "~4.2.1", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", "karma": "~1.7.1", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "~2.0.0", "karma-jasmine": "~1.1.1", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.4.0", "ts-node": "~5.0.1", "tslint": "~5.9.1", "typescript": "~2.7.2" } } |
Y con esto ya tendriamos unidos los dos frameworks para poder trabajar.
Como me está quedando un poco largo, voy a divir el artículo en dos. En la siguiente parte efectuaremos la instalación de todas las dependencias y las pequeñas modificaciones que hay que hacer para que Angular acepte los eventos de Cordova.
Hasta pronto!
1 Response
[…] de Como unir AngularJS y Cordova para generar aplicaciones móviles (parte 1) y vamos a continuar donde lo […]