Тема
Настройка host и remote
Эта страница настраивает только загрузку remote module. Перед ней прочитайте Bootstrap и mount.
Рекомендуемая структура
text
apps/
shell/ host application
billing-remote/ remote application
packages/
contracts/ TypeScript bootstrap/API contractscontracts не создаёт runtime singleton и не содержит React UI. В нём лежат только interface/type, которые одинаково видят host и remote.
Shared dependencies
React, React DOM, MobX и Query Layer должны быть singleton в одной странице. Иначе можно получить две React runtime, две MobX reactive graph или разные версии scoped protocol.
ts
// Общая часть Webpack/Rspack federation config.
export const shared = {
react: {
singleton: true,
requiredVersion: "^19.0.0",
},
"react-dom": {
singleton: true,
requiredVersion: "^19.0.0",
},
mobx: {
singleton: true,
requiredVersion: "^7.0.3",
},
"mobx-react-lite": {
singleton: true,
requiredVersion: "^5.0.0",
},
"@dubium/query-layer": {
singleton: true,
// Текущий workspace — 1.0.0-rc.1; ^1.0.0 не включает prerelease.
requiredVersion: "^1.0.0-rc.1",
},
axios: {
singleton: true,
requiredVersion: "^1.7.0",
},
}Точный синтаксис зависит от federation plugin. Инвариант один: host и remote должны согласовать совместимые версии. Для Query Layer 1.0 RC требуется MobX 7; mobx-react-lite 5 требует React 18 или новее. Не смешивайте MobX 6 и 7 в federation graph: singleton должен разрешиться в один экземпляр MobX 7.
Host config
ts
new ModuleFederationPlugin({
name: "shell",
// Alias billing будет использоваться в import("billing/bootstrap").
remotes: {
billing: "billing@https://billing.example.com/remoteEntry.js",
},
shared,
})Remote URL берите из доверенной конфигурации окружения. Не разрешайте пользователю подменить origin через query string.
Remote config
ts
new ModuleFederationPlugin({
name: "billing",
filename: "remoteEntry.js",
// Host видит только bootstrap boundary.
exposes: {
"./bootstrap": "./src/bootstrap.tsx",
},
shared,
})Не публикуйте отдельными exposes внутренние stores, token provider и Axios client. Host должен зависеть только от bootstrap contract.
Type declaration динамического import
ts
declare module "billing/bootstrap" {
import type { BillingRemoteModule } from "@portal/contracts"
export const mount: BillingRemoteModule["mount"]
}Так TypeScript проверит, что host передал все обязательные bootstrap options.
Локальные адреса
| Часть | URL |
|---|---|
| Host | http://127.0.0.1:3000 |
| Billing remote entry | http://127.0.0.1:3001/remoteEntry.js |
| Backend | http://127.0.0.1:3100 |
CORS для remote chunks и CORS backend — разные настройки. Разрешение загрузить JavaScript remote не должно автоматически открывать API любому origin.
Deployment
- remote chunks публикуются с content hash;
remoteEntry.jsимеет контролируемый cache policy;- host знает фактическую версию remote;
- rollback remote не требует пересборки host;
- несовместимый protocol отклоняется до UI mount;
- URL remote входит в allowlist host.
Что должно работать перед runtime
Проверьте:
import("billing/bootstrap")завершается успешно;remote.mount({ container })показывает UI;- returned disposer удаляет React tree;
- повторный mount/unmount не оставляет listeners;
- shared React/MobX загружены в одном экземпляре.
Теперь можно создать root runtime в host: Runtime в host.