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

Чтобы ускорить сборку, разработали систему из шаблона и CLI утилиты. Теперь новый микрофронтенд со всей обвязкой создается за 20 минут. В статье — подробное решение для тех, кто захочет повторить.

Как поняли, что пора шаблонизировать микрофронтенды

Пока микрофронтендов было немного, над скоростью их создания не задумывались: такие задачи поступали раз в несколько месяцев, и не страшно было потратить лишний час. Наши микрофронтенды имеют базовую структуру каталогов, повторяющиеся настройки, например, тулинг и линтинг, и предустановленные библиотеки, записанные в package.json (подробнее о том, как устроен пайплайн поставки микрофронтендов на продакшен, рассказали в отдельной статье). Чтобы создать новый микрофронтенд, мы копировали старый, удаляли ненужные библиотеки и куски кода и переименовывали шаблонные строки, например _template_frontend_name_ — затем можно было работать.

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

Как работает система автоматической сборки из шаблона и утилиты 

Наше решение состоит из двух частей: 

  • Шаблонного микрофронтенда. Это репозиторий в GitHub, для которого выставлена настройка Template repository. Он включает все, что требуется для нового микрофронтенда: стандартную структуру каталогов; стандартные файлы конфигураций для тулинга (.releaserc.js, commitlint.config.js, .eslintrc.js) и package.json с вписанными заранее зависимостями и парочкой specific полей.

  • CLI утилиты, которая создает новый микрофронтенд из шаблона. Она написана на Node.js и поставляется в виде NPM-библиотеки, которую можно запустить командой npx, не устанавливая на локальный компьютер.

Чтобы создать новый микрофронтенд, нужно:

  1. Открыть страницу шаблона в GitHub.

  2. Нажать «Use this template» → «Create a new repository».

  3. Указать имя нового микрофронтенда.

  4. Склонировать созданный репозиторий на компьютер.

  5. В корне репозитория запустить CLI.

CLI выполнит определенные действия, и микрофронтенд будет готов к работе.

Стоп, что за «определенные действия»?

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

Откуда взялись теги <% и %>

Это кастомный вариант замены template-тегов {{ и }}. Для этого есть причина — символы { и } стандартные для Mustache и Handlebars, если будем использовать их для template-тегов, все смешается. Поэтому для переменных внутри файлов используем теги <% и %>

Мы также хотим использовать переменные в названиях файлов, но символы < и > зарезервированы в Windows, поэтому для переменных в названии файла используем символ _

Так получился набор template-тегов:

  • <% и %> для переменных внутри файла,

  • _% и %_ для переменных в пути файла.

При запуске CLI задает вопросы, чтобы понять, какие переменные подставить в шаблон. Опрос реализован с помощью Enquirer. Например, CLI запрашивает название namespace — это техническое название микрофронтенда в Mindbox:

В шаблоне эта переменная может использоваться в любом месте, даже в названии файла. Например:

Перед названием переменной есть модификатор camelCase. Он позволяет модифицировать её во время рендера:  в нашем случае приводит переменную namespace в формат camelCase. CLI проходится по всем файлам в будущем микрофронтенде, находит и рендерит шаблонные переменные через шаблонизатор. 

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

CLI в репозитории frontend-awesome с настройкой namespace: "awesome" выдаст такой результат:

Итоговый код
import React, { FC, useCallback } from 'react';
import { RouteComponentProps } from '@reach/router';
import { useErrorLogger } from '@mindbox-cloud/frontend-error-logging';
import { Button, GridItem, PageWrapper } from '@mindbox-cloud/ui-components';
import { trl } from '@mindbox-cloud/frontend-i18n';

export const ErrorLoggingScreen: FC<RouteComponentProps> = () => {
  const logger = useErrorLogger();

  const handleSendInfoToErrorLoggingSystem = useCallback(() => {
    logger.info('frontend-awesome message', (scope) => {
      scope.setTag('source', 'frontend-awesome');
      scope.setExtra('is_test', true);
    });
  }, [logger]);

  return (
    <PageWrapper>
      <GridItem>
        <h1>Error logging screen</h1>
      </GridItem>

      <GridItem>
        <Button type="primary" onClick={handleSendInfoToErrorLoggingSystem}>
          {trl('awesomeFrontend:SendMessageToErrorLoggingSystem')}
        </Button>
      </GridItem>
    </PageWrapper>
  );
};

CLI и автозамена позволяют создать микрофронтенд за 20 минут, на который при копировании ушел бы час. 

Если копировать файлы

С помощью Ctrl+Shift+R прошлись по всему проекту, нашли строку _template_frontend_name_ и вписали название микрофронтенда. 

Повторили с остальными переменными.

Учли, что переменные могут быть написаны в разных форматах, и вручную привели переменные к нужному формату. Например, формат camelCase используется в свойствах объектов, а формат PascalCase — в названиях компонентов.

Готово!

С CLI и автозаменой

Запустили CLI в проекте, указали в нем namespace: "my-awesome".

Готово!

Почему с микрофронтендом можно работать сразу после создания

При работе с любыми шаблонными решениями могут возникать проблемы. Например, шаблон создан на старой версии Node.js со старыми версиями зависимостей, и при запуске на новой версии Node.js зависимости оказываются несовместимы с ней. Или кто-то поменял шаблонный код, сломал типизацию — микрофронтенд не запустится.

Чтобы предотвратить эти проблемы, в репозитории нашего шаблона есть несколько команд, которые проверяют наличие ошибок в типизации, скриптах и стилях. Эти статические проверки гарантируют, что с вероятностью 99% с шаблоном всё в порядке и новый микрофронтенд запустится без проблем.

Несколько команд для проверки:

Чтобы поддерживать актуальные версии зависимостей, у нас реализован непрерывный процесс обновления зависимостей через Renovate. Он регулярно проходится по репозиторию шаблона и пытается автоматически обновить минорные (1.X.0) и патч-версии (1.0.X) зависимостей: создает Pull Request и, если обновление успешно установлено, мерджит его в main ветку. Если Pull Request с обновлением упал с ошибкой, то разработчику придётся прийти и самостоятельно её поправить. Подробнее, что такое Renovate и как он работает, можно узнать на официальном сайте

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


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

А сейчас можете посмотреть исходный код CLI, который мы используем.

Комментарии (2)


  1. gun_dose
    26.06.2024 15:39
    +1

    Я правильно понимаю, что микрофронтенд должен брать данные с микробэкенда? При этом микросервисы для микробэкенда уже не годятся, и нужны наносервисы?