Приложения, использующие любой веб-API Firebase с пространством имен, начиная с библиотек compat
до версии 8 или более ранней, должны рассмотреть возможность перехода на модульный API, следуя инструкциям в этом руководстве.
В этом руководстве предполагается, что вы знакомы с API пространства имен и воспользуетесь преимуществами упаковщика модулей, например Webpack или Rollup, для обновления и постоянной разработки модульных приложений.
Настоятельно рекомендуется использовать сборщик модулей в вашей среде разработки. Если вы его не используете, вы не сможете воспользоваться основными преимуществами модульного API в уменьшении размера приложения. Для установки SDK вам понадобится npm или yarn .
Шаги обновления в этом руководстве будут основаны на воображаемом веб-приложении, которое использует Authentication и Cloud Firestore SDK. Работая с примерами, вы сможете освоить концепции и практические шаги, необходимые для обновления всех поддерживаемых Firebase web SDK.
О библиотеках с пространством имен ( compat
)
Для Firebase web SDK доступны два типа библиотек:
- Модульность — новая поверхность API, разработанная для упрощения tree-shaking (удаления неиспользуемого кода) с целью сделать ваше веб-приложение максимально компактным и быстрым.
- Пространство имен (
compat
) — знакомая поверхность API, которая полностью совместима с более ранними версиями SDK, что позволяет вам обновляться, не меняя весь ваш код Firebase сразу. Библиотеки Compat имеют мало или вообще не имеют преимуществ по размеру или производительности по сравнению с их аналогами с пространством имен.
В этом руководстве предполагается, что вы воспользуетесь библиотеками compat для облегчения обновления. Эти библиотеки позволяют вам продолжать использовать код с пространством имен наряду с кодом, рефакторинг которого выполнен для модульного API. Это означает, что вы можете легче компилировать и отлаживать свое приложение по мере работы над процессом обновления.
Для приложений с очень небольшим воздействием на Firebase web SDK — например, приложение, которое делает только простой вызов API Authentication — может быть практичным рефакторинг старого кода пространства имен без использования библиотек compat. Если вы обновляете такое приложение, вы можете следовать инструкциям в этом руководстве для «модульного API» без использования библиотек compat.
О процессе обновления
Каждый шаг процесса обновления ограничен, чтобы вы могли закончить редактирование исходного кода вашего приложения, а затем скомпилировать и запустить его без поломок. Вкратце, вот что вам нужно сделать для обновления приложения:
- Добавьте в свое приложение модульные библиотеки и библиотеки совместимости.
- Обновите операторы импорта в вашем коде для совместимости.
- Реорганизуйте код для одного продукта (например, Authentication ) в модульный стиль.
- Необязательно: на этом этапе удалите библиотеку совместимости Authentication и код совместимости для Authentication , чтобы реализовать преимущество размера приложения для Authentication , прежде чем продолжить.
- Реорганизовать функции для каждого продукта (например, Cloud Firestore , FCM и т. д.) в модульный стиль, компилируя и тестируя до тех пор, пока все области не будут завершены.
- Обновите код инициализации в модульном стиле.
- Удалите все оставшиеся операторы совместимости и код совместимости из вашего приложения.
Получите последнюю версию SDK
Для начала скачайте модульные библиотеки и совместимые библиотеки с помощью npm:
npm i firebase@11.8.0 # OR yarn add firebase@11.8.0
Обновите импорт для совместимости
Чтобы ваш код продолжал работать после обновления зависимостей, измените операторы импорта, чтобы использовать «совместимую» версию каждого импорта. Например:
До: версия 8 или более ранняя
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
После: совместимо
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
Рефакторинг в модульный стиль
В то время как API с пространством имен основаны на шаблоне точечного цепочечного пространства имен и сервиса, модульный подход означает, что ваш код будет организован в основном вокруг функций . В модульном API пакет firebase/app
и другие пакеты не возвращают полный экспорт, содержащий все методы из пакета. Вместо этого пакеты экспортируют отдельные функции.
В модульном API службы передаются в качестве первого аргумента, а затем функция использует сведения о службе, чтобы сделать все остальное. Давайте рассмотрим, как это работает, на двух примерах, которые рефакторят вызовы API Authentication и Cloud Firestore .
Пример 1: рефакторинг функции Authentication
До: совместимо
Код совместимости идентичен коду пространства имен, но импорт изменился.
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
После: модульный
Функция getAuth
принимает firebaseApp
в качестве своего первого параметра. Функция onAuthStateChanged
не связана с экземпляром auth
, как это было бы в API с пространством имен; вместо этого это свободная функция, которая принимает auth
в качестве своего первого параметра.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Обновить обработку метода аутентификации getRedirectResult
Модульный API вносит критическое изменение в getRedirectResult
. Когда операция перенаправления не вызывается, модульный API возвращает null
в отличие от API пространства имен, который возвращал UserCredential
с null
пользователем.
До: совместимо
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
После: модульный
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;
Пример 2: рефакторинг функции Cloud Firestore
До: совместимо
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);
});
После: модульный
Функция getFirestore
принимает firebaseApp
в качестве своего первого параметра, который был возвращен из initializeApp
в предыдущем примере. Обратите внимание, как код для формирования запроса сильно отличается в модульном API; нет цепочки, а такие методы, как query
или where
, теперь представлены как свободные функции.
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());
});
Обновление ссылок на Firestore DocumentSnapshot.exists
Модульный API вводит критическое изменение, в котором свойство firestore.DocumentSnapshot.exists
было изменено на метод . Функциональность по сути та же (проверка существования документа), но вам необходимо реорганизовать свой код, чтобы использовать новый метод, как показано:
До:совместимо
if (snapshot.exists) {
console.log("the document exists");
}
После: модульный
if (snapshot.exists()) {
console.log("the document exists");
}
Пример 3: объединение стилей кода с пространством имен и модульного кода
Использование библиотек compat во время обновления позволяет вам продолжать использовать код с пространством имен вместе с кодом, рефакторинг которого выполнен для модульного API. Это означает, что вы можете сохранить существующий код с пространством имен для Cloud Firestore , пока вы рефакторите код Authentication или другой код Firebase SDK в модульный стиль, и по-прежнему успешно компилировать свое приложение с обоими стилями кода. То же самое относится к коду с пространством имен и модульному коду API в таком продукте, как Cloud Firestore ; новые и старые стили кода могут сосуществовать, пока вы импортируете пакеты compat:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
Помните, что, хотя ваше приложение будет компилироваться, вы не получите преимуществ модульного кода по размеру приложения, пока полностью не удалите операторы и код совместимости из своего приложения.
Обновить код инициализации
Обновите код инициализации вашего приложения для использования модульного синтаксиса. Важно обновить этот код после завершения рефакторинга всего кода в вашем приложении; это связано с тем, что firebase.initializeApp()
инициализирует глобальное состояние как для совместимых, так и для модульных API, тогда как модульная функция initializeApp()
инициализирует только состояние для модульных.
До: совместимо
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
После: модульный
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Удалить совместимый код
Чтобы реализовать преимущества модульного API в плане размера, вам в конечном итоге следует преобразовать все вызовы в модульный стиль, показанный выше, и удалить все операторы import "firebase/compat/*
из вашего кода. Когда вы закончите, не должно быть больше ссылок на глобальное пространство имен firebase.*
или любой другой код в стиле API с пространством имен.
Использование библиотеки совместимости из окна
Модульный API оптимизирован для работы с модулями, а не с объектом window
браузера. Предыдущие версии библиотеки позволяли загружать и управлять Firebase с помощью пространства имен window.firebase
. Это не рекомендуется делать в дальнейшем, поскольку это не позволяет удалять неиспользуемый код. Однако совместимая версия JavaScript SDK работает с window
для разработчиков, которые предпочитают не начинать сразу модульный путь обновления.
<script src="https://www.gstatic.com/firebasejs/11.8.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.8.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.8.0/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
Библиотека совместимости использует модульный код под капотом и предоставляет ему тот же API, что и API с пространством имен; это означает, что вы можете обратиться к справочнику API с пространством имен и фрагментам кода с пространством имен для получения подробной информации. Этот метод не рекомендуется для долгосрочного использования, но как начало для обновления до полностью модульной библиотеки.
Преимущества и ограничения модульного SDK
Полностью модульный SDK имеет следующие преимущества по сравнению с более ранними версиями:
- Модульный SDK позволяет значительно уменьшить размер приложения. Он использует современный формат JavaScript Module, что позволяет применять методы «tree shake», при которых вы импортируете только те артефакты, которые нужны вашему приложению. В зависимости от вашего приложения tree shake с модульным SDK может привести к уменьшению размера килобайт на 80% по сравнению с сопоставимым приложением, созданным с использованием API с пространством имен.
- Модульный SDK продолжит получать выгоду от постоянной разработки функций, в то время как API с пространством имен — нет.