1 of 74

Micro frontends

2 of 74

CONTENTS

Frontend Monolith

Micro frontends

Domain Driven Design (DDD)

Native Module federation 🚀

Communication micro frontends

3 of 74

Peter Eijgermans

@EijgermansPeter

4 of 74

Monolith - big ball of Mud

Database

Application

5 of 74

Frontend layer

Backend layer

Database layer

Database

6 of 74

Frontend Monolith

the Frontend

DB

DB

DB

DB

DB

DB

DB

Backend

Microservices

7 of 74

Micro frontends �are born!

8 of 74

Short definition Micro frontends

“An architectural style where independently deliverable frontend applications are composed into a greater whole”

9 of 74

Micro frontends as Verticals

Team A

F

Team A

E

D

B

B

C

DB

DB

DB

DB

DB

DB

DB

B

C

F

D

E

Frontend

Backend

Host / Container / Shell

10 of 74

Why micro frontends?

Incremental Upgrades

Simple Codebases

Independent Deployment

Autonomous Teams

Tech Agnostic

Modularity

Reusability

11 of 74

But…

How to define my Verticals?

12 of 74

Use DDD !

Domain Driven Design

13 of 74

Why DDD for Micro frontends?

Alignment Business capabilities

Shared understanding

Clearer Boundaries

Modular design

Continuous Evolution

14 of 74

How to apply DDD?

15 of 74

Event booking platform !

16 of 74

Identify subdomains

Event

Event detail

Planning

Reservation

Invoice

Payment

Event

Booking

Event

Customer

Ticket

account

account detail

Event detail

Query events

17 of 74

Identify subdomains

Event

Event detail

Planning

Reservation

Invoice

Payment

Event

Booking

Event

Customer

Ticket

account

account detail

Event detail

Query events

18 of 74

Identify subdomains

Event

Event detail

Planning

Reservation

Invoice

Payment

Event

Booking

Event

Customer

Ticket

account

account detail

Event detail

Query events

19 of 74

Define Bounded Contexts

Event

Event detail

Planning

Reservation

Invoice

Payment

Event

Booking

Event

Customer

Ticket

account

account detail

Reservation

Booking

Account

Query events

Event

20 of 74

Bounded Contexts as Micro frontends

Event

Account

Reser

vation

Booking

Frontend

Backend

Host / Container

Event

Booking

Account

DB

Reser

vation

DB

DB

DB

21 of 74

Bounded Contexts as Micro frontends

Event

Account

Reser

vation

Booking

Frontend

Backend

Host / Container

Event

Booking

Account

DB

Reser

vation

DB

DB

DB

22 of 74

23 of 74

Micro-frontend Outdoor Events

Container

BrowserRouter - Shared component

Micro-frontend Search Event

24 of 74

25 of 74

Micro-frontend Reservation

Container

BrowserRouter - Shared component

26 of 74

How to develop this

Micro frontend?

27 of 74

Module �Federation

28 of 74

What is Module Federation?

Loads remote modules (MF) at runtime

Allows sharing dependencies

Modules Lazy loaded

Runtime code sharing

29 of 74

Module Federation options

Native Federation 🚀🚀

🚀

30 of 74

How?

31 of 74

Roles?

Host / Container / Shell

remotes: {

outdoorevents:"outdoorevents@http://...”

reservation: "reservation@http://..”

}

Micro frontend 1

name:"outdoorevents",

exposes: {

./OutdoorEvents.tsx

}

Micro frontend 2

name:"reservation",

exposes: {

./OutdoorEvent.tsx

}

32 of 74

Host / Container / Shell

remotes: { reservation:”reservation@http://./remoteEntry.js

},

shared: {

React: {

singleton: true,

requiredVersion: 18.0.0

strictVersion: true

}

}

Micro frontend (= Remote)

name: "reservation",

filename: "remoteEntry.js",

exposes: {

"./OutdoorEvent":"./src/OutdoorEvent.tsx"

},

shared: {

React: {

singleton: true,

requiredVersion: 17.2.0

}

}

33 of 74

Version mismatch shared lib

Rule:

Take the highest compatible version !

34 of 74

Version mismatch shared lib

singleton = true

Host version: 18.0.0 Mfe version: 17.2.0

Only load 18.0.0

Host version: 18.0.0 Mfe version: 18.1.0

Only load 18.1.0 (is highest compatible version)

35 of 74

Version mismatch shared lib

singleton = false

Host version: 18.0.0 Mfe version: 17.2.0

Load both, big bundle size !

Host version: 18.0.0 Mfe version: 18.1.0

Only load 18.1.0 (is highest compatible version)

36 of 74

singleton = false

Search

event

Outdoor

events

Reser-

vation

Module

Federation

“Remotes”

Host / Container

React

Module

Federation

“Host”

React

React

React

37 of 74

singleton = true

Search

event

Outdoor

events

Reser-

vation

Module

Federation

“Remotes”

Host / Container

Module

Federation

“Host”

React

38 of 74

Webpack

Module �Federation�

39 of 74

Steps

Step 1. Generate Container

Step 2. Generate Micro Frontends

Step 3. Change Configurations

Step 4. Implement Components

npx create-mf-app

npx create-mf-app

Step 5. Implement Routing

40 of 74

npx create-mf-app

41 of 74

Step 1 Generate Container

microfrontends-in-action ❯ npx create-mf-app

? Pick the name of your app: container

? Project Type: Application

? Port number: 3000

? Framework: (Use arrow keys)

lit-html

mithril

preact

react

solid-js

svelte

vue3

42 of 74

Step 2 Generate Micro Frontends

microfrontends-in-action ❯ npx create-mf-app

? Pick the name of your app: outdoor-events

? Project Type: Application

? Port number: 3002

? Framework: (Use arrow keys)

lit-html

mithril

preact

react

solid-js

svelte

vue3

43 of 74

44 of 74

Step 3 Change configurations

Host / Container / Shell

remotes: {

outdoorevents:"outdoorevents@http://...”

reservation: "reservation@http://..”

}

Micro frontend 1

name:"outdoorevents",

exposes: {

./OutdoorEvents.tsx

}

Micro frontend 2

name:"reservation",

exposes: {

./OutdoorEvent.tsx

}

45 of 74

Step 4 Implement Components

export default function OutdoorEvents() {� return (� <div>� <h1>Outdoor Events . . . .</h1>� <div>� {outdoorEvents.map(event => (� <Cardtitle={event.title}� image={event.image}� slug={event.slug}� />� ))}� </div>� </div>� );�}��function Card({title, image, slug}) {� return (� <div>� <img src={image} />� <div>� <h2>{title}</h2>� <Link to={`/outdoorEvents/${slug}`}>Reservation</Link>� </div>� </div>� );�}

46 of 74

Step 5 Implement Routing

Micro frontend 1

name:"outdoorevents",

exposes: {

./OutdoorEvents.tsx

}

Micro frontend 2

name:"reservation",

exposes: {

./OutdoorEvent.tsx

}

"/outdoorEvents/:slug

47 of 74

Native

Module �Federation�

48 of 74

Native Module Federation 🚀

Browser-native implementation 🚀

Independently of build tools and frameworks 🧰

Mental model as Module Federation 𝌭

Embraces Import maps & EcmaScript modules

Blazing fast

49 of 74

Layered Architecture

@angular-architects/native-federation

@softarc/native-federation

@gioboa/vite-module-federation

yours

Native Federation Core

50 of 74

h

Native Federation

Your Bundler

Your Adapter

51 of 74

Comparison

Webpack Module Federation

Native Federation

Very Fast

Easy to use

Buildtools agnostic

Small community

Least Mature

Slower

More difficult

Dependent on Webpack

Large community

Mature

More plugins and tools

Caches shared dep

Lazy loading

Lazy loading

Maximum flexibility

🚀

52 of 74

Example Apps

53 of 74

Communication between Micro frontends�

Routing

CustomEvent Web API

Pub Sub

Shared state

54 of 74

55 of 74

Live coding Shopping cart

OutdoorEvents

Layout

Header.tsx

CustomEvent: addToCart

56 of 74

const increment = () => {

const action = {

detail: { action: 'increment' },

};

const event = new CustomEvent('ADD_TO_CART', action);

document.dispatchEvent(event);

};

57 of 74

export default function Header() {

const [count, setCount] = useState(0);

useEffect(() => {

const handleIncrement = () => {

setCount((prevCount) => prevCount + 1);

};

const handleCustomEvent = (event) => {

if (event.detail.action === 'increment') {

handleIncrement();

}

};

document.addEventListener('ADD_TO_CART', handleCustomEvent);

return () => {

document.removeEventListener('ADD_TO_CART', handleCustomEvent);

};

}, [count]);

58 of 74

59 of 74

Peter Eijgermans

@EijgermansPeter

60 of 74

Peter Eijgermans

@EijgermansPeter

const increment = () => {

const action = {

detail: { action: 'increment' },

};

const event = new CustomEvent('ADD_TO_CART', action);

document.dispatchEvent(event);

};

const [count, setCount] = useState(0);

useEffect(() => {

const handleIncrement = () => {

setCount((prevCount) => prevCount + 1);

};

const handleCustomEvent = (event) => {

if (event.detail.action === 'increment') {

handleIncrement();

}

};

document.addEventListener('ADD_TO_CART', handleCustomEvent);

return () => {

document.removeEventListener('ADD_TO_CART', handleCustomEvent);

};

}, [count]);

61 of 74

62 of 74

63 of 74

64 of 74

65 of 74

Monolith !!!

66 of 74

67 of 74

How fast can Indian Rhinoceroses run?

  1. 25 km per hour
  2. 40 km per hour
  3. 50 km per hour

68 of 74

How fast can Indian Rhinoceroses run?

  1. 25 km per hour
  2. 40 km per hour

C. 50 km per hour !!!

69 of 74

70 of 74

How do I survive the charging Rhino?

  1. Make yourself big and make a lot of noise
  2. Run away zigzag
  3. A tiger comes by
  4. My friend took a photo of the Rhino

71 of 74

click!

72 of 74

Micro

Agile

Independent

Adaptability

To survive

Strength and robustness

Easy to manipulate

73 of 74

74 of 74