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

Этот сценарий обычно решается полной перезаписью. Старт в совершенно другом фреймворке, языке и технологическом стеке. Хотя это может решить проблему, это требует больших усилий, может привести к задержкам в разработке и иметь непредсказуемые ETA. Более того, эта ситуация может повторяться с переписыванием, которое требуется каждые 5–6 лет, когда появляются новые интерфейсные технологии.

Этого мы хотели избежать в Заве. Мы хотели найти подход, который позволил бы нам непрерывно и незаметно переключаться с одного технологического стека на другой. Что-то, упрощающее прогнозирование момента внедрения новой технологии и устраняющее обычный риск, связанный с внедрением и инвестированием в чего-то нового.

Почему мы начали искать новый интерфейсный фреймворк?

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

Однако в конце 2018 года почти весь наш интерфейс был основан на Angular.js, включая клиентские и внутренние приложения, а также множество дополнительных инструментов и компонентов. Невозможно было внести необходимые изменения с требуемой скоростью, потому что в наших приложениях использовались устаревшие подходы и накапливались такие проблемы, как:

  • Большой размер пакетов, без разделения кода
  • Между приложениями не использовались общие компоненты. Доступны только стили CSS
  • Код был недостаточно модульным. На глобальные объекты ссылались повсюду

Как фреймворк Angular.js больше не поддерживается для разработки. Его создатели отказались от него, новых библиотек не создается, а рынок труда разработчиков Angular.js постепенно сокращается. Было ясно, что нужно попробовать что-то новое.

Процесс обзора - какую структуру мы должны использовать?

Было непонятно, переходить ли на новый фреймворк Angular (который совершенно другой) или выбрать фреймворк вроде React. В то время React был устоявшимся вариантом, который казался подходящим решением всех наших проблем, но мы решили рассмотреть все доступные варианты.

Для организации перехода на новые технологии мы создали форум для фронтенд-разработчиков из независимых команд - гильдию next-web. Каждого попросили предложить структуру по своему выбору. Основными кандидатами были:

  • Угловой
  • React.js
  • Vue.js

Угловой

Angular - это совершенно новый фреймворк, и мы знали, что не сможем повторно использовать то, что уже написали на Angular.js. Во время встречи по принятию решения от Angular сразу отказались, поскольку он полагается на TypeScript и библиотеку RxJS. RxJS, например, заставляет вас думать в парадигме реактивного программирования и соответствующим образом структурировать приложение, в то время как React и Vue.js менее уверены в том, как обрабатывать асинхронную логику.

Никто в команде не был доволен TypeScript библиотеки RxJS, поэтому казалось слишком рискованным инвестировать не только в новый фреймворк, но и в эти новые технологии.

React.js

React имеет очень сильный набор преимуществ:

  • Его поддерживают крупнейшие интернет-компании: Facebook, Airbnb, Netflix.
  • Богатая экосистема открытых библиотек, дискуссий, курсов.
  • Для решения одной и той же проблемы существует несколько библиотек - например, для управления состоянием Redux, Mobx, Unstated. Вы можете подобрать наиболее подходящий для вашей задачи.

Но с другой стороны медали были и недостатки:

  • Быстрая оборачиваемость библиотек, сложнее успевать за быстрыми темпами изменений (управление состоянием, маршрутизация библиотек).
  • Часто библиотеки React стараются быть универсальными, чтобы их можно было использовать как для веб-разработки, так и для нативной разработки, response-router v3 был хорош для сети, но response-router 4 был ориентирован как на веб-платформу, так и на собственные платформы, поэтому сначала он имел многого не хватает в сети.
  • Имея более крутую кривую обучения, разработчики должны понимать новые концепции функционального программирования, такие как компоненты более высокого порядка.

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

Vue.js

Положительные стороны Vue.js следующие:

  • Ориентирован в основном на решение проблем, возникающих в сети.
  • Легко начать.
  • Имеет библиотеки по умолчанию для основных проблем, которые поддерживаются основными участниками: vue-router, vuex для управления состоянием, vue-server-renderer, vue-cli.
  • Более естественное понимание для backend-разработчиков, которые раньше имели ограниченный доступ к front-end, потому что Vue использует простые шаблоны.
  • В хорошем смысле слова самоуверенны. В нем есть готовые шаблоны для решения многих проблем, при меньшем количестве вариантов.
  • Он соответствует стандарту веб-компонентов.

Тем не менее, Vue является более молодой технологией, чем React, и у нее есть свои недостатки:

  • Меньше выбор библиотек с открытым исходным кодом, меньше людей, имеющих опыт работы с Vue.
  • Все меньше компаний используют Vue, хотя, похоже, ситуация меняется - например, Apple и Netflix недавно начали использовать Vue.
  • Не так много примеров больших приложений, написанных на Vue, за заметным исключением Gitlab. Для Gitlab переход на Vue прошел достаточно хорошо и поддерживал их масштаб.

Решение

Чтобы принять окончательное решение, мы провели открытое голосование разработчиков, которое помогло всем согласоваться. Мы определили два основных аспекта того, как мы можем различать Vue и React:

Сравнение JSX и HTML-шаблонов. React подразумевает использование JSX для написания шаблонов, и, хотя это также возможно с Vue, более идиоматично использовать HTML-шаблоны во Vue. Таким образом, у нас был выбор между использованием шаблонов HTML и JSX.

Фреймворк, основанный на мнении или не придерживающийся мнения. Этот выбор имеет большое влияние на кодовую базу. Выбор менее самоуверенного решения обеспечивает большую свободу и гибкость при создании архитектуры вашего приложения. Однако за это приходится платить - командам нужно тратить больше времени на расследования и на многочисленные встречи, чтобы согласовать и согласовать подход. Напротив, в случае самоуверенного решения многие решения уже приняты авторами фреймворка, поэтому согласование команды требует гораздо меньше усилий.

Мы проголосовали за то, какой подход предпочитают члены нашей команды:

Финальное голосование было связано с выбором между Vue и React:

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

Первые шаги

После того, как мы выбрали Vue, мы начали закладывать прочную основу для нашего нового внешнего технологического стека. Первым шагом была настройка Verdaccio - реестра для хранения пакетов приватных узлов. Далее мы проанализировали ведущие решения для отображения разделяемого компонента и выбирали между Storybook и vue-styleguidist. Мы создали руководства по стилю для проверки концепции с обоими решениями и выбрали Storybook, поскольку он имеет более гибкую конфигурацию и лучшую поддержку сообщества.

Однако первоначальный прогресс в разработке на какое-то время застопорился, поскольку у нас не было четкого пути миграции для больших приложений. Ситуация будет оставаться такой, пока мы не выясним, как писать приложения на Vue, но при этом приносить пользу бизнесу:

  • Использование Micro Frontends - подхода с разделением внешнего интерфейса на более мелкие и независимые микроприложения. Он отлично подходит для постепенного переноса старых приложений.
  • Создавать новые приложения полностью в Vue - это было проще, если бы приложение было полностью независимым от старых приложений.

Для микро-интерфейсов мы выбрали два подхода:

  • Используйте single-spa для постепенного переноса текущих приложений. Библиотека Single-spa предоставляет утилиты для автоматической инициализации и уничтожения приложения в зависимости от активного URL-адреса. Еще одна замечательная вещь - это то, что он позволяет разделять зависимости между приложениями с микро-интерфейсом.
  • Написание приложений-виджетов с помощью Vue, чтобы мы могли использовать его где угодно. У нас есть всего два файла: файлы сценария и файлы стилей, которые мы можем вставлять всякий раз, когда нам нужно показать виджет. В будущем мы захотим сделать из виджета веб-компоненты, чтобы изолировать его стили и сделать его более надежным.

Мы можем показать, как мы используем оба этих подхода в нашем приложении для оценки. Основная цель нашего приложения Assessment - получить информацию о состоянии здоровья пациента, включая все детали, которые позволяют нам безопасно выполнить заказ. Он состоит из следующих разделов:

  • Анкета для постановки диагноза пациенту
  • Выбор продукции
  • Вход и регистрация
  • Доставка
  • Оплата

Вот как это выглядит (отображение раздела анкеты):

Наш общий подход заключается в использовании библиотеки single-spa для разделения приложения Assessment на независимые микроприложения и их независимого переноса. Single-spa предоставляет несколько утилит для загрузки / удаления новых приложений в зависимости от активного URL-адреса. Это также позволяет разделять зависимости между ними.

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

Этот гибридный подход выглядит так:

Мы уже используем single-spa в других клиентских приложениях, и это значительно упростило нам процесс миграции.

Мы также перешли с WebDriverIO на Cypress для сквозного тестирования виджета и начали тестирование виджета в различных контекстах: автономный виджет, виджет внутри других приложений.

Что мы узнали на данный момент?

  • Vue-cli отлично подходит для проектов строительных лесов, поддерживая процесс сборки в актуальном состоянии и синхронизируя между проектами.
  • Трудно организовать работу над общими компонентами, если у вас есть кросс-функциональные независимые команды.
  • Использование белых этикеток особенно сложно, поскольку вы можете предоставить разные степени настройки. Сужение требований помогло сдвинуть дело с мертвой точки.
  • С Vue и Jest тестирование стало намного проще, чем с Angular.js

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

В качестве следующих шагов мы планируем:

  • Объедините усилия независимых команд для объединения нескольких реализаций компонентов в общую библиотеку.
  • Добавить визуальное регрессионное тестирование общих компонентов
  • Принять стандартные инструменты - отслеживание, A / B-тестирование для использования с приложениями Vue.
  • Начать рендеринг компонентов Vue на стороне сервера

Это позволит нам легко масштабировать Zava для нескольких брендов, иметь согласованный дизайн и реализацию, а также быстро экспериментировать с идеями.

Спасибо Ramón García, Gemma Goode и Mati Shomrat за помощь и рецензирование этого поста, Michele Stara за прекрасную обложку и всем из команды Zava Engineering за идеи.