Привет, Хабр! Меня зовут Роман Хаджаев, я работаю над проектами Fix Price в качестве фронтенд-разработчика. Сегодня расскажу вам о том, как мы создали собственное веб-приложение и развернули его для запуска на Android. Да, речь идет о PWA-приложении, в которое мы упаковали наш сайт и добавили некоторые дополнительные функции. А в завершение дам полезную информацию начинающим разработчикам, которые только приступают к решению подобных задач.
Итак, перед нами была поставлена задача по оперативному запуску приложения Fix Price в других странах: в Беларуси и Казахстане. При этом дополнительно нужно было реализовать пуш-уведомления и возможность списания баллов в программе лояльности. Такого функционала на сайте либо нет, либо он ограничен, а программа лояльности пользуется большим спросом среди наших покупателей.
Приняли решение остановиться на PWA, поскольку PWA в нашем случае можно было реализовать значительно быстрее, чем делать полноценное нативное приложение (оно будет реализовано несколько позже).
Техническая реализация
Для начала немного терминологии. PWA — это прогрессивные веб-приложения (Progressive Web Application), которые, по сути, являются продвинутыми версиями веб-сайтов. Кроме того, есть также TWA-приложения для Android, сделанные по технологии, разработанной Google. Отличия в том, что PWA является эмулируемым, то есть может устанавливаться на Android или iOS. А TWA выступает в качестве своеобразной «обертки» прогрессивного веб-приложения.
По умолчанию использовался фреймворк Vue.js, где есть удобные паттерны проектирования и плагины (надстройки), которые существенно упрощают разработку. Настройка PWA оказалась на удивление простой, нужно было просто добавить манифест, то есть json-файл с описанием различных параметров (названия, цвета элементов и т.д.).
Но разработка PWA на самом деле невеликая задача, сложнее сделать так, чтобы приложение нормально работало на всех системах. И не слишком удобным для нас оказался процесс тестирования, так как здесь возникают сложности с эмуляторами устройств, применяемых для тестирования в Android Studio. К тому же почти любое приложение на каких-то смартфонах будет работать идеально, а где-то может и вообще не устанавливаться либо работать некорректно. К счастью, на основных системах всё работало гладко, сложности возникали только при запуске приложений на устройствах китайских производителей, в особенности это касалось Huawei и Xiaomi.
Плюсы и минусы PWA
Из преимуществ PWA/TWA отмечу, что они:
делаются быстрее, чем нативные приложения;
обходятся дешевле, так как, по сути, это адаптированные сайты;
весят очень мало: менее 3 Мб против десятков и сотен Мб у нативных.
Таким образом, PWA идеальны для тестирования, так как позволяют быстро создавать минимально жизнеспособные продукты.
Но, разумеется, есть у PWA и недостатки:
Главный — ограниченность функционала PWA-приложений, поскольку это не полноценное мобильное приложение, а, по сути, обернутый веб-сайт с некоторыми дополнительными возможностями. Поэтому есть проблемы с добавлением продвинутой логики или при доработке существующих функций. В результате приходится реализовывать многие вещи обходными путями.
Также отмечу сложность в тестировании, о чём уже говорил выше. Функционал скрыт внутри, и проверить его работоспособность можно только, загружая PWA на конкретные устройства.
И третий минус в том, что, хотя технология появилась уже около 5 лет назад, документации по PWA пока немного. Но тем, что мы собрали, я с вами поделюсь.
Полезные ссылки
Перед началом разработки рекомендую почитать следующее:
https://web.dev/learn/pwa/welcome?hl=ru — основная документация по PWA
https://pwadev.ru/learn/pwa/detection/ — она же на темном фоне
https://web.dev/articles/what-are-pwas?hl=ru — серия статей по PWA
https://www.w3.org/TR/appmanifest/ — W3C-манифест
https://developers.google.com/codelabs/pwa-in-play?hl=ru#0 — основное про TWA
Путь разработчика
Здесь расскажу о том, с чем вы, возможно, столкнетесь, приступив к разработке.
Начав изучать, что такое PWA, мы нашли эту библиотеку: https://pwa.nuxtjs.org/
Увидели, что ramfy манифест, который мы используем для уведомлений, конфликтует с манифестом, описываемым для nuxt-pwa.
Создали темплейт для генерации манифеста и убрали хеши для файла manifest, чтобы можно было использовать его для PWA, путь/имя для которого должны быть статичны.
Для Safari вам необходимо будет отключить фавикон в настройках библиотеки для PWA (в объекте настройке плагина meta — favicon: false). Также стоит уточнить, что в документации не описаны некоторые возможные настройки, которые по факту присутствуют.
Начали добавлять FCM. Если у вас ssr, то необходимо подключать Firebase только для клиента, а чтобы не дублировать настройки аккаунта, вы можете создать переменную окружения с данными и динамически генерировать service-worker с заданными параметрами, которые также сможете подтягивать в скрипт по настройке Firebase на клиенте.
После добавления FCM у нас появились задачи по переходу из клика по пушам и дополнительной обработке. Здесь мы столкнулись с проблемами малой документированности FCM, а также различными проблемами, связанными с особенностями работы PWA (например, когда пользователь отключает уведомления в настройках, когда авторизуется и разлогинивается, удаляет и скачивает приложение, так как service-workers работают отдельно от приложения и могут оставаться даже после его удаления). Кроме того, Firebase не обрабатывает некоторые нужные параметры пушей, в результате необходимо перехватывать управление.
Подводные камни
Во-первых, будьте осторожны с плагинами (если вы не уверены в библиотеке, лучше делайте нативно или с js-пакетами без привязки к фреймворку). Например, в библиотеке nuxt есть проблема, которой нет в более старой версии.
При использовании Firebase для пуш-уведомлений (FCM) надо быть готовым к тому, что придется перехватывать запросы из service-workers и обрабатывать какие-то случаи, так как FCM просто их игнорирует. В доказательство приведу такой пример.
Если вы не нашли нужной информации по FCM в официальной инструкции, загляните в код проекта, поскольку некоторые реализации могут быть не очевидны. К сожалению, информация которую вы будете находить по подключению и использованию FCM, как правило, будет либо взята из документации, либо окажется некорректной/устаревшей, либо же крайне скудной (в основном описываются простые кейсы).
Ну, и в завершение —пример кода (больше ничем поделиться не можем, так как остальной код под NDA), который, надеюсь, вам поможет. Узнать, что приложение запущено как PWA или TWA, можно из URL страницы, вот так:
Надеюсь, приведенная выше информация оказалась для вас полезной, благодарю за внимание!