Przejdź z interfejsu API z przestrzeni nazw na modułowy interfejs API

Aplikacje korzystające obecnie z dowolnego interfejsu API Firebase opartego na przestrzeni nazw (od bibliotek compat do wersji 8 lub starszej) powinny rozważyć przejście na modułowy interfejs API zgodnie z instrukcjami w tym przewodniku.

W tym przewodniku zakładamy, że znasz interfejs API z przestrzenią nazw i że będziesz korzystać z pakietu modułów, takiego jak webpack lub Rollup, do uaktualniania i dalszego tworzenia aplikacji modułowych.

Zdecydowanie zalecamy używanie kreatora pakietów modułów w środowisku programistycznym. Jeśli nie użyjesz, zmniejsz rozmiar aplikacji, aby skorzystać z głównych zalet interfejsu modułowego interfejsu API. Do zainstalowania pakietu SDK potrzebujesz npm lub yarn.

Czynności uaktualnienia opisane w tym przewodniku opierają się na wymyślonej aplikacji internetowej, która korzysta z pakietów SDK uwierzytelniania i Cloud Firestore. Korzystając z przykładów, opanujesz pojęcia i praktyczne czynności wymagane do uaktualnienia wszystkich obsługiwanych pakietów internetowych SDK Firebase.

Informacje o bibliotekach z przestrzeni nazw (compat)

Dla pakietu SDK internetowego Firebase są dostępne 2 typy bibliotek:

  • Modular – nowa platforma API zaprojektowana w celu ułatwienia potrząsania drzewami (usuwania nieużywanego kodu) w celu jak najszybszego i małego tworzenia aplikacji internetowej.
  • Przestrzeń nazw (compat) to dobrze znany interfejs API, który jest w pełni zgodny z wcześniejszymi wersjami pakietu SDK, umożliwiając uaktualnienie bez zmieniania całego kodu Firebase naraz. Biblioteki Compat mają minimalny lub zerowy rozmiar i wydajność w porównaniu z ich odpowiednikami z przestrzenią nazw.

W tym przewodniku przyjęto założenie, że ułatwisz uaktualnienie, korzystając z bibliotek zgodnych. Te biblioteki pozwalają na dalsze korzystanie z kodu z przestrzeni nazw wraz z kodem refaktoryzowanym dla modułowego interfejsu API. Oznacza to, że w trakcie procesu uaktualniania możesz łatwiej kompilować i debugować aplikację.

W przypadku aplikacji, które mają bardzo małą ekspozycję na pakiet SDK Firebase Web SDK – na przykład takich, które wykonują tylko proste wywołania interfejsów Authentication API – może być praktyczna refaktoryzacja starszego kodu z przestrzeni nazw bez używania zgodnych bibliotek. Jeśli uaktualniasz taką aplikację, możesz postępować zgodnie z instrukcjami w tym przewodniku dotyczącym „modułowego interfejsu API” bez używania zgodnych bibliotek.

Proces uaktualniania

Każdy etap procesu uaktualniania ma zakres ograniczony, więc możesz zakończyć edytowanie źródła aplikacji, a potem skompilować i uruchomić je bez błędów. Aby uaktualnić aplikację:

  1. Dodaj do swojej aplikacji biblioteki modułowe i biblioteki kompatybilne.
  2. Zaktualizuj instrukcje importu w kodzie, tak aby były zgodne.
  3. Refaktoryzacja kodu pojedynczego produktu (np. Uwierzytelnianie) na styl modułowy.
  4. Opcjonalnie: na tym etapie usuń bibliotekę kompatybilną z Uwierzytelnianiem i kod kompatybilny na potrzeby uwierzytelniania, aby móc jeszcze lepiej wykorzystać rozmiar aplikacji w przypadku uwierzytelniania, zanim przejdziesz dalej.
  5. Refaktoryzacja funkcji dla każdej usługi (np. Cloud Firestore, FCM itp.) na styl modułowy, kompilowanie i testowanie aż do ukończenia wszystkich obszarów.
  6. Zaktualizuj kod inicjowania do stylu modułowego.
  7. Usuń z aplikacji wszystkie pozostałe instrukcje zgodne i kod kompatybilny.

Pobierz najnowszą wersję pakietu SDK

Na początek pobierz biblioteki modułowe i biblioteki zgodne przy użyciu npm:

npm i firebase@10.12.2

# OR

yarn add firebase@10.12.2

Zaktualizuj importy do zgodności

Aby po zaktualizowaniu zależności kod nadal działał, zmień instrukcje importu tak, aby korzystały z wersji „compat” każdego importu. Przykład:

Przed: wersja 8 lub starsza

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

Po: zgodny

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

Refaktoryzacja na styl modułowy

Interfejsy API z przestrzenią nazw bazują na przestrzeni nazw w łańcuchu kropek i wzorcu usług, natomiast podejście modułowe oznacza, że kod jest zorganizowany głównie wokół funkcji. W modułowym interfejsie API pakiet firebase/app i inne pakiety nie zwracają pełnego eksportu zawierającego wszystkie metody z pakietu. Zamiast tego eksportują one poszczególne funkcje.

W modułowym interfejsie API usługi są przekazywane jako pierwszy argument, które następnie wykorzystują szczegóły usługi do wykonywania pozostałych czynności. Przyjrzyjmy się 2 przykładom, które refaktoryzują wywołania interfejsów API uwierzytelniania i Cloud Firestore.

Przykład 1. refaktoryzacja funkcji uwierzytelniania

Przed: zgodny

Kod kompatybilny jest taki sam jak kod z przestrzeni nazw, ale importy się zmieniły.

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

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

Po: modułowy

Funkcja getAuth przyjmuje jako pierwszy parametr firebaseApp. Funkcja onAuthStateChanged nie jest połączona z instancją auth w taki sam sposób jak w interfejsie API z przestrzenią nazw. Jest to funkcja swobodna, która jako pierwszy parametr przyjmuje auth.

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

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

Zaktualizuj obsługę metody uwierzytelniania getRedirectResult

Modułowy interfejs API wprowadza zmianę powodującą niezgodność w getRedirectResult. Gdy nie zostanie wywołana żadna operacja przekierowania, modułowy interfejs API zwróci wartość null, a nie interfejs API z przestrzenią nazw, który zwrócił błąd UserCredential użytkownikowi null.

Przed: zgodny

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

Po: modułowy

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;

Przykład 2: refaktoryzacja funkcji Cloud Firestore

Przed: zgodny

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

Po: modułowy

Funkcja getFirestore przyjmuje jako pierwszy parametr firebaseApp, który został zwrócony z metody initializeApp we wcześniejszym przykładzie. Zwróć uwagę, że kod tworzący zapytanie w modułowym interfejsie API bardzo się różni – nie ma łańcuchów, a metody takie jak query czy where są teraz udostępniane jako funkcje bezpłatne.

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

Zaktualizuj odniesienia do Firestore DocumentSnapshot.exists

Modułowy interfejs API wprowadza zmianę powodującą niezgodność, w wyniku której właściwość firestore.DocumentSnapshot.exists została zmieniona w metodę. Funkcjonalność jest zasadniczo taka sama (sprawdzanie, czy dokument istnieje), ale trzeba dokonać refaktoryzacji kodu, aby użyć nowszej metody, jak pokazano poniżej:

Przed:Kompatyzm

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

Po: modułowy

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

Przykład 3: łączenie przestrzeni nazw z modułowymi stylami kodu

Użycie bibliotek zgodnych podczas uaktualniania pozwala na dalsze korzystanie z kodu z przestrzenią nazw wraz z kodem zrefaktoryzowanym na potrzeby modułu interfejsu API. Oznacza to, że w Cloud Firestore możesz zachować istniejący kod z przestrzenią nazw, refaktoryzując uwierzytelnianie lub inny kod pakietu SDK Firebase na styl modułowy, a przy tym nadal efektywnie skompilować aplikację z użyciem obu stylów. To samo dotyczy przestrzeni nazw i modułowego kodu interfejsu API w ramach usługi, takiej jak Cloud Firestore. Nowe i stare style kodu mogą współistnieć, o ile importujesz kompatybilne pakiety:

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

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

Pamiętaj, że chociaż aplikacja się kompiluje, nie uzyskasz korzyści związanych z rozmiarem aplikacji związanych z kodem modułowym, dopóki nie usuniesz z aplikacji zgodnych instrukcji i kodu.

Zaktualizuj kod inicjowania

Zaktualizuj kod inicjowania aplikacji, aby używać składni modułowej. Pamiętaj, aby zaktualizować ten kod po zakończeniu refaktoryzacji całego kodu w aplikacji. Wynika to z tego, że firebase.initializeApp() inicjuje stan globalny zarówno dla zgodnych, jak i modułowych interfejsów API, natomiast funkcja modułowa initializeApp() inicjuje tylko stan dla modułu.

Przed: zgodny

import firebase from "firebase/compat/app"

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

Po: modułowy

import { initializeApp } from "firebase/app"

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

Usuń kod kompatybilny

Aby wykorzystać możliwości związane z rozmiarem, jakie daje modułowy interfejs API, przekonwertuj wszystkie wywołania na styl modułowy pokazany powyżej i usuń wszystkie instrukcje import "firebase/compat/* z kodu. Gdy skończysz, nie powinno być już żadnych odniesień do globalnej przestrzeni nazw firebase.* ani żadnego innego kodu w stylu interfejsu API z przestrzenią nazw.

Używanie biblioteki kompatybilnej z poziomu okna

Modułowy interfejs API jest zoptymalizowany pod kątem pracy z modułami, a nie z obiektem window przeglądarki. Poprzednie wersje biblioteki umożliwiały wczytywanie Firebase i zarządzanie nią dzięki przestrzeni nazw window.firebase. Od tej pory nie jest to zalecane, ponieważ nie pozwala na usuwanie nieużywanego kodu. Zgodna wersja pakietu SDK JavaScript działa jednak z window w przypadku deweloperów, którzy nie chcą od razu rozpoczynać modułowej ścieżki uaktualnienia.

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

Biblioteka zgodności korzysta w niej z kodu modułowego, który jest dostępny w ramach tego samego interfejsu API co interfejs API z przestrzenią nazw. Aby dowiedzieć się więcej, możesz zapoznać się z dokumentacją interfejsu API z przestrzenią nazw i fragmentami kodu w przestrzeni nazw. Ta metoda nie jest zalecana do długoterminowego użytkowania, ale jako początek przechodzenia na w pełni modułową bibliotekę.

Zalety i ograniczenia modułu SDK

W pełni modułowy pakiet SDK ma te zalety w porównaniu z wcześniejszymi wersjami:

  • Modułowy pakiet SDK umożliwia znaczne zmniejszenie rozmiaru aplikacji. Wykorzystuje nowoczesny format modułów JavaScript, co umożliwia stosowanie praktyk „trząsania drzewem”, w ramach których importujesz tylko artefakty potrzebne aplikacji. W zależności od aplikacji potrząsanie drzewem przy użyciu modułu SDK może zmniejszyć o 80% ilość kilobajtów danych niż w przypadku porównywalnej aplikacji utworzonej przy użyciu interfejsu API z przestrzenią nazw.
  • Modułowy pakiet SDK nadal będzie korzystać ze stałego rozwoju funkcji, natomiast interfejs API z przestrzenią nazw – nie.