Micro-Frontends-diagram.excalidraw
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
Micro-Frontends — Module Federation Topology + Composition Strategies
Text Elements
Module Federation Topology ^topology-label
Shell / Host Application ^shell-label Webpack Module Federation ^mf-label Shared: React, Router, Design System ^shared-deps
Team A: Product Catalog MFE ^team-a-label exposes: ./ProductList, ./ProductDetail ^team-a-exposes remoteEntry.js ^arrow-a-label
Team B: Shopping Cart MFE ^team-b-label exposes: ./Cart, ./Checkout ^team-b-exposes remoteEntry.js ^arrow-b-label
Team C: User Profile MFE ^team-c-label exposes: ./Profile, ./Settings ^team-c-exposes remoteEntry.js ^arrow-c-label
Each MFE is independently deployable, independently testable ^independent-label
Composition Strategies ^strategies-label
Build-Time ^build-time-label Compile together ^build-time-desc
Server-Side ^server-side-label SSI / ESI ^server-side-desc
Run-Time (Module Federation) ^runtime-label Load remotes at runtime ^runtime-desc
%%
Drawing
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"id": "topology-label",
"type": "text",
"x": 40,
"y": 20,
"width": 300,
"height": 24,
"text": "Module Federation Topology",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "top",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "shell-box",
"type": "rectangle",
"x": 40,
"y": 56,
"width": 700,
"height": 140,
"strokeColor": "#1971c2",
"backgroundColor": "#d0ebff",
"fillStyle": "solid",
"strokeWidth": 3,
"roughness": 1,
"opacity": 100
},
{
"id": "shell-label",
"type": "text",
"x": 280,
"y": 68,
"width": 220,
"height": 24,
"text": "Shell / Host Application",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "mf-label",
"type": "text",
"x": 270,
"y": 100,
"width": 240,
"height": 20,
"text": "Webpack Module Federation",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 80
},
{
"id": "shared-deps-box",
"type": "rectangle",
"x": 60,
"y": 130,
"width": 660,
"height": 50,
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "shared-deps-text",
"type": "text",
"x": 70,
"y": 147,
"width": 640,
"height": 20,
"text": "Shared: React, Router, Design System",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "team-a-box",
"type": "rectangle",
"x": 40,
"y": 280,
"width": 200,
"height": 120,
"strokeColor": "#2f9e44",
"backgroundColor": "#d3f9d8",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "team-a-label",
"type": "text",
"x": 50,
"y": 292,
"width": 180,
"height": 36,
"text": "Team A:\nProduct Catalog MFE",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "team-a-exposes",
"type": "text",
"x": 50,
"y": 346,
"width": 180,
"height": 36,
"text": "exposes:\n./ProductList, ./ProductDetail",
"fontSize": 11,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-a",
"type": "arrow",
"x": 140,
"y": 278,
"width": 0,
"height": -82,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [0, -82]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "remoteEntry.js",
"fontSize": 11,
"strokeColor": "#2f9e44"
}
},
{
"id": "team-b-box",
"type": "rectangle",
"x": 290,
"y": 280,
"width": 200,
"height": 120,
"strokeColor": "#e67700",
"backgroundColor": "#ffe8cc",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "team-b-label",
"type": "text",
"x": 300,
"y": 292,
"width": 180,
"height": 36,
"text": "Team B:\nShopping Cart MFE",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "team-b-exposes",
"type": "text",
"x": 300,
"y": 346,
"width": 180,
"height": 36,
"text": "exposes:\n./Cart, ./Checkout",
"fontSize": 11,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-b",
"type": "arrow",
"x": 390,
"y": 278,
"width": 0,
"height": -82,
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [0, -82]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "remoteEntry.js",
"fontSize": 11,
"strokeColor": "#e67700"
}
},
{
"id": "team-c-box",
"type": "rectangle",
"x": 540,
"y": 280,
"width": 200,
"height": 120,
"strokeColor": "#7048e8",
"backgroundColor": "#e5dbff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "team-c-label",
"type": "text",
"x": 550,
"y": 292,
"width": 180,
"height": 36,
"text": "Team C:\nUser Profile MFE",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#7048e8",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "team-c-exposes",
"type": "text",
"x": 550,
"y": 346,
"width": 180,
"height": 36,
"text": "exposes:\n./Profile, ./Settings",
"fontSize": 11,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#7048e8",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-c",
"type": "arrow",
"x": 640,
"y": 278,
"width": 0,
"height": -82,
"strokeColor": "#7048e8",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [0, -82]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "remoteEntry.js",
"fontSize": 11,
"strokeColor": "#7048e8"
}
},
{
"id": "independent-text",
"type": "text",
"x": 40,
"y": 420,
"width": 700,
"height": 20,
"text": "Each MFE is independently deployable, independently testable",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#495057",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "strategies-label",
"type": "text",
"x": 40,
"y": 460,
"width": 300,
"height": 24,
"text": "Composition Strategies",
"fontSize": 15,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "top",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "build-time-box",
"type": "rectangle",
"x": 40,
"y": 500,
"width": 200,
"height": 90,
"strokeColor": "#495057",
"backgroundColor": "#f1f3f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "build-time-label",
"type": "text",
"x": 50,
"y": 514,
"width": 180,
"height": 20,
"text": "Build-Time",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#495057",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "build-time-desc",
"type": "text",
"x": 50,
"y": 546,
"width": 180,
"height": 36,
"text": "Compile together\n(couples releases)",
"fontSize": 11,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "server-side-box",
"type": "rectangle",
"x": 270,
"y": 500,
"width": 200,
"height": 90,
"strokeColor": "#495057",
"backgroundColor": "#f1f3f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "server-side-label",
"type": "text",
"x": 280,
"y": 514,
"width": 180,
"height": 20,
"text": "Server-Side",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#495057",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "server-side-desc",
"type": "text",
"x": 280,
"y": 546,
"width": 180,
"height": 36,
"text": "Server stitches fragments\nSSI / ESI",
"fontSize": 11,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "runtime-box",
"type": "rectangle",
"x": 500,
"y": 500,
"width": 240,
"height": 90,
"strokeColor": "#1971c2",
"backgroundColor": "#d0ebff",
"fillStyle": "solid",
"strokeWidth": 3,
"roughness": 1,
"opacity": 100
},
{
"id": "runtime-label",
"type": "text",
"x": 510,
"y": 514,
"width": 220,
"height": 20,
"text": "Run-Time (Module Federation)",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "runtime-desc",
"type": "text",
"x": 510,
"y": 546,
"width": 220,
"height": 36,
"text": "Shell loads remotes at runtime\n(recommended default)",
"fontSize": 11,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
}
],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}%%