Utiliser des bundles de modules avec Firebase

Les bundlers de modules JavaScript peuvent faire beaucoup de choses, mais l'une de leurs fonctionnalités les plus utiles est la possibilité d'ajouter et d'utiliser des bibliothèques externes dans votre base de code. Les bundlers de modules lisent les chemins d'importation dans votre code et combinent (groupent) votre code spécifique à l'application avec votre code de bibliothèque importé.

À partir de la version 9 et des versions ultérieures, l'API modulaire Firebase JavaScript est optimisée pour fonctionner avec les fonctionnalités d'optimisation des bundles de modules afin de réduire la quantité de code Firebase incluse dans votre version finale.

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.
 */

Ce processus d'élimination du code inutilisé d'une bibliothèque est connu sous le nom de tree shaking. Il serait extrêmement long et sujet aux erreurs de supprimer manuellement ce code, mais les bundlers de modules peuvent automatiser cette suppression.

Il existe de nombreux bundlers de modules de haute qualité dans l'écosystème JavaScript. Ce guide se concentre sur l'utilisation de Firebase avec webpack , Rollup et esbuild .

Commencer

Ce guide nécessite que vous ayez installé npm dans votre environnement de développement. npm est utilisé pour installer et gérer les dépendances (bibliothèques). Pour installer npm, installez Node.js , qui inclut automatiquement npm.

La plupart des développeurs sont correctement configurés une fois qu'ils ont installé Node.js. Cependant, de nombreux développeurs rencontrent des problèmes courants lors de la configuration de leur environnement. Si vous rencontrez des erreurs, assurez-vous que votre environnement dispose de l'interface de ligne de commande npm et que vous disposez des autorisations appropriées pour ne pas avoir à installer de packages en tant qu'administrateur avec la commande sudo .

package.json et installation de Firebase

Une fois que vous avez installé npm, vous devrez créer un fichier package.json à la racine de votre projet local. Générez ce fichier avec la commande npm suivante :

npm init

Cela vous guidera à travers un assistant pour fournir les informations nécessaires. Une fois le fichier créé, il ressemblera à ce qui suit :

{
  "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": {

  }
}

Ce fichier est responsable de beaucoup de choses différentes. Il s'agit d'un fichier important avec lequel vous devez vous familiariser si vous souhaitez en savoir plus sur le regroupement de modules et la création de code JavaScript en général. La pièce importante pour ce guide est l'objet "dependencies" . Cet objet contiendra une paire clé-valeur de la bibliothèque que vous avez installée et de la version qu'elle utilise.

L'ajout de dépendances se fait via la commande npm install ou npm i .

npm i firebase

Lorsque vous exécutez npm i firebase , le processus d'installation met à jour package.json pour répertorier Firebase en tant que dépendance :

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

La clé est le nom de la bibliothèque et la valeur est la version à utiliser. La valeur de version est flexible et peut accepter une plage de valeurs. C'est ce qu'on appelle le versioning sémantique ou semver. Pour en savoir plus sur semver, consultez le guide de npm sur la gestion sémantique des versions .

Dossiers source vs build

Le code que vous écrivez est lu et traité par un groupeur de modules, puis sorti sous la forme d'un nouveau fichier ou d'un ensemble de fichiers. Il est important de séparer ces deux types de fichiers. Le code que les bundlers de modules lisent et traitent est appelé code "source". Les fichiers qu'ils génèrent sont connus sous le nom de code construit ou "dist" (distribution).

Une configuration courante dans les bases de code consiste à stocker le code source dans un dossier appelé src et le code construit dans un dossier nommé dist .

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


- dist
 |_ bundle.js

Dans l'exemple de structure de fichier ci-dessus, considérez que index.js importe à la fois animations.js et datalist.js . Lorsqu'un module bundler traite le code source, il produit le fichier bundle.js dans le dossier dist . Le bundle.js est une combinaison des fichiers du dossier src et de toutes les bibliothèques importées également.

Si vous utilisez des systèmes de contrôle de source tels que Git, il est courant d'ignorer le dossier dist lors du stockage de ce code dans le référentiel principal.

Points d'entrée

Les bundlers de modules ont tous un concept de point d'entrée. Vous pouvez considérer votre application comme une arborescence de fichiers. Un fichier importe le code d'un autre et ainsi de suite. Cela signifie qu'un fichier sera la racine de l'arborescence. Ce fichier est appelé point d'entrée.

Reprenons l'exemple de structure de fichier précédent.

- 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);
});

Le fichier src/index.js est considéré comme le point d'entrée car il commence les importations de tout le code nécessaire à l'application. Ce fichier de point d'entrée est utilisé par les bundlers de modules pour commencer le processus de regroupement.

Utilisation de Firebase avec Webpack

Aucune configuration spécifique n'est nécessaire pour les applications Firebase et Webpack. Cette section couvre une configuration générale de webpack .

La première étape consiste à installer webpack à partir de npm en tant que dépendance de développement.

npm i webpack webpack-cli -D

Créez un fichier à la racine de votre projet local nommé webpack.config.js et ajoutez le code suivant.

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',
};

Assurez-vous ensuite que Firebase est installé en tant que dépendance.

npm i firebase

Initialisez ensuite Firebase dans votre base de code. Le code suivant importe et initialise Firebase dans un fichier de point d'entrée et utilise Firestore Lite pour charger un document "ville".

// 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(),
  };
}

L'étape suivante consiste à ajouter un script npm pour exécuter la construction du webpack. Ouvrez le fichier package.json et ajoutez la paire clé-valeur suivante à l'objet "scripts" .

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

Pour exécuter webpack et générer le dossier de construction, exécutez la commande suivante.

npm run build

Enfin, vérifiez le dossier de construction dist . Il doit contenir un fichier nommé bundle.js qui contient votre application groupée et le code de dépendance.

Pour plus d'informations sur l'optimisation de votre build de webpack pour la production, consultez leur documentation officielle sur le paramètre de configuration "mode" .

Utilisation de Firebase avec Rollup

Aucune configuration spécifique n'est nécessaire pour les applications Firebase et Rollup. Cette section couvre une configuration générale de cumul.

La première étape consiste à installer Rollup et un plugin utilisé pour mapper les importations aux dépendances installées avec npm.

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

Créez un fichier à la racine de votre projet local nommé rollup.config.js et ajoutez le code suivant.

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()]
};

Initialisez ensuite Firebase dans votre base de code. Le code suivant importe et initialise Firebase dans un fichier de point d'entrée et utilise Firestore Lite pour charger un document "ville".

// 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(),
  };
}

L'étape suivante consiste à ajouter un script npm pour exécuter la construction du cumul. Ouvrez le fichier package.json et ajoutez la paire clé-valeur suivante à l'objet "scripts" .

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

Pour exécuter le cumul et générer le dossier de génération, exécutez la commande suivante.

npm run build

Enfin, vérifiez le dossier de construction dist . Il doit contenir un fichier nommé bundle.js qui contient votre application groupée et le code de dépendance.

Pour plus d'informations sur l'optimisation de votre build Rollup pour la production, consultez leur documentation officielle sur les plugins pour les builds de production .

Utiliser Firebase avec esbuild

Aucune configuration spécifique n'est nécessaire pour les applications Firebase et esbuild. Cette section couvre une configuration générale d'esbuild.

La première étape consiste à installer esbuild en tant que dépendance de développement.

npm i esbuild -D

Créez un fichier à la racine de votre projet local nommé esbuild.config.js et ajoutez le code suivant.

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))

Initialisez ensuite Firebase dans votre base de code. Le code suivant importe et initialise Firebase dans un fichier de point d'entrée et utilise Firestore Lite pour charger un document "ville".

// 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(),
  };
}

L'étape suivante consiste à ajouter un script npm pour exécuter esbuild. Ouvrez le fichier package.json et ajoutez la paire clé-valeur suivante à l'objet "scripts" .

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

Enfin, vérifiez le dossier de construction dist . Il doit contenir un fichier nommé bundle.js qui contient votre application groupée et le code de dépendance.

Pour plus d'informations sur l'optimisation d'esbuild pour la production, consultez leur documentation officielle sur la minification et d'autres optimisations .