Firebase изменила свой Javascript API на версию v9. Ранее методы были объединены в цепочки, что делало их более читабельными:
Теперь Firebase 9 использует более модульный подход, ориентированный на функциональное программирование:
Это несет в себе некоторые преимущества:
- Команде Firebase проще тестировать функции
- Облегчает встряхивание дерева (уменьшает размер пакета — неиспользуемые модули/функции выбрасываются при компиляции)
Однако все становится запутанным, когда пользователь API (разработчик) пробует что-то более реалистичное (и люди жалуются):
Действия теперь обратные с точки зрения читающего код. Никто с небольшим опытом программирования не должен писать такой код. Хорошим решением для этого является использование переменных:
Однако рекомендуется избегать чрезмерного использования переменных, так как это создает больше возможностей для ошибок. Возможно, есть лучший способ использовать новый API: попробуйте каррировать новые функции и конвейерно их. Если вы новичок в функциональном программировании, я предлагаю прочитать другие статьи, чтобы понять, как работают эти две концепции.
Чтобы упростить это:
- pipe() возвращает функцию, которую мы можем вызвать. Любые аргументы будут переданы первому элементу в списке, и мы получим результат последнего элемента.
- curry() возвращает ту же предоставленную функцию, которую мы можем частично завершить для последующего выполнения (когда предоставлены все аргументы). Из ref docs: если мы
const refC = curry(ref)
, мы можем вызватьconst refDb = refC(database)
и позжеrefDb('users')
.
API Firebase обычно принимает контекст (ссылка, база данных) в качестве первого аргумента и информацию о функции (путь, полезная нагрузка) в качестве второго аргумента (последние данные). Поэтому мы делаем это справа. Например, в ref()
сначала указывается путь, а ссылка получается позже, когда у нас есть база данных.
ramda — отличная библиотека FP, но она не предоставляет прямого метода обратного каррирования. Поэтому мы используем curryRight lodash. Если вы используете ESM, установите вместо него lodash-es
.
Изначально получаем:
Последний вариант соответствует принципу избегания переменных в FP, но он менее удобочитаем (особенно при вызове только что созданной функции). Первый вариант более удобочитаем, и действия можно экспортировать в отдельные файлы для повторного использования.
Как минимум мы должны экспортировать каррированный API в отдельный файл:
Теперь нам не нужно различать ref и refC.
Ваш выбор между двумя вариантами зависит от вашей ситуации. Мне пришлось реорганизовать существующее приложение Vue.js, и второй подход был более простым, поскольку каждый компонент Vue использовал Firebase напрямую без каких-либо сервисных функций (например, /services/users/getUser
). Пример из реального мира:
Здесь я не стремлюсь к чистым функциям, поэтому вставка внешних переменных (состояние формы, идентификатор пользователя) тривиальна.
С другой стороны, при создании нового приложения вы должны перенести действия в служебные файлы.
Намного лучше. Эту функцию будет очень легко заменить, если вы решите использовать другую технологию базы данных. Хотя необходимость переместить наш первый логический элемент (usersRef
) вниз внесет некоторую путаницу.
К сожалению, обычное каррирование не подходит для Typescript. Интерпретатор не может понять, что получается, когда вы каррируете функцию. В этом случае вы можете полностью отказаться от lodash и выполнить функции вручную:
В заключение давайте проведем чистое сравнение:
Надеюсь, это было полезно для вас. Я еще не закончил рефакторинг своего приложения, поэтому у меня не было времени, чтобы сгладить этот подход. Возьмите то, что вы хотите от него, и примените свои собственные предпочтения, чтобы получить стиль, который вам подходит.
Для пользователей Docker я сделал демо для обеих версий API (инструкции внутри).
Примечание №1. Новый Firebase v9 SDK предлагает API compat, который позволяет связывать методы и снижает потребность в рефакторинге — это выходит за рамки этой статьи.
Примечание №2: в этой статье используется база данных реального времени. Другие модули не тестировались.
Повышение уровня кодирования
Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:
- 👏 Хлопайте за историю и подписывайтесь на автора 👉
- 📰 Смотрите больше контента в публикации Level Up Coding
- 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"
🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу