Как вы реализуете микрофронтенды с 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-приложений с несколькими командами разработки.