Приложения, использующие любой веб-API Firebase с пространством имен, начиная с compat
библиотек до версии 8 или более ранней, должны рассмотреть возможность перехода на модульный API, следуя инструкциям в этом руководстве.
В этом руководстве предполагается, что вы знакомы с API пространства имен и воспользуетесь средством сборки модулей, таким как Webpack или Rollup, для обновления и дальнейшей разработки модульных приложений.
Настоятельно рекомендуется использовать сборщик модулей в вашей среде разработки. Без него вы не сможете воспользоваться основными преимуществами модульного API, заключающимися в уменьшении размера приложения. Для установки SDK вам потребуется npm или yarn .
В этом руководстве шаги по обновлению будут основаны на воображаемом веб-приложении, использующем SDK Authentication и Cloud Firestore . Разбирая примеры, вы сможете освоить концепции и практические шаги, необходимые для обновления всех поддерживаемых веб-SDK Firebase.
О библиотеках с пространством имен ( compat
)
Для Firebase web SDK доступны два типа библиотек:
- Модульный — новая поверхность API, разработанная для упрощения Tree Shaking (удаления неиспользуемого кода) с целью сделать ваше веб-приложение максимально компактным и быстрым.
- Пространство имён (
compat
) — привычная API-платформа, полностью совместимая с предыдущими версиями SDK, что позволяет обновляться без одновременного изменения всего кода Firebase. Библиотеки Compat практически не имеют преимуществ по размеру и производительности по сравнению с аналогичными библиотеками с пространством имён.
В этом руководстве предполагается, что вы воспользуетесь совместимыми библиотеками для упрощения обновления. Эти библиотеки позволяют вам продолжать использовать код с пространством имён наряду с кодом, рефакторинг которого был проведён для модульного API. Это упрощает компиляцию и отладку приложения в процессе обновления.
Для приложений, которые мало используют Firebase Web SDK (например, для приложений, которые выполняют лишь простые вызовы API Authentication ), может быть целесообразно рефакторить старый код пространства имён без использования библиотек Compat. При обновлении такого приложения можно следовать инструкциям из этого руководства по «модульному API» без использования библиотек Compat.
О процессе обновления
Каждый этап процесса обновления ограничен, чтобы вы могли завершить редактирование исходного кода приложения, а затем скомпилировать и запустить его без сбоев. Вкратце, вот что вам нужно сделать для обновления приложения:
- Добавьте в свое приложение модульные библиотеки и совместимые библиотеки.
- Обновите операторы импорта в вашем коде для совместимости.
- Реорганизуйте код для одного продукта (например, Authentication ) в модульный стиль.
- Необязательно: на этом этапе удалите библиотеку совместимости Authentication и совместимый код для Authentication , чтобы реализовать преимущества по размеру приложения для Authentication , прежде чем продолжить.
- Реорганизовать функции для каждого продукта (например, Cloud Firestore , FCM и т. д.) в модульный стиль, компилируя и тестируя до завершения всех областей.
- Обновить код инициализации в соответствии с модульным стилем.
- Удалите все оставшиеся заявления о совместимости и совместимый код из вашего приложения.
Получите последнюю версию SDK
Для начала получите модульные библиотеки и совместимые библиотеки с помощью npm:
npm i firebase@12.0.0 # OR yarn add firebase@12.0.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: объединение стилей кода с пространством имен и модульных стилей
Использование совместимых библиотек во время обновления позволяет продолжать использовать код с пространством имён наряду с кодом, рефакторинг которого выполнен для модульного API. Это означает, что вы можете сохранить существующий код с пространством имён для Cloud Firestore , пока выполняете рефакторинг кода Authentication или другого кода Firebase SDK в модульный стиль, и при этом успешно компилировать приложение с использованием обоих стилей кода. То же самое справедливо для кода с пространством имён и модульного API в таком продукте, как Cloud Firestore ; новые и старые стили кода могут сосуществовать при условии импорта совместимых пакетов:
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()
инициализирует только состояние для модульных API.
До: совместимо
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/12.0.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/12.0.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/12.0.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 с пространством имен — нет.