Как стать автором
Обновить

Комментарии 21

Все так. Плюс несколько добавлений. Есть макро и микроприложения.
Макро — клей между микроприложениями. Он должен быть как можно легче и загружаться как можно быстрее, т.к. он присутствует на любой странице и грузится в любом случае.
Для 95% приложений не нужны микрофронты достаточно продуманного API на input и output и релиза раз в день.

Какие еще оверхеды несет микрофронт?
1. Частые билды вхолостую — например, когда меняется общий компонент — мы должны проверить типы во всех местах использования, чтобы убедиться, что ничего не сломано.
2. Появляется отдельная сервисная команда сопровождающая макроприложение, т.к. все хотят туда залезть, но кому-то нужно следить за консистентностью API.
3. Нетривиальный роутинг сделать не получится.
В идеальной картине мира — каждый микрофронт имеет свой namespace, а уже внутри него накручивает те урлы, что ему нужны. Но может быть нюанс, если на странице несколько микрофронтов с одинаковым неймспейсом — как быть тогда.
4. Обработка глобальных клавиш — постоянные коллизии для стрелочек, enter, esc, особенно если они все подписаны на window.

Возможно как-нибудь напишу статью о подводных камнях.

Странное название "макро" для клея между микроприложениями. Я бы скорее назвал его "ядро".

Кстати, у нас оно так и называется Core UI

Почему «Микрофронтенды», а не виджеты?
Мне без iframe не обойтись: если нужно быстро что-то просмотреть в диалоге и отправить на печать, то иначе никак.
Пример микро и макро фронтенда здесь.
Почему «Микрофронтенды», а не виджеты?

Повелось с того, что SPA называют фронтендом. А когда их много, то по аналогии с микросервисами, их стали называть микрофронтендами. Так подчеркивается их независимость: React + Vuejs, например. Также как и один микросервис на nodejs, а второй на Java.


Не могли бы вы поделиться, что значит "быстро что-то посмотреть", что такое диалог и какая у вас печатная логика в приложении?


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

Если перейти по ссылке, откроется регистрационно-контрольная форма, в ней вложения. При нажатии «быстрый просмотр» для pdf-файла открывается модальное окно в iframe с кнопочками от G.Chrome/MF.
Как это можно сделать без iframe, я не знаю. Если есть варианты, поделитесь, плиз.
Ниже есть поле «Более поздние обращения, ответы». Если нажать ссылку, открывается связанный документ, НЕ в iframe. Многооконное SPA :)

В "Быстром просмотре" у вас разношерстные документы, загружаемые пользователями.
Здесь мы получаем преимущество iframe: безопасность. Пользователь может загрузить документ с вредоносным скриптом, в случае iframe, скрипт не сможет ничего сделать, будет в песочнице.


Да и особых преимуществ от отображения таких документов не в iframe, а в embed-тегах мы не получим.


Тот факт, что "Более поздние обращения, ответы" сделано без iframe — это очень здорово.


Могу обратить ваше внимание на такой css


@media print {
  a[href^="http"]:not([href*="example.com"]):after {
    content: " (" attr(href) ")";
  }
}

@page :first {
  margin-top: 250pt;
}

Может помочь в разделении стилей для заполнения/для печати.

спасибо, прошу потратить 5 мин и описать словами, как работает ваш фрагмент css

Ну… я-то опишу, но в сети довольно много материала про @media запросы, включая всякие печатные стили.


Первый блок добавляет ссылкам их атрибут href. В результате, такая ссылка отобразится на листе бумаги или в предпросмотре на печать вот так:


В результате, такая ссылка ( https://developer.mozilla.org/en-US/docs/Web/CSS/attr ) отобразится на листе бумаги...

Там еще есть :not оператор, но это просто пример: ссылки, ведущие на example.com не будут отображены с раскрытием атрибута href.


А следующая директива @page добавит первой странице отступ сверху.
Тема печати в CSS довольно обширна. Например, можно применить свойство так, что каждый заголовок, скажем, <h2 /> будет печататься с новой страницы. Как будто мы вставили "разрыв страницы" в Word

И как ваш iframe в плане SEO и других парсеров? Индексируется вообще хоть что-то?

Приложение продается как коробочное решение, там SEO не нужно в принципе.
А так, я думаю, что SEO — еще один повод отказаться от iframe, и использовать монструозный SSR, который делает регидрацию всего и вся. Это, как мне кажется, отдельная задача.


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

Почему вместо компонентов решили пойти этим ужасным путем? iframe — это ещё та боль начиная от поддержки авторизации до передачи состояния от одного куска к другому. А дибажить это ещё то удовольствие.

Почему вместо компонентов

Ответ в начале статьи: iframe — проверенная годами кровавого ынтырпрайза технология, поэтому используем ее. </sarcasm>
А про поддержку авторизации я тоже описал в разделе "Бонусная проблема"


К сожалению, повлиять на экспертную оценку CTO не удалось. В чем присутствует и моя вина, возможно.

В чем проблема авторизации? В моем приложении с правами очень строго, если iframe грузится с того же сервера, никаких бонусов нет.
Ну как, к примеру у вас микро-уня которая отвечает за авторизацию там кнопки логина, регистрации, вспомнить пароль итп. В этом iframe происходит авторизация, затем полученный кук или жот-токен нужно передать в родительскую страницу, затем эти куки/токены нужно передать в другие iframe-ы, чтобы они могли дергать данные с сервера, а когда кука/токен устареет надо обновить и опять по цепочке…

Микросервисы на стороне сервера — это гуд потому, что при нагрузке эти сервисы будут размножатся, их удобно разрабатывать отдельно, ну и кучу там плюшек, а на фронте зачем это деление? На фронте нужно делить всё на компоненты, и пущай каждая команда пилит конкретные компоненты.
Ничего не понимаю :). Я залогинился на хабре, открываю разные статьи, — всюду авторизован. Тоже самое с iframe, — ничего никуда не передаю, и всюду присутствую под своим юзернэйм. Браузер сам передает нужный кук с авторизацией.
Я не фанат iframe, просто без них иногда не обойтись. Я уже писал выше об этом

Ручная передача кук нужна в случае разных доменов. Или саб-доменов.


Нам пришлось отказаться от манящей идеи сделать такой роутинг:


app1.domain.zone
app2.domain.zone
header.serviceapp.domain.zone
config.serviceapp.domain.zone

Отсюда получили кучу проблем с настройкой прокси, и внутренним роутингом.
Есть такая настройка у React Router: basename, очень помогла нам.


В итоге, каждое приложение имеет свой basename, которое оно берет из специального конфиг-файла. Он мог бы быть тоже микросервисом, но решили ограничиться простым config.json.

Сейчас как раз занимаюсь подобным. От от ифреймов откозался сразу. В итоге обычные js модули которые грузятся через import и экспортируют набор функции, которые определены на уровне API, где рендерить приложение определяет то самое Core UI на основе роутинга или исходя из разметки(виджеты). Core UI предоставляет вендор зависимости. Модули собираются без этих зависимостей. Модули общаются через «шину», которая внутри себя имеет 3 сущности — команды, запросы и евенты. Когда Приложение ренедриться, оно может зарегистрировать свои команды события и евенты, и общаться с другими приложением через эту шину, выполнять команды, запросы, слушать евенты. Самая сложное во всем этом было(в порядке уменьшения сложности) это сборка модулей, и организация дев окружения, релиз и деплой.

Расскажите поподробнее, пожалуйста!


  1. Как вы заставили собираться виджеты в случае, что вендорные зависимости поставляет Core UI? Как вы тестируете виджеты/микрофронтенды по отдельности?
  2. Какая у вас шина общения? Redux имеет прекрасный Devtools, к которому можно интегрировать любую другую библиотеку. Это очень интересная возможность, кстати.
  3. Каким образом у вас реализован роутинг?
  4. Особенности дев окружения? Может быть какие самописные плагины?
  5. Холостые релизы бывают?

Спасибо!

Как вы заставили собираться виджеты в случае, что вендорные зависимости поставляет Core UI?

я написал свой сборщик, основаный на rollup и Angular CLI Builder API. Верне как написал, до сих пор вношу изменения:). Core Ui знает что нужно для виджетов. При сборке, пробегает по этим зависемостям и собирает ES модули и генерирует import map. Когда собираеться виджет или приложение, используется тоже rollup и то что в Core Ui прописаны как вендор, в приложениях помечаются как внешние и не добавляются в сборку.
Как вы тестируете виджеты/микрофронтенды по отдельности?

виджеты/микрофронтенды у нас атомарные единицы, которые могут работать по отдельности. те процесс разработки и отладки не как не связана с Core UI. Как обычное веб приложение. e2e тесты проходят так же по отдельности(вернее планируется так, еще не дошли до этого)
Какая у вас шина общения? Redux имеет прекрасный Devtools, к которому можно интегрировать любую другую библиотеку. Это очень интересная возможность, кстати.


Шина самописная, она простая, просто позволяет реализовать через нее три действия комманда/запрос/событие. Я решил отказаться от стейта как такого тк, тогда получаеться связаность, а мы от этого хотели уйти. Каждое приложения или виджет имеет свой стейт если нужно. и общается через шину с другими если нужно. Ну и шина позволяет замокать что то на уровне разработке.

Каким образом у вас реализован роутинг?

Core Ui написан на angular, с самописным matcher'ом, часть роутинга на нем, дальше подключается, тот который используется в приложении. Если одному приложению надо перейти в другое, это делается через CoreUI, через шину отправляется комманда. У нас договореность на странице может быть только одно приложение которое работает с роутингом. и так же мы не используем вложенность одного приложения в другое, хотя для этого есть все возможности. Чтоб не закопаться в зависимостях.

Особенности дев окружения? Может быть какие самописные плагины?

Мы используем nx.dev и в целом большинство проблем исчезли. Туда же подключили кастомный билдер, которые собирает приложения как ES модули, включает в модулю ресурсы нужные заворачивает в npm и публикует.

Холостые релизы бывают?

nx.dev позволяет запускать сборки только того кода которые были изменены.

Было много маленьких проблем которые решали похожу дела. Как пример как фиксировать релизную версию. На какой стороне, на стороне CI/CD или вручную. Или вот пришлось реакт собирать по своему, тк реакт только как UMD модуль.

Спасибо большое за открытие такой находки как nx.dev!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации