Как вы реализуете микрофронтенды с Angular?

Реализация микрофронтендов (Micro Frontends, MFE) с использованием Angular предполагает разбиение большого фронтенд-приложения на независимые, изолированные модули, каждый из которых можно разрабатывать, разворачивать и масштабировать независимо. Angular хорошо подходит для этого подхода благодаря поддержке модульной архитектуры, Angular CLI и Webpack Module Federation (в Angular 12+).

1. Подходы к реализации микрофронтендов

1.1 Module Federation (Webpack 5)
Основной современный способ реализации микрофронтендов в Angular — использование Webpack Module Federation, который позволяет загружать Angular-приложения (или их части) на лету.

1.2 iframe/isolated shell
Используется в случае полной изоляции между частями (разные версии Angular, сторонние фреймворки).

1.3 Single-spa
Фреймворк-агностичный роутинг-движок для запуска нескольких фронтендов в одном приложении.

2. Module Federation в Angular

С Angular 12+ (и @angular-architects/module-federation) можно настроить микрофронтенды с Webpack 5.

Шаг 1. Создание проектов

Создаются два (или более) проекта:

  • host-app — контейнер/оболочка

  • remote-app — микрофронтенд

ng new host-app --routing --style=scss
ng new remote-app --routing --style=scss

Шаг 2. Установка plugin'а

ng add @angular-architects/module-federation --project host-app
ng add @angular-architects/module-federation --project remote-app

Шаг 3. Конфигурация webpack.config.js

В remote-app:
// webpack.config.js
const { withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
name: 'remoteApp',
exposes: {
'./Module': './src/app/remote/remote.module.ts',
},
shared: {
"@angular/core": { singleton: true, strictVersion: true },
"@angular/common": { singleton: true, strictVersion: true },
"@angular/router": { singleton: true, strictVersion: true },
}
});
В host-app:
remotes: {
remoteApp: "remoteApp@http://localhost:4201/remoteEntry.js"
}
#### **Шаг 4. Использование в маршрутизации**
const routes: Routes = \[
{
path: 'remote',
loadChildren: () =>
loadRemoteModule({
type: 'module',
remoteEntry: 'http://localhost:4201/remoteEntry.js',
exposedModule: './Module'
}).then(m => m.RemoteModule)
}
\];

Шаг 5. Запуск

cd remote-app && ng serve --port 4201
cd host-app && ng serve --port 4200

3. Архитектура и изоляция

Изоляция на уровне:

  • Зависимостей — каждая команда может использовать свою версию Angular или сторонних библиотек (в iframe или с sandbox-изоляцией);

  • Маршрутизации — каждый микрофронтенд может иметь собственную маршрутизацию;

  • Данных и состояний — обмен осуществляется через событийную шину, shared сервисы или global store (например, через RxJS, NgRx, custom EventBus);

  • CI/CD — каждый микрофронтенд может быть развёрнут независимо и загружаться по URL.

4. Обмен данными

Через сервис EventBus (RxJS):

@Injectable({ providedIn: 'root' })
export class EventBusService {
private events$ = new Subject<any>();
emit(event: any) {
this.events$.next(event);
}
on(): Observable<any> {
return this.events$.asObservable();
}
}

Через customElement + DOM события (для встроенных микрофронтов):

const event = new CustomEvent('user-logged-in', { detail: user });
window.dispatchEvent(event);

5. Версионирование и CI/CD

  • Каждый MFE может иметь свой pipeline, repo, версию;

  • Разворачивается как статический SPA на CDN (например, remoteEntry.js);

  • В host-app можно динамически подставлять URL через env, manifest.json или внешние конфиги;

  • Важно кэшировать через hash, чтобы не ловить кеш-баги.

6. Поддержка standalone компонентов (Angular 15+)

Можно экспортировать standalone компоненты напрямую:

exposes: {
'./LoginComponent': './src/app/login/login.component.ts',
}

Затем загружать и использовать как часть другого standalone-приложения.

7. Использование single-spa

Если микрофронтенды написаны на разных фреймворках (React, Vue, Angular), используется single-spa:

  • Каждый микрофронт — приложение со своей жизнью;

  • Устанавливается адаптер: single-spa-angular;

  • Регистрация через registerApplication();

  • Интеграция через custom DOM-элементы и события.

8. Подход с iframe (в крайнем случае)

Если необходимо полное разделение (разные домены, фреймворки, Angular версии), используют iframe:

  • Обмен данными через postMessage;

  • Нет общего роутинга;

  • Высокая изоляция, но сложный UX (прокрутка, интеграция, SSR).

9. SSR и микрофронтенды

SSR с Angular Universal в микрофронтах возможен, но требует доп. настройки:

  • SSR должен рендерить как shell, так и части remoteEntry (или вставлять stub с динамической заменой на клиенте);

  • Чаще микрофронты рендерятся только на клиенте (SPA), а SSR — только оболочка.

10. Проблемы и ограничения

  • Управление зависимостями и конфликты (singleton/shared);

  • Миграция remote-приложений при обновлении Angular;

  • Общие стили — возможны конфликты, рекомендуется ViewEncapsulation или Shadow DOM;

  • Тестирование и E2E сложнее, нужно учитывать загрузку модулей.

Эффективная реализация микрофронтендов в Angular требует чёткого разделения ответственности, использования Module Federation или Single-SPA, продуманной схемы обмена данными и изоляции. Подход особенно эффективен для масштабируемых enterprise-приложений с несколькими командами разработки.