Mise à niveau de l'API avec espace de noms vers l'API modulaire

Les applications utilisant actuellement une API Web Firebase avec espace de noms, depuis les bibliothèques compat jusqu'à la version 8 ou antérieure, devraient envisager de migrer vers l'API modulaire en suivant les instructions de ce guide.

Ce guide suppose que vous êtes familier avec l'API avec espace de noms et que vous profiterez d'un regroupeur de modules tel que webpack ou Rollup pour la mise à niveau et le développement continu d'applications modulaires.

L’utilisation d’un bundler de modules dans votre environnement de développement est fortement recommandée. Si vous n'en utilisez pas, vous ne pourrez pas profiter des principaux avantages de l'API modulaire en termes de taille d'application réduite. Vous aurez besoin de npm ou de fil pour installer le SDK.

Les étapes de mise à niveau de ce guide seront basées sur une application Web imaginaire qui utilise les SDK d'authentification et Cloud Firestore. En parcourant les exemples, vous pouvez maîtriser les concepts et les étapes pratiques nécessaires à la mise à niveau de tous les SDK Web Firebase pris en charge.

À propos des bibliothèques avec espace de noms ( compat )

Il existe deux types de bibliothèques disponibles pour le SDK Web Firebase :

  • Modulaire : une nouvelle surface d'API conçue pour faciliter l'arborescence (suppression du code inutilisé) afin de rendre votre application Web aussi petite et rapide que possible.
  • Namespaced ( compat ) - une surface API familière qui est entièrement compatible avec les versions antérieures du SDK, vous permettant d'effectuer une mise à niveau sans modifier tout votre code Firebase à la fois. Les bibliothèques Compat ont peu ou pas d'avantages en termes de taille ou de performances par rapport à leurs homologues avec espace de noms.

Ce guide suppose que vous profiterez des bibliothèques compatibles pour faciliter votre mise à niveau. Ces bibliothèques vous permettent de continuer à utiliser du code avec espace de noms parallèlement au code refactorisé pour l'API modulaire. Cela signifie que vous pouvez compiler et déboguer votre application plus facilement au fur et à mesure du processus de mise à niveau.

Pour les applications avec une très faible exposition au SDK Web Firebase (par exemple, une application qui n'effectue qu'un simple appel aux API d'authentification), il peut être pratique de refactoriser le code avec un espace de noms plus ancien sans utiliser les bibliothèques compatibles. Si vous mettez à niveau une telle application, vous pouvez suivre les instructions de ce guide pour « l'API modulaire » sans utiliser les bibliothèques compatibles.

À propos du processus de mise à niveau

Chaque étape du processus de mise à niveau est définie de manière à ce que vous puissiez terminer la modification de la source de votre application, puis la compiler et l'exécuter sans interruption. En résumé, voici ce que vous ferez pour mettre à niveau une application :

  1. Ajoutez les bibliothèques modulaires et les bibliothèques compatibles à votre application.
  2. Mettez à jour les instructions d'importation dans votre code pour les rendre compatibles.
  3. Refactorisez le code d'un seul produit (par exemple, l'authentification) vers le style modulaire.
  4. Facultatif : à ce stade, supprimez la bibliothèque de compatibilité d'authentification et le code de compatibilité pour l'authentification afin de bénéficier de l'avantage de la taille de l'application pour l'authentification avant de continuer.
  5. Refactorisez les fonctions de chaque produit (par exemple, Cloud Firestore, FCM, etc.) dans le style modulaire, en compilant et en testant jusqu'à ce que tous les domaines soient terminés.
  6. Mettez à jour le code d'initialisation vers le style modulaire.
  7. Supprimez toutes les instructions de compatibilité restantes et le code de compatibilité de votre application.

Obtenez la dernière version du SDK

Pour commencer, récupérez les bibliothèques modulaires et les bibliothèques compatibles à l'aide de npm :

npm i firebase@10.9.0

# OR

yarn add firebase@10.9.0

Mettre à jour les importations pour les rendre compatibles

Afin que votre code continue de fonctionner après la mise à jour de vos dépendances, modifiez vos instructions d'importation pour utiliser la version "compat" de chaque importation. Par exemple:

Avant : version 8 ou antérieure

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

Après : compatibilité

// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';

Refactoriser le style modulaire

Alors que les API avec espace de noms sont basées sur un espace de noms et un modèle de service en chaîne de points, l'approche modulaire signifie que votre code sera organisé principalement autour de fonctions . Dans l'API modulaire, le package firebase/app et les autres packages ne renvoient pas d'exportation complète contenant toutes les méthodes du package. Au lieu de cela, les packages exportent des fonctions individuelles.

Dans l'API modulaire, les services sont transmis comme premier argument et la fonction utilise ensuite les détails du service pour faire le reste. Examinons comment cela fonctionne dans deux exemples qui refactorisent les appels aux API d'authentification et Cloud Firestore.

Exemple 1 : refactoriser une fonction d'authentification

Avant : compatibilité

Le code de compatibilité est identique au code de l'espace de noms, mais les importations ont changé.

import firebase from "firebase/compat/app";
import "firebase/compat/auth";

const auth = firebase.auth();
auth.onAuthStateChanged(user => { 
  // Check for user status
});

Après : modulaire

La fonction getAuth prend firebaseApp comme premier paramètre. La fonction onAuthStateChanged n'est pas chaînée à partir de l'instance auth comme elle le serait dans l'API avec espace de noms ; au lieu de cela, c'est une fonction gratuite qui prend auth comme premier paramètre.

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
  // Check for user status
});

Gestion des mises à jour de la méthode Auth getRedirectResult

L'API modulaire introduit un changement radical dans getRedirectResult . Lorsqu'aucune opération de redirection n'est appelée, l'API modulaire renvoie null , contrairement à l'API avec espace de noms, qui renvoyait un UserCredential avec un utilisateur null .

Avant : compatibilité

const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
  return null;
}
return result;

Après : modulaire

const result = await getRedirectResult(auth);
// Provider of the access token could be Facebook, Github, etc.
if (result === null || provider.credentialFromResult(result) === null) {
  return null;
}
return result;

Exemple 2 : refactoriser une fonction Cloud Firestore

Avant : compatibilité

import "firebase/compat/firestore"

const db = firebase.firestore();
db.collection("cities").where("capital", "==", true)
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
    })
    .catch((error) => {
        console.log("Error getting documents: ", error);
    });

Après : modulaire

La fonction getFirestore prend firebaseApp comme premier paramètre, qui a été renvoyé par initializeApp dans un exemple précédent. Notez à quel point le code permettant de former une requête est très différent dans l'API modulaire ; il n'y a pas de chaînage et des méthodes telles que query ou where sont désormais exposées comme des fonctions gratuites.

import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";

const db = getFirestore(firebaseApp);

const q = query(collection(db, "cities"), where("capital", "==", true));

const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
});

Mettre à jour les références à Firestore DocumentSnapshot.exists

L'API modulaire introduit une modification radicale dans laquelle la propriété firestore.DocumentSnapshot.exists a été remplacée par une méthode . La fonctionnalité est essentiellement la même (tester si un document existe) mais vous devez refactoriser votre code pour utiliser la méthode la plus récente, comme indiqué :

Avant : compatible

if (snapshot.exists) {
  console.log("the document exists");
}

Après : modulaire

if (snapshot.exists()) {
  console.log("the document exists");
}

Exemple 3 : combiner des styles de code avec espace de noms et modulaire

L'utilisation des bibliothèques compatibles lors de la mise à niveau vous permet de continuer à utiliser du code avec espace de noms ainsi que du code refactorisé pour l'API modulaire. Cela signifie que vous pouvez conserver le code d'espace de noms existant pour Cloud Firestore pendant que vous refactorisez l'authentification ou un autre code du SDK Firebase vers le style modulaire, tout en compilant avec succès votre application avec les deux styles de code. Il en va de même pour le code API avec espace de noms et modulaire au sein d'un produit tel que Cloud Firestore ; les nouveaux et les anciens styles de code peuvent coexister, à condition que vous importiez les packages compatibles :

import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'

const docRef = firebase.firestore().doc();
getDoc(docRef);

Gardez à l’esprit que, même si votre application sera compilée, vous n’obtiendrez pas les avantages du code modulaire en termes de taille d’application tant que vous n’aurez pas complètement supprimé les instructions de compatibilité et le code de votre application.

Mettre à jour le code d'initialisation

Mettez à jour le code d'initialisation de votre application pour utiliser la syntaxe modulaire. Il est important de mettre à jour ce code après avoir terminé la refactorisation de tout le code de votre application ; en effet, firebase.initializeApp() initialise l'état global pour les API compat et modulaire, alors que la fonction modulaire initializeApp() initialise uniquement l'état pour modulaire.

Avant : compatibilité

import firebase from "firebase/compat/app"

firebase.initializeApp({ /* config */ });

Après : modulaire

import { initializeApp } from "firebase/app"

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

Supprimer le code de compatibilité

Pour profiter des avantages de taille de l'API modulaire, vous devez éventuellement convertir toutes les invocations dans le style modulaire indiqué ci-dessus et supprimer toutes les instructions import "firebase/compat/* de votre code. Lorsque vous avez terminé, il ne devrait plus y avoir de références. à l'espace de noms global firebase.* ou à tout autre code dans le style API avec espace de noms.

Utiliser la bibliothèque compat depuis la fenêtre

L'API modulaire est optimisée pour fonctionner avec des modules plutôt qu'avec l'objet window du navigateur. Les versions précédentes de la bibliothèque permettaient le chargement et la gestion de Firebase en utilisant l'espace de noms window.firebase . Cela n’est pas recommandé à l’avenir car cela ne permet pas l’élimination du code inutilisé. Cependant, la version compatible du SDK JavaScript fonctionne avec la window pour les développeurs qui préfèrent ne pas commencer immédiatement le chemin de mise à niveau modulaire.

<script src="https://www.gstatic.com/firebasejs/10.9.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.9.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.9.0/firebase-auth-compat.js"></script>
<script>
   const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
   const db = firebaseApp.firestore();
   const auth = firebaseApp.auth();
</script>

La bibliothèque de compatibilité utilise du code modulaire sous le capot et lui fournit la même API que l'API avec espace de noms ; cela signifie que vous pouvez vous référer à la référence de l'API avec espace de noms et aux extraits de code avec espace de noms pour plus de détails. Cette méthode n'est pas recommandée pour une utilisation à long terme, mais comme début de mise à niveau vers la bibliothèque entièrement modulaire.

Avantages et limites du SDK modulaire

Le SDK entièrement modularisé présente les avantages suivants par rapport aux versions précédentes :

  • Le SDK modulaire permet de réduire considérablement la taille de l'application. Il adopte le format de module JavaScript moderne, permettant des pratiques de « secouement d'arbre » dans lesquelles vous importez uniquement les artefacts dont votre application a besoin. En fonction de votre application, l'arborescence avec le SDK modulaire peut générer 80 % de kilo-octets en moins qu'une application comparable créée à l'aide de l'API avec espace de noms.
  • Le SDK modulaire continuera de bénéficier du développement continu de fonctionnalités, contrairement à l'API avec espace de noms.