Веб — богатая экосистема с массой мощных API, которая только пополняется. В нашем распоряжении уже знакомые инструменты — Canvas или Intersection Observer, но в 2023 мы также имеем Web MIDI API, Speech Recognition и даже такие экзотические штуки, как геймпады и VR прямо в браузере. Естественно, эти API сложно использовать в Angular из-за разницы парадигм нативного JavaScript и декларативного Angular. Вот тут и появляемся мы!
Как все начиналось
Web API для Angular — это опенсорс-инициатива, которую мы с Ромой начали давным-давно. Мы сторонники идиоматического подхода в Angular — любим декларативный код и стараемся продвигать его везде, где он уместен. Однажды мы взглянули на страницу Web API на MDN и решили: почему бы не облегчить их использование в Angular?
Я начал с Web Audio API, так как увлекался этой темой. Мы заметили, что одного DOCUMENT недостаточно для работы с другими глобальными объектами вроде window или navigator в безопасной DI-манере. Поэтому сделали пакет, который стал самым популярным среди этой коллекции библиотек, — @ng-web-apis/common. Вместе с сестринской @ng-web-apis/universal они позволяют комфортно работать с глобальными объектами через инъекцию зависимостей. Это означает легкое тестирование и SSR.
Я уже писал, почему подобные абстракции важны. Ещё я уже упоминал Web Audio API и Web MIDI API. Но я раньше не освещал эту инициативу в целом. А ведь в ней есть еще много полезных инструментов, которых вам могло не хватать. Кроме того, после недавних изменений, о которых я скажу в конце, у нас есть планы развивать этот продукт далее, так что стоит поместить его в закладки! А пока давайте посмотрим на все, что у нас есть уже сейчас.
APIs
Про common, universal, audio и midi я уже рассказал выше. Вот список остальных библиотек.
IntersectionObserver — наш второй по популярности пакет. Он позволяет использовать Intersection Observer в комфортном для Angular виде. Создаем директивой обсервер и задаем параметры, такие как границы срабатывания. Затем помечаем другой директивой элементы, которые собираемся отслеживать. Обычный @Output будет сообщать о пересечениях. То же самое можно получить, используя RxJS-сервис и передавая настройки через DI-токен. Эта библиотека хорошо отражает принципы, на которых построены все пакеты из этой коллекции. Подробнее можно почитать в другой моей статье:
ResizeObserver. Следуя тому же подходу с декларативными директивами и RxJS-сервисом, эта библиотека позволяет следить за изменениями размера элемента и делать это эффективно. Библиотеки обсерверов хорошо обрисовывают основной принцип: оборачиваем нативный API с минимальной интервенцией. Работа с DOM означает директивы, события означают RxJS-потоки. Так мы получаем преимущества комфортного использования всего за пару килобайт. При этом знания Angular и нативного JavaScript достаточно для работы.
MutationObserver. Последний из троицы обсерверов. Этот API появился больше десяти лет назад! В отличие от предыдущих библиотек, здесь директива расширяет нативный MutationObserver-класс. Код получается совсем крошечный, и мы видим интересный пример, который возможен с современным JavaScript. Не стоит беспокоиться по поводу nodejs и SSR: наш специализированный пакет universal, упомянутый выше, берет это на себя. Стоит также помнить про него при работе с Jest-тестами!
Geolocation. Пакет от Владимира Потехина и его первый опыт в open source. Сейчас Вова входит в команду, разрабатывающую наш основной продукт Taiga UI. С этим пакетом очень легко наблюдать за своим GPS-местоположением с помощью Observable-сервиса.
Canvas. Этот пакет позволяет рисовать на HTMLCanvasElement
схожим с SVG способом, описывая графику декларативными директивами. Он покрывает все 2D-возможности Canvas API, такие как пути, трансформации, текст, типы заливки и обводки.
Workers — вклад Игоря Кацубы, чей проект ng-morph позволил нам сделать довольно изощренные миграции ломающих изменений при переходе между мажорными релизами Taiga UI. Вы можете почитать об этом проекте тут, тут и тут. Пакет @ng-web-apis/workers
позволяет использовать веб-воркеры в Angular в знакомом виде потоков событий RxJS.
Payment Request — исторически самый первый опенсорс-проект от Ромы. Это библиотека для декларативной сборки payment request с помощью директив, которые можно использовать, к примеру, в компоненте корзины при оформлении заказа в e-commerce-приложении.
Permissions — вклад Дмитрия Ефименко. Крошечный пакет с сервисом, позволяющим запрашивать доступ к браузерным API через RxJS-потоки.
Speech — синтезатор и распознавание речи в одной библиотеке. В вашем распоряжении настраиваемая text-to-speech-директива и сервис для распознавания речи в виде RxJS-операторов.
Storage — пакет для работы с Web Storage API через обсерваблы.
Как все продолжается
Мы начинали эту инициативу как наш личный проект, чтобы освоиться в среде open source. Он стал очень полезным, и мы начали использовать его в своей работе в Тинькофф.
За последние годы у нас оставалось все меньше и меньше времени на эти пакеты. Особенно на более нишевые, такие как Web Audio API — самая большая и сложная библиотека. Многие из них оставались на Angular 9 с публикацией во View Engine, когда уже вышел Angular 16 и поддержка старого движка была прекращена.
Самым разумным решением стал перевод библиотек в nx-монорепу для удобной поддержки. Но на это не хватало времени: множество других проектов требовали нашего внимания. Я не мог просто попросить коллег заняться этим в свободное время. Учитывая, что многие библиотеки — неотъемлемая часть наших продуктов, мы решили передать их полностью под поддержку Тинькофф. Так вся команда может и дальше развивать эту коллекцию.
Для конечного пользователя это означает только перевод лицензии с MIT на Apache 2.0. Ну и более качественную и своевременную поддержку. Проект остается на GitHub, и все желающие также могут продолжить вносить свой вклад. Смена лицензии обозначена новым мажорным релизом, в котором все пакеты были синхронизированы на версии 3.0 и переведены на Ivy-публикацию. Если вы встретите какие-то проблемы или отсутствующие возможности — не стесняйтесь завести Issue в новом монорепозитории. Старые страницы на GitHub переведены в режим read only.