Usar paquetes de módulos con Firebase

Los paquetes de módulos de JavaScript pueden hacer muchas cosas, pero una de sus características más útiles es la capacidad de agregar y usar bibliotecas externas en su código base. Los paquetes de módulos leen las rutas de importación en su código y combinan (agrupan) el código específico de su aplicación con el código de su biblioteca importada.

A partir de la versión 9 y superiores, la API modular de JavaScript de Firebase está optimizada para funcionar con las funciones de optimización de los paquetes de módulos para reducir la cantidad de código de Firebase incluido en la compilación final.

import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth';

const firebaseApp = initializeApp({ /* config */ });
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => { /* check status */ });

/**
 * getRedirectResult is unused and should not be included in the code base.
 * In addition, there are many other functions within firebase/auth that are
 * not imported and therefore should not be included as well.
 */

Este proceso de eliminar código no utilizado de una biblioteca se conoce como sacudida de árboles. Eliminar este código manualmente llevaría mucho tiempo y sería propenso a errores, pero los paquetes de módulos pueden automatizar esta eliminación.

Hay muchos paquetes de módulos de alta calidad en el ecosistema de JavaScript. Esta guía se centra en cubrir el uso de Firebase con webpack , Rollup y esbuild .

Empezar

Esta guía requiere que tenga npm instalado en su entorno de desarrollo. npm se utiliza para instalar y administrar dependencias (bibliotecas). Para instalar npm, instale Node.js , que incluye npm automáticamente.

La mayoría de los desarrolladores están configurados correctamente una vez que han instalado Node.js. Sin embargo, existen problemas comunes con los que se encuentran muchos desarrolladores al configurar su entorno. Si encuentra algún error, asegúrese de que su entorno tenga la CLI npm y de que tenga configurados los permisos adecuados para no tener que instalar paquetes como administrador con el comando sudo .

package.json e instalando Firebase

Una vez que haya instalado npm, deberá crear un archivo package.json en la raíz de su proyecto local. Genere este archivo con el siguiente comando npm:

npm init

Esto lo llevará a través de un asistente para proporcionar la información necesaria. Una vez creado el archivo, tendrá un aspecto similar al siguiente:

{
  "name": "your-package-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {

  }
}

Este archivo es responsable de muchas cosas diferentes. Este es un archivo importante con el que debe familiarizarse si desea obtener más información sobre la agrupación de módulos y la creación de código JavaScript en general. La pieza importante de esta guía es el objeto "dependencies" . Este objeto contendrá un par clave-valor de la biblioteca que ha instalado y la versión que está utilizando.

La adición de dependencias se realiza mediante el comando npm install o npm i .

npm i firebase

Cuando ejecuta npm i firebase , el proceso de instalación actualizará package.json para incluir Firebase como una dependencia:

  "dependencies": {
    "firebase": "^9.0.0"
  },

La clave es el nombre de la biblioteca y el valor es la versión a utilizar. El valor de la versión es flexible y puede aceptar un rango de valores. Esto se conoce como versiones semánticas o semver. Para obtener más información sobre semver, consulte la guía de npm sobre versiones semánticas .

Carpetas de origen versus carpetas de compilación

El código que escribe es leído y procesado por un paquete de módulos y luego generado como un nuevo archivo o conjunto de archivos. Es importante separar estos dos tipos de archivos. El código que los paquetes de módulos leen y procesan se conoce como código "fuente". Los archivos que generan se conocen como código compilado o "dist" (distribución).

Una configuración común en las bases de código es almacenar el código fuente en una carpeta llamada src y el código creado en una carpeta llamada dist .

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js

En la estructura de archivos de ejemplo anterior, considere que index.js importa tanto animations.js como datalist.js . Cuando un paquete de módulos procesa el código fuente, producirá el archivo bundle.js en la carpeta dist . bundle.js es una combinación de los archivos en la carpeta src y también cualquier biblioteca que importe.

Si utiliza sistemas de control de código fuente como Git, es común ignorar la carpeta dist al almacenar este código en el repositorio principal.

Puntos de entrada

Todos los paquetes de módulos tienen el concepto de punto de entrada. Puedes pensar en tu aplicación como un árbol de archivos. Un archivo importa código de otro y así sucesivamente. Esto significa que un archivo será la raíz del árbol. Este archivo se conoce como punto de entrada.

Revisemos el ejemplo anterior de estructura de archivos.

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js
// src/index.js
import { animate } from './animations';
import { createList } from './datalist';

// This is not real code, but for example purposes only
const theList = createList('users/123/tasks');
theList.addEventListener('loaded', event => {
  animate(theList);
});

El archivo src/index.js se considera el punto de entrada porque comienza las importaciones de todo el código necesario para la aplicación. Los paquetes de módulos utilizan este archivo de punto de entrada para comenzar el proceso de agrupación.

Usando Firebase con paquete web

No se necesita ninguna configuración específica para las aplicaciones y el paquete web de Firebase. Esta sección cubre una configuración general del paquete web .

El primer paso es instalar webpack desde npm como dependencia de desarrollo.

npm i webpack webpack-cli -D

Cree un archivo en la raíz de su proyecto local llamado webpack.config.js y agregue el siguiente código.

const path = require('path');

module.exports = {
  // The entry point file described above
  entry: './src/index.js',
  // The location of the build folder described above
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  devtool: 'eval-source-map',
};

Luego asegúrese de tener Firebase instalado como una dependencia.

npm i firebase

Luego inicializa Firebase en tu código base. El siguiente código importa e inicializa Firebase en un archivo de punto de entrada y usa Firestore Lite para cargar un documento de "ciudad".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

El siguiente paso es agregar un script npm para ejecutar la compilación del paquete web. Abra el archivo package.json y agregue el siguiente par clave-valor al objeto "scripts" .

  "scripts": {
    "build": "webpack --mode=development"
  },

Para ejecutar el paquete web y generar la carpeta de compilación, ejecute el siguiente comando.

npm run build

Finalmente, verifique la carpeta de compilación dist . Debe contener un archivo llamado bundle.js que contenga la aplicación incluida y el código de dependencia.

Para obtener más información sobre cómo optimizar la compilación de su paquete web para producción, consulte su documentación oficial sobre la configuración de "modo" .

Usando Firebase con Rollup

No se necesita ninguna configuración específica para las aplicaciones de Firebase y el Rollup. Esta sección cubre una configuración general de Rollup.

El primer paso es instalar Rollup y un complemento utilizado para asignar importaciones a dependencias instaladas con npm.

npm i rollup @rollup/plugin-node-resolve -D

Cree un archivo en la raíz de su proyecto local llamado rollup.config.js y agregue el siguiente código.

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  // the entry point file described above
  input: 'src/index.js',
  // the output for the build folder described above
  output: {
    file: 'dist/bundle.js',
    // Optional and for development only. This provides the ability to
    // map the built code back to the original source format when debugging.
    sourcemap: 'inline',
    // Configure Rollup to convert your module code to a scoped function
    // that "immediate invokes". See the Rollup documentation for more
    // information: https://rollupjs.org/guide/en/#outputformat
    format: 'iife'
  },
  // Add the plugin to map import paths to dependencies
  // installed with npm
  plugins: [nodeResolve()]
};

Luego inicializa Firebase en tu código base. El siguiente código importa e inicializa Firebase en un archivo de punto de entrada y usa Firestore Lite para cargar un documento de "ciudad".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

El siguiente paso es agregar un script npm para ejecutar la compilación acumulada. Abra el archivo package.json y agregue el siguiente par clave-valor al objeto "scripts" .

  "scripts": {
    "build": "rollup -c rollup.config.js"
  },

Para ejecutar el resumen y generar la carpeta de compilación, ejecute el siguiente comando.

npm run build

Finalmente, verifique la carpeta de compilación dist . Debe contener un archivo llamado bundle.js que contenga la aplicación incluida y el código de dependencia.

Para obtener más información sobre cómo optimizar su compilación acumulativa para producción, consulte su documentación oficial sobre complementos para compilaciones de producción .

Usando Firebase con esbuild

No se necesita ninguna configuración específica para las aplicaciones de Firebase y esbuild. Esta sección cubre una configuración general de esbuild.

El primer paso es instalar esbuild como dependencia de desarrollo.

npm i esbuild -D

Cree un archivo en la raíz de su proyecto local llamado esbuild.config.js y agregue el siguiente código.

require('esbuild').build({
  // the entry point file described above
  entryPoints: ['src/index.js'],
  // the build folder location described above
  outfile: 'dist/bundle.js',
  bundle: true,
  // Replace with the browser versions you need to target
  target: ['chrome60', 'firefox60', 'safari11', 'edge20'],
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  sourcemap: 'inline',
}).catch(() => process.exit(1))

Luego inicializa Firebase en tu código base. El siguiente código importa e inicializa Firebase en un archivo de punto de entrada y usa Firestore Lite para cargar un documento de "ciudad".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

El siguiente paso es agregar un script npm para ejecutar esbuild. Abra el archivo package.json y agregue el siguiente par clave-valor al objeto "scripts" .

  "scripts": {
    "build": "node ./esbuild.config.js"
  },

Finalmente, verifique la carpeta de compilación dist . Debe contener un archivo llamado bundle.js que contenga la aplicación incluida y el código de dependencia.

Para obtener más información sobre la optimización de esbuild para producción, consulte su documentación oficial sobre minificación y otras optimizaciones .