Это переработанная инструкция из статьи 🛠️
Так же есть описание других boilerplate 🛠️
Так же есть описание remote React app и react-wrapper для Angular в этом репозитории есть примеры 🛠️
- angular CLI
- angular 16
- node 18.17.1
- npm 8.19.4
- nvm 1.11.1
- Он позволит добавить webpack config для проектов и преднастроить его
- @angular-architects/module-federation
- Создание без основного приложение
ng new YOUR_PROJECT_NAME --create-application=false- Генерация нового подпроекта - он будет главным
host
ng g application host --routing --style=scss- Добавить к этому проекту компоненты:
ng g c home --project=hostapp-routing.module.tsнастроить там Routes
const routes: Routes = [
{
path: "",
component: HomeComponent,
pathMatch: "full",
},
];- Упростить компонент
app.component.tsдо:
<h1>Module Federation HOST</h1>
<router-outlet></router-outlet>- Генерация нового подпроекта это будет уже дополнительный микрофронтенд корзина
cart
ng g application cart --routing --style=scss- Добавить к этому проекту компоненты:
ng g c home --project=cart- Добавить модуль и компонент к нему
ng g m cartfeature --routing --project=cart
ng g c cartfeature --project=cartcartfeature.module.tsнастроить там Routes
const routes: Routes = [
{
path: "",
component: CartfeatureComponent,
pathMatch: "full",
},
];app-routing.module.tsтеперь чуть сложнее, там настроить там Routes + lazy
const routes: Routes = [
{
path: "",
component: HomeComponent,
pathMatch: "full",
},
{
path: "cart",
loadChildren: () =>
import("./cartfeature/cartfeature.module").then(
(m) => m.CartfeatureModule
),
},
];- Упростить компонент
app.component.tsдо:
<h1>Module Federation CART</h1>
<a routerLink="/">Home</a>
<a routerLink="/cart">Cart</a>
<router-outlet></router-outlet>- Добавить к host
ng add @angular-architects/module-federation --project host --port 4200- Добавить к cart
ng add @angular-architects/module-federation --project cart --port 5000- В
package.jsonдобавить секциюresolutionsна данный момент Angular 16 версии, выбрал такие версии пакетов может быть нужно уточнить детали если версия уйдёт далеко вперёд.
"resolutions": {
"webpack": "^5.61.0",
"license-webpack-plugin": "^3.0.1"
},- В проекте host к
app-routing.module.tsдобавить
{
path: 'cart',
loadChildren: () =>
import('cart/CartfeatureModule').then((m) => {
return m.CartfeatureModule;
}),
},- Что бы проект собирался с отсутствующим
cart/CartfeatureModuleт.к. он будет только в runtimeе нужно прописать в файлdecl.d.ts` он располагается в ../projects/host/src
declare module "cart/CartfeatureModule";- Запустим host
ng serve host - Запустим cart
ng serve cart
- Если вы делаете проект в нормальном каталоге, просто новом, и для vscode он корневой тогда можно просто использовать что сгенерит vscode по умолчанию В моём случае так
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve HOST",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng serve CART",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:5000/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}-
Запускаем по порядку
-
host приложение
ng serve host --host=127.0.0.1 -
cart приложение
ng serve cart --host=127.0.0.1 -
Жмём
F5 -
Нужно понимать, что мы в remote указали только
CartfeatureModule. Соответственно доступный для debug`а код будет загружен только из него. -
Но при этом, если открывать сам микрофронтенд по
localhost:5000то тут уже доступен debug всего, но только конкретно этого микро-фронтенда.
- Способ 1 - предварительная подгрузка remoteEntry скрипта
{
path: 'cart',
loadChildren: () =>
import('cart/CartfeatureModule').then((m) => {
return m.CartfeatureModule;
}),
},- Способ 2 - полное ожидание до момента обращения к remote с помощью loadRemoteModule, что позволит загружать host приложение, даже если в перспективе есть ошибки в загружаемом remoteEntry скрипте. Используя Способ 1 наверное безопасней, но не запустит всё приложение если есть проблемы во внешнем коде.
{
path: 'cart',
loadChildren: () =>
loadRemoteModule({
type: 'module',
remoteEntry: 'http://localhost:5000/remoteEntry.js',
exposedModule: './CartfeatureModule',
}).then((m) => m.CartfeatureModule),
},- Создаём новое
npx create-react-app react_module_federation- Внутри
react_module_federationставим:
npm install --save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader-
Запустим для проверки
npm run startоткроется стандартный boilerplate react -
Основная проблема в том что react dev server отдаёт не модуль, а html и компилирует в процессе, из-за этого MF host не может получить модуль как код. Нужно понять как делается преобразование на лету.
-
Нужен wrapper для react. в этом репозитории есть примеры репозиторий староват, но даёт представление.