Микрофронтенды

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


Структура приложения

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

  • components/ — набор UI-компонентов, каждый со своим .marko шаблоном и .js логикой.
  • pages/ — страницы приложения, объединяющие несколько компонентов.
  • services/ — взаимодействие с внешними API или микросервисами.
  • layouts/ — базовые шаблоны страниц для единообразного оформления.

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


Компоненты Marko

Компонент Marko состоит из трёх ключевых элементов:

  1. Шаблон (.marko) — описывает разметку HTML с возможностью включения логики через директивы и выражения.
  2. Скрипт (.js) — управляет состоянием компонента и его поведением.
  3. Стили (.css/.scss) — локальные или глобальные стили для компонента.

Пример базового компонента:

<template>
  <div class="card">
    <h2>${input.title}</h2>
    <p>${input.description}</p>
  </div>
</template>

<script>
  export default class {
    onCreate() {
      console.log('Компонент создан');
    }
  }
</script>

<style>
  .card {
    border: 1px solid #ccc;
    padding: 16px;
    border-radius: 8px;
  }
</style>

Каждый компонент может быть независимым микрофронтендом, особенно если он взаимодействует с отдельным API или имеет собственную маршрутизацию.


Интеграция микрофронтендов

Существует несколько подходов к интеграции микрофронтендов в Marko:

  1. Сборка на уровне сервера (Server-Side Composition) Используется для интеграции разных приложений на сервере, где каждая часть рендерится отдельно и объединяется в общий HTML. Подходит для SEO-оптимизированных страниц.

  2. Клиентская интеграция (Client-Side Composition) Отдельные микрофронтенды загружаются динамически через import() или через Web Components. Marko поддерживает динамический импорт компонентов:

<await(import('./header.marko')) render(header => header) />
  1. Фреймворки для маршрутизации микрофронтендов В крупных приложениях рекомендуется использовать отдельные маршрутизаторы для каждого микрофронтенда, что позволяет минимизировать зависимости и избежать конфликтов состояния.

Управление состоянием

Marko предлагает несколько подходов к управлению состоянием компонентов:

  • Локальное состояниеthis.state внутри компонента, используется для UI-логики.
  • Глобальное состояние — через интеграцию с внешними store, например, Redux, MobX или простыми EventEmitter-паттернами.
  • Props и события — обмен данными между компонентами через входные свойства (input) и кастомные события (this.emit()).

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


Асинхронные данные

Микрофронтенды часто требуют загрузки данных с разных сервисов. Marko поддерживает асинхронные операции на сервере и клиенте:

<await(input.dataPromise) render(data => {
  return <div>${data.title}</div>;
}) />

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


Роутинг и навигация

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

  • Маршрутизация на сервереexpress или fastify с маршрутизацией для разных приложений.
  • Клиентская навигация@marko/run и marko-router позволяют обновлять компоненты без полной перезагрузки страницы.

Оптимизация производительности

Использование микрофронтендов требует особого внимания к производительности:

  • Ленивая загрузка компонентов через динамический импорт.
  • Кэширование API-запросов на уровне сервера.
  • Минимизация пересборки CSS и JS с помощью bundler’ов (Vite, Webpack).
  • Изоляция стилей и скриптов для предотвращения конфликтов между микрофронтендами.

Взаимодействие с внешними сервисами

Микрофронтенды часто общаются с внешними API или микросервисами. В Marko рекомендуется использовать сервисный слой (services/) для всех внешних вызовов. Пример запроса через fetch:

export async function fetchUser(id) {
  const response = await fetch(`https://api.example.com/users/${id}`);
  if (!response.ok) throw new Error('Ошибка при загрузке пользователя');
  return response.json();
}

Компонент может затем использовать этот сервис:

<await(fetchUser(input.userId)) render(user => <UserCard user=user/>) />

Разделение кода и деплой

Каждый микрофронтенд должен быть автономным:

  • Собственный билд — отдельные JS и CSS.
  • Контейнеризация — возможность деплоя как независимого сервиса.
  • Версионирование — минимизация рисков при обновлении отдельных компонентов.

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


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