Pull to refresh
330.44
TINKOFF
IT’s Tinkoff — просто о сложном

От одного приложения — к сотне. Путь микрофронтенда в Тинькофф Бизнес

Reading time6 min
Views8.2K

Привет, меня зовут Ваня, недавно я выступил на CodeFest 11, где рассказал про путь Тинькофф Бизнеса на фронтенде от одного приложения к сотне. Но так как в ИT очень быстро все меняется, а ждать запись еще долго, сейчас я тезисно расскажу о нашем шестилетнем путешествии в дивный мир микрофронтенда!

Мою статью можно разбить на две части. В первой части вас ждет история развития через призму бизнеса. А во второй — рассказ о том, как мы адаптировались к новым вызовам.

Этапы развития

  1. Одно приложение на AngularJS в 2014—2015 годах.

  2. Миграция на Angular2.

  3. Утяжеление десяти приложений новой функциональностью.

  4. Переход к микросервисам и разбиение на 100 приложений.

На дворе начало 2015 года. К нам приходит бизнес и говорит: «Мы хотим сделать зарплатный проект! Посмотрите, что есть сейчас на рынке по технологиям, и сделайте». Выбираем AngularJS, быстро создаем приложение. Спустя некоторое время аппетиты вырастают, мы создаем еще два сервиса. На этот момент фронтенд-приложения никак не взаимодействуют друг с другом.

Компания растет, мы доходим до десяти приложений в 2017 году. Команды еще не так сильно разрослись, но уже чувствуется локализация некоторой экспертизы. Для шаринга информации выделяется особая роль — «архитектор». С одной стороны, это самый технически прокачанный человек, с другой — евангелист наших подходов, который на одном языке общается как с бизнесом, так и с новичком в компании.

В 2017—2018 годах мы подумали, что уже хватит отдельных репозиториев, и стали добавлять фичи в существующие проекты и репозитории вместо создания новых.

В одном из проектов у нас было пять фронтенд-команд, в каждой по 3—5 человек, то есть в самый лучший момент в одном проекте работали 25 фронтендеров! Иногда было действительно больно: ты вот-вот замержишь свою задачку, но нет! Перед тобой кто-то успевает и все твои пайплайны начинают проходить заново! До сих пор мне не по себе от этих воспоминаний.

В какой-то момент мы осознали, что сборка приложения занимает уже полчаса и будет только расти, и решили распиливать наши монолиты на микросервисы.

Вот так быстро и пролетели шесть лет эволюции наших подходов. Теперь взглянем на наш путь через призму своих решений для микрофронтенда.

Сайдбар

Первые три приложения мы подружили между собой с помощью сайдбара.

В каждое приложение он встраивался с помощью ссылки на скрипт, который загружал на клиент полноценное приложение. Сайдбар отвечал за авторизацию, продукты клиента и текущий роутинг страницы, мог отправлять уведомления и загружал мессенджер на страницу. Как мы видим, довольно много возможностей у одного сервиса.

По технической части это iframe со всеми плюсами и минусами, о которых довольно подробно расписано в докладе Яндекса. Но больше всего нам не нравилась перезагрузка страницы на каждую смену продукта. Это мешало переиспользованию состояния клиента, требовало каждый раз обращаться к бекенду и добавляло некрасивые «мерцания» страницы при переходах.

Подсвеченная область – отдельное приложение Сайдбар
Подсвеченная область – отдельное приложение Сайдбар

Frame Manager

Именно рваные переходы мы убрали с появлением Frame Manager'а (далее буду называть его ФМ).

Подсвеченная область – отдельное приложение Frame Manager
Подсвеченная область – отдельное приложение Frame Manager

В отличие от сайдбара, который встраивался в приложение с помощью iframe, ФМ находился на странице всегда и сам встраивал в себя приложения.

Слева – концепция сайдбара (было), справа – Frame Manager'а (стало)
Слева – концепция сайдбара (было), справа – Frame Manager'а (стало)

Для клиента ФМ так же не заметен, как и сайдбар, но для нас он выполняет уже больше функций. Кроме рейтинга, списка продуктов и авторизации он может передавать состояние между приложениями, например через глобальный window. Пользователь больше не замечает, что ходит между несколькими отдельными приложениями, так как верхняя часть у него никуда не пропадает и визуально весь процесс выглядит как подгрузка контента на одну страницу.

В плане интеграции приложения тоже все поменялось:

  • Раньше приложению-клиенту достаточно было подключить необходимый скрипт к себе в index.html.

  • Теперь все приложения ФМа хранятся в отдельной конфигурации и используются как единый источник правды.

Минус этого подхода — мы все равно остались с iframe, который нам не особо нравился из-за особенностей работы с ним. 

Однажды через поддержку к нам обратились пользователи с ситуацией: «Раньше у меня работал плагин для Google Chrome, а с недавнего времени именно на вашем сайте перестал. Почините, пожалуйста!» Обычно на такие просьбы не реагируют: пользователь что-то себе установил — пусть сам и разбирается. Но только не в нашей компании. Команда долго изучала вопрос, смотрела, какое окружение у клиента, версия браузера и все-все, но ответа так и не было. В итоге мы полностью повторили окружение, загрузили себе плагины и путем дебагинга установили, что данный плагин не работает, если у iframe динамически менять атрибут src или пересоздавать фрейм. К сожалению, мы так и не смогли исправить такое поведение, поскольку на этой концепции построено все взаимодействие ФМ и дочерних приложений.

Бесфрейм-менеджер

Однажды мы собрались и подумали: «Несколько лет страдаем от iframe. Как перестать страдать? Давайте просто уберем его!» Сказано — сделано. Так и появился бесфрейм-менеджер — с фантазией у нас, конечно, не фонтан ;-) 

Ключевые отличия от предыдущей версии — самописная изоляция и работа с микрофронтендом вместо фрейма. На мой взгляд, лучше всего мотивацию создания отражает слайд из моей презентации:

В решении — три составляющие:

  1. Webpack-плагин — основа нашего решения, подробнее о которой можно прочитать в статье Игоря.

  2. Angular builder — обвязка для настройки и запуска плагина.

  3. Angular schematics — скрипт для упрощения работы с файловой структурой с помощью AST.

В 2021 году плагин становится менее актуальным, потому что вышел Webpack 5 с Module Federation, но напомню, что мы вели разработку в 2018 году, а Angular стал поддерживать последнюю версию вебпака лишь с двенадцатой версии, которая вышла 12 мая 2021 года. Мы пока не уверены, сможет ли MF заменить наше решение, и изучаем комбинацию подходов.

Что же касается других решений, на которые можно было перейти для отказа от iframe, то это Single SPA. Он всем хорош и очень популярен, но в плане Angular есть небольшой дисклеймер.

https://single-spa.js.org/docs/ecosystem-angular/
https://single-spa.js.org/docs/ecosystem-angular/

Мы понимали, что глобально менять концепцию фреймворка нам никто не даст, потому решили доделать имеющийся.

Что же касается Angular builder и schematics, то они нужны, чтобы разработчики, которые будут интегрировать наше решение к себе, не выполняли километровую инструкцию, а просто написали в консоли:

ng update @scripts/deframing

И вся магия подключения произойдет у них на глазах, но не потребует никакого ручного вмешательства. Подробнее с работой билдеров и схематиков можно ознакомиться в классной статье.

Тестирование

Для нас важным моментом является автоматическое тестирование, тем более в проекте, от которого зависят все остальные команды. Путем проб и ошибок мы пришли к такому разделению тестового покрытия:

  1. Можно прогонять тесты совместно с локальным ФМом. Так разработчики всегда могут быть уверены, что на текущей продовой сборке все работает и выглядит так, как и задумывалось.

  2. Сам ФМ определяет несколько жизненно важных процессов, работоспособность которых гарантирует при любых условиях: это авторизация, роутинг, работа с данными приложений. Для этого создаются приложения-стабы (stub), суть которых — подключиться к ФМу и выполнить одну из вышеперечисленных функций. То есть на каждое изменение кодовой базы ФМа будет гарантированно работать эта функция.

Ну и как же обойтись без описания багов, которые мы встретили на своем пути. Их тоже можно поделить глобально на две группы: накопление стилей и сторонние библиотеки.

Накопление стилей — пользователь «гуляет» между приложениями, и у него накапливается состояние. Допустим, один из разработчиков написал:

.my-pretty-header {
    display: none;
}

Если у кого-то из следующих приложений есть такое же название класса, этот стиль применится так же!

Пример: диалог решил спрятаться под меню, чтобы пользователь не догадался, что от него требуется:

Этот тип багов мы решили путем префикса по id приложения для всех стилей, чтобы они не имели глобальную видимость.

Сторонние библиотеки — если на одной странице два и более приложения используют библиотеку, которая на старте создает новый инстанс, то получается такая картина:

То есть библиотека пытается дважды запуститься и второй сервис затирает первый, что ломает поведение обоих. Это мы исправили путем небольших доработок библиотек.

Microzord

Вот мы и прошли шесть лет технического развития нашего решения. И что может быть лучше, чем поделиться этим опытом с сообществом? Все наработки будут публиковаться под npm scope @microzord с открытым кодом на Гитхабе.

В планах — предоставить клиент не только для Angular, но и для работы с другими фреймворками. Сейчас лишь небольшая часть вынесена на Гитхаб, но будьте уверены, ребята не заставят себя ждать и в одной из следующих статей расскажут о гитхабе поподробнее.

Tags:
Hubs:
+29
Comments0

Articles

Information

Website
www.tinkoff.ru
Registered
Founded
Employees
over 10,000 employees
Location
Россия