Cuando se configura un nuevo proyecto angular, es necesario instalar todos los paquetes npm necesarios para ejecutar el proyecto y, a partir de este punto, comienzas a trabajar en la implementación de tu proyecto. Tarde o temprano te encuentras algún problema que requiere una codificación especial, por lo que recurres a Google y busca una respuesta, probablemente un paquete. Lo instalas y compilas el proyecto. Luego miras su tamaño y ... así es como te da un infarto. ¿Cómo terminé con 15 MB node_modules?
Al contrario de lo que puede pensar un programador primerizo, el tamaño de la aplicación es importante por lo siguiente:
Es cierto, y yo soy un ejemplo, que a los desarrolladores nos gusta simplificar nuestro trabajo y, en muchas ocasiones, esto supone importar bibliotecas externas a nuestros proyectos. Desafortunadamente, realizar estas operativas supone aumentar el tamaño de nuestra web Angular y, en las ocasiones más radicales, puede salirse de control.
¿Cómo solucionarlo? Actualmente, la mejor forma de conseguir disminuir el tamaño de tu aplicación Angular es a través de la librería webpack-bundle-analyzer. Este plugin permite analizar qué dependencias componen nuestros bundles al detalle.
Esta aplicación despliega una gráfica interactiva con el resultado de nuestro bundle, qué dependencias contiene , cuánto pesan y cómo se distribuyen.
Dicho esto, para instalar la libreria aplica el siguiente comando:
npm install --save-dev webpack-bundle-analyzer
Una vez instalado, en el momento que compilamos el proyecto, tenemos que añadir la siguiente opción --stats-json de forma que quede algo tal que así:
ng build --configuration production --aot --vendor-chunk --common-chunk --delete-output-path --build-optimizer --stats-json
Automáticamente se genera un fichero stats.json.
El siguiente paso seria ejecutar el siguiente comando, dónde path_to_stats_file es la ruta al fichero.
webpack-bundle-analyzer path_to_stats_file/stats.json
El resultado es el siguiente mapa de calor: Las aplicaciones que actualmente usan Firebase Web SDK versión 8 o anterior tiene una cosa en común, un fichero node_modules de tamaño desmesurado como el que se puede observar a continuación:
Es decir, el rendimiento y la eficiencia de vuestra aplicación web se verá mermado por la utilización de está librería tan pesada. Para evitar estos problemas, los desarrolladores de google han implementado una nueva versión (9) muy adaptada a entornos dónde la eficiencia y el tamaño reducido son necesarios. Dicho esto, en este punto vamos a exponer qué procedimientos hay que llevar a cabo para realizar una migración a esta nueva versión.
npm i firebase@exp
Una vez realizado, elimina de src/app/app.module.ts los siguientes módulos AngularFireDatabaseModule,
DeviceDetectorModule.forRoot(),
AngularFireModule.initializeApp(environment.firebase),
AngularFirestoreModule,
AngularFireAuthModule
Un pequeño detalle, en este ejemplo he almacenado la credenciales de acceso al entorno firebase en el fichero src/environments/environments.prod.ts con la siguiente estructura: export const environment = {
production: false,
firebase: {
apiKey: '',
authDomain: '',
databaseURL: '',
projectId: '',
storageBucket: '',
messagingSenderId: '',
appId: '',
measurementId: ''
}
};
import { Injectable } from '@angular/core';
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";
import { getDatabase, ref, child, get } from "firebase/database";
import {environment} from "../environments/environment";
import { initializeApp } from "firebase/app"
Una vez realizada la modificación, vamos a poner algunos ejemplos. Empezaremos con el ejemplo en login en firebase 7 utilizando un usuario y contraseña:
doLogin() {
return new Promise<any>((resolve, reject) => {
firebase.auth().signInWithEmailAndPassword('correo', 'Pass')
.then(res => {
resolve(res);
}, err => reject(err))
})
}
Su correspondiente en la versión 9 es:
doLogin(): Promise<Boolean> {
const firebaseApp = initializeApp(environment.firebase);
const auth = getAuth(firebaseApp);
return signInWithEmailAndPassword(auth, 'correo', 'pass')
.then((userCredential) => {
// Signed in
return true
})
.catch((error) => {
return false
});
}
getEvolutionLife() {
return this.db2.list('/esperanza_vida').valueChanges()
}
Para la versión 9, simplemente hay que aplicar el siguiente código: obtener_base_de_datos_realtime(): Promise<Array<any>>{
const dbRef = ref(getDatabase());
return get(child(dbRef, 'esperanza_vida')).then((snapshot) => {
let result = []
snapshot.forEach((doc) => {
result.push(doc.toJSON()) //en caso de objetos json.
});
return result
}).catch((error) => {
return []
});
}
Si utilizamos fire cloud, el código necesario sería el siguiente getProyectos() {
return this.db.collection('proyecto').snapshotChanges();
}
Y en su versión 9 corresponde al siguiente código. async obtener_colleccion() {
const firebaseApp = initializeApp(environment.firebase);
const db = getFirestore(firebaseApp);
const q = query(collection(db, "proyecto"));
let array = []
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
array.push( doc.data())
});
return array
}
Para terminar, os expongo un ejemplo de comunicación con firebase. En este ejemplo invocamos el método obtener_base_de_datos_realtime() de forma síncrona. Para realizar esta tarea, en el mismo código invocamos el método then y finally de la siguiente forma: this.graficaListData.obtener_base_de_datos_realtime().then(
tratados => {
for (let i = 0; i < tratados.length; i++) {
this.tratados.push(<Tratados>tratados[i]);
}
}
, error => this.errorMessage = <any>error);