SlideShare a Scribd company logo
Vue micro frontend
implementation patterns
Albert Brand
Who am I?
Albert Brand
Senior consultant @ Xebia
Pragmatic programmer
Proud husband & dad
twitter.com/al_bert_brand
medium.com/@albert.brand
linkedin.com/in/albertbrand
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 2
What is a micro frontend?
- Autonomously developed, tested and deployed frontend components
- Focused on a single business domain
- Implemented end-to-end by a team
- Offering more freedom and less dependencies for developers
- Very useful in a multi team setting
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 3
How can Vue help?
- Vue is an opinionated web framework
- Can build anything:
- large single page apps with client side routing; or
- a library of shared UI components; or even
- repackage as Web Components
- Easy to adjust to needs
- Not too much hard choices
Seems like a good match!
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 4
From monolith to disaster microservices
5
Single page app monolith
Browser Page
Server
Backend app
Frontend app
HTML Assets API API
6
Backend microservices
Browser Page
Server
App service
Frontend app
Micro
service
API
HTML Assets
Micro
service
Proxy
API
7
Frontend microservices
Browser Page
Server
App service
Micro
frontend
component
Micro
serviceAPI
HTML Proxy
Micro
service
Assets
HTML
Micro
frontend
component
Micro
serviceAPI
Micro
service
Assets
HTML
8
Domains
Browser Page
Server
Supportive
domain
Business
domain
Business
domain
9
Wait, why can't I use IFRAMEs?
10
More server side concatenation tools
- Server side includes
- Compoxure
- Tailor
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 11
Example page
Page
Menu
Footer
Product detail
Cart
12
Micro frontend domain division
Page
Menu
Footer
Product detail
Cart
13
Example repository structure
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 14
/renderer
/templates
/domain-navigation
/backend
/assets
/templates
/frontend
/src
/domain-product
... same
/domain-cart
... same
Local development HTTP servers
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 15
/renderer <- serves at
http://localhost:8000
/domain-navigation /backend <- serves at
http://localhost:9000
/domain-product/backend <- serves at
http://localhost:9001
/domain-cart/backend <- serves at
http://localhost:9002
Example page render GET request
- Renders a template with menu, cart, product and footer component
- Queries micro frontend endpoints
- Can be queried in parallel, slowest is bottleneck
- Need to handle failing micro frontend endpoint
- No / short cache period for endpoint result
- Returns rendered HTML page
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 16
Example renderer requests
http://localhost:9000/assets/frontend-assets.json
http://localhost:9000/menu
http://localhost:9000/footer
http://localhost:9001/assets/frontend-assets.json
http://localhost:9001/product-detail
http://localhost:9002/assets/frontend-assets.json
http://localhost:9002/cart
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 17
Frontend assets?
JSON structure that contains initial JS/CSS for the micro frontend component:
{
"css": ["/assets/css/app.a4393e1d.css"],
"js": ["/assets/js/app.938921fc.js"]
}
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 18
Navigation Vue JS entrypoint
import Vue from "vue";
import Menu from "@/components/Menu.vue";
import Footer from "@/components/Footer.vue";
new Vue({
el: "#menu",
render: h => h(Menu)
});
new Vue({
el: "#footer",
render: h => h(Footer)
}); Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 19
vue.config.js addition
module.exports = {
...
configureWebpack: {
plugins: [
new HtmlWebpackPlugin({
template: "templates/assets.ejs",
filename: "frontend-assets.json",
inject: false,
minify: false,
}),
],
}
}
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 20
Run build
/domain-navigation/frontend$ npm run build
⠋ Building for production…
Build complete. The ../backend/assets directory is ready to be
deployed.
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 21
Server side HTML template
<head>
{{range $css := .Assets.CSS}}
<link rel="stylesheet" href="{{$css}}" />
{{end}}
</head>
<body>
{{ .MenuHTML }}
{{ .CartHTML }}
{{ .ProductDetailHTML }}
{{ .FooterHTML }}
{{range $js := .Assets.JS}}
<script type="text/javascript" src="{{$js}}"></script>
{{end}}
</body> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 22
Rendered template output
<head>
<link rel="stylesheet" href="/proxy/menu/css/app.a4393e1d.css" />
<link rel="stylesheet" href="/proxy/cart/css/app.ae6c87ce.css" />
...
</head>
<body>
<div id="menu"/>
<div id="cart"/>
<div id="product"/>
<div id="footer"/>
<script type="text/javascript"
src="/proxy/menu/js/app.938921fc.js"></script>
<script type="text/javascript" src="/proxy/cart/js/app.ffb4.js"></script>
...
</body> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 23
Client side result
<body>
<ul class="menu" id="menu">
<li><a href="/">Home</a></li>
<li><a href="/shop">Shop</a></li>
</ul>
<div id="cart"> ... </div>
<div id="product"> ... </div>
<div class="footer" id="footer"> ... </div>
...
</body>
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 24
Issues
25
Issues
- Components are only rendered once
- How to send server side data to client side?
- How to call authenticated microservice APIs?
- Everybody's touching my browser's globals
- How do we share components?
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 26
Components are only rendered once
Instead of looking at IDs, use custom elements:
<example-menu></example-menu>
<example-product-detail></example-product-detail>
<example-cart></example-cart>
<example-footer></example-footer>
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 27
Components are only rendered once
Then add a loop in each entrypoint:
const components = {
"example-menu": Menu,
"example-footer": Footer,
};
Object.entries(components).forEach(([tagName, Component]) => {
document.getElementsByTagName(tagName).forEach(el => {
new Vue({
el,
render: h => h(Component)
});
});
}); Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 28
How to send server side data to client side?
Continuing on the custom elements solution:
<example-menu active="home"></example-menu>
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 29
How to send server side data to client side?
Update the entrypoint:
Object.entries(components).forEach(([tagName, Component]) => {
document.getElementsByTagName(tagName).forEach(el => {
const props = Array.from(el.attributes).reduce((props, attr) => {
props[attr.nodeName] = attr.nodeValue;
return props;
}, {});
new Vue({
el,
render: h => h(Component, { props })
});
});
});
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 30
How to send server side data to client side?
Alternative solution: treat pieces of document structure as Vue template.
Enable the Vue runtime compiler in vue.config.js:
module.exports = {
...
runtimeCompiler: true,
}
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 31
How to send server side data to client side?
The template should be adjusted:
<example-menu class="navigation" active="home"></example-menu>
<example-product-detail class="product"></example-product-detail>
<example-cart class="cart"></example-cart>
<example-footer class="navigation"></example-footer>
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 32
How to send server side data to client side?
Update the entrypoint:
const components = {
"example-menu": Menu,
"example-footer": Footer,
};
document.getElementsByClassName("menu").forEach(el => {
new Vue({
el,
components,
});
});
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 33
How to send server side data to client side?
Bonus: this makes component composition possible:
<example-menu class="navigation" active="home">
<example-menu-item href="/">Home</example-menu-item>
<example-menu-item href="/shop">Shop</example-menu-item>
</example-menu>
Downside is extra 10kb for the runtime compiler in each bundle.
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 34
How to call authenticated microservice APIs?
You want to use a prope web token auth framework such as OAuth.
When that's in place you have basically two options:
- store the token on the client and pass it along proxy calls
- store the token on the server and use a session cookie on the client
The last option requires you to tinker with your proxy and make it session-aware.
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 35
Everybody's touching my browser's globals
Rules for all teams:
- Only touch your own document structure
- No pollution of global JS scope (should be fine if using Webpack)
- Regulate usage of web APIs (for instance, only 1 client side router allowed)
- If needed, communicate on a page via browser events
- Prefix CSS and limit to document structure
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 36
Browser's globals: CSS
Use the scoped attribute on Vue component style tags:
<style scoped>
h1 {
font-size: 2rem;
}
</style>
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 37
Browser's globals: CSS
Use a Vue preprocessor to prefix third party CSS:
.navigation {
@import 'buefy.css'
}
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 38
How do we share frontend components?
1. Create a Vue component library.
2. Share using a private NPM repo.
3. Include the components that you use in your bundle.
There are some advanced Webpack tricks to reduce bundle size! For next time...
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 39
Questions? 🤷♂️
40
Thank you!
Albert Brand
twitter.com/al_bert_brand
medium.com/@albert.brand
linkedin.com/in/albertbrand
Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 41

More Related Content

What's hot

Continuous Integration and development environment approach
Continuous Integration and development environment approachContinuous Integration and development environment approach
Continuous Integration and development environment approach
Aleksandr Tsertkov
 

What's hot (20)

Introducing Spring Framework 5.3
Introducing Spring Framework 5.3Introducing Spring Framework 5.3
Introducing Spring Framework 5.3
 
Going Serverless Using the Spring Framework Ecosystem
Going Serverless Using the Spring Framework EcosystemGoing Serverless Using the Spring Framework Ecosystem
Going Serverless Using the Spring Framework Ecosystem
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
 
Spring Cloud Function: Where We Were, Where We Are, and Where We’re Going
Spring Cloud Function: Where We Were, Where We Are, and Where We’re GoingSpring Cloud Function: Where We Were, Where We Are, and Where We’re Going
Spring Cloud Function: Where We Were, Where We Are, and Where We’re Going
 
Vue3: nuove funzionalità, differenze e come migrare
Vue3: nuove funzionalità, differenze e come migrareVue3: nuove funzionalità, differenze e come migrare
Vue3: nuove funzionalità, differenze e come migrare
 
Micro Frontends
Micro FrontendsMicro Frontends
Micro Frontends
 
Blazor - the successor of angular/react/vue?
Blazor - the successor of angular/react/vue?Blazor - the successor of angular/react/vue?
Blazor - the successor of angular/react/vue?
 
Introduction of ASP.NET MVC and AngularJS
Introduction of ASP.NET MVC and AngularJSIntroduction of ASP.NET MVC and AngularJS
Introduction of ASP.NET MVC and AngularJS
 
70-534: ARCHITECTING MICROSOFT AZURE SOLUTIONS
70-534: ARCHITECTING MICROSOFT AZURE SOLUTIONS70-534: ARCHITECTING MICROSOFT AZURE SOLUTIONS
70-534: ARCHITECTING MICROSOFT AZURE SOLUTIONS
 
Micronaut: A new way to build microservices
Micronaut: A new way to build microservicesMicronaut: A new way to build microservices
Micronaut: A new way to build microservices
 
Spring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWSSpring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWS
 
Introduction to ASP.NET Core
Introduction to ASP.NET CoreIntroduction to ASP.NET Core
Introduction to ASP.NET Core
 
Continuous Integration and development environment approach
Continuous Integration and development environment approachContinuous Integration and development environment approach
Continuous Integration and development environment approach
 
Security Patterns for Microservice Architectures - SpringOne 2020
Security Patterns for Microservice Architectures - SpringOne 2020Security Patterns for Microservice Architectures - SpringOne 2020
Security Patterns for Microservice Architectures - SpringOne 2020
 
"Project Tye to Tie .NET Microservices", Oleg Karasik
"Project Tye to Tie .NET Microservices", Oleg Karasik"Project Tye to Tie .NET Microservices", Oleg Karasik
"Project Tye to Tie .NET Microservices", Oleg Karasik
 
Full Steam Ahead, R2DBC!
Full Steam Ahead, R2DBC!Full Steam Ahead, R2DBC!
Full Steam Ahead, R2DBC!
 
Setup ColdFusion application using fusebox mvc architecture
Setup ColdFusion application using fusebox mvc architectureSetup ColdFusion application using fusebox mvc architecture
Setup ColdFusion application using fusebox mvc architecture
 
TDD with ASP.NET MVC 1.0
TDD with ASP.NET MVC 1.0TDD with ASP.NET MVC 1.0
TDD with ASP.NET MVC 1.0
 
Spring: Your Next Java Micro-Framework
Spring: Your Next Java Micro-FrameworkSpring: Your Next Java Micro-Framework
Spring: Your Next Java Micro-Framework
 
Connecting Spring Apps to Distributed SQL Clusters Running in Kubernetes
Connecting Spring Apps to Distributed SQL Clusters Running in KubernetesConnecting Spring Apps to Distributed SQL Clusters Running in Kubernetes
Connecting Spring Apps to Distributed SQL Clusters Running in Kubernetes
 

Similar to Vue micro frontend implementation patterns

Similar to Vue micro frontend implementation patterns (20)

using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
Magento
MagentoMagento
Magento
 
Struts notes
Struts notesStruts notes
Struts notes
 
Struts natraj - satya
Struts   natraj - satyaStruts   natraj - satya
Struts natraj - satya
 
Struts natraj - satya
Struts   natraj - satyaStruts   natraj - satya
Struts natraj - satya
 
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speechVue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
 
Introducción al SharePoint Framework SPFx
Introducción al SharePoint Framework SPFxIntroducción al SharePoint Framework SPFx
Introducción al SharePoint Framework SPFx
 
5 年後還是新手 - WordPress Plugin 開發大冒險 - GOTY
5 年後還是新手 - WordPress Plugin 開發大冒險 - GOTY5 年後還是新手 - WordPress Plugin 開發大冒險 - GOTY
5 年後還是新手 - WordPress Plugin 開發大冒險 - GOTY
 
Link. apache wicket [santi caltabiano]
  Link. apache wicket [santi caltabiano]  Link. apache wicket [santi caltabiano]
Link. apache wicket [santi caltabiano]
 
Overview of the AngularJS framework
Overview of the AngularJS framework Overview of the AngularJS framework
Overview of the AngularJS framework
 
Vered Flis: Because performance matters! Architecture Next 20
Vered Flis: Because performance matters! Architecture Next 20Vered Flis: Because performance matters! Architecture Next 20
Vered Flis: Because performance matters! Architecture Next 20
 
What's new in Portal and WCM 8.5
What's new in Portal and WCM 8.5What's new in Portal and WCM 8.5
What's new in Portal and WCM 8.5
 
PWA - The Future of eCommerce - Magento Meetup Ahmedabad 2018
PWA - The Future of eCommerce - Magento Meetup Ahmedabad 2018PWA - The Future of eCommerce - Magento Meetup Ahmedabad 2018
PWA - The Future of eCommerce - Magento Meetup Ahmedabad 2018
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
 
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentationvue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
 
Link. wicket [santi caltabiano].txt blocco note
  Link. wicket [santi caltabiano].txt   blocco note  Link. wicket [santi caltabiano].txt   blocco note
Link. wicket [santi caltabiano].txt blocco note
 
Integrate any Angular Project into WebSphere Portal
Integrate any Angular Project into WebSphere PortalIntegrate any Angular Project into WebSphere Portal
Integrate any Angular Project into WebSphere Portal
 
The next step from Microsoft - Vnext (Srdjan Poznic)
The next step from Microsoft - Vnext (Srdjan Poznic)The next step from Microsoft - Vnext (Srdjan Poznic)
The next step from Microsoft - Vnext (Srdjan Poznic)
 
CODE IGNITER
CODE IGNITERCODE IGNITER
CODE IGNITER
 
Web Components: back to the future
Web Components: back to the futureWeb Components: back to the future
Web Components: back to the future
 

Recently uploaded

Recently uploaded (20)

Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 

Vue micro frontend implementation patterns

  • 1. Vue micro frontend implementation patterns Albert Brand
  • 2. Who am I? Albert Brand Senior consultant @ Xebia Pragmatic programmer Proud husband & dad twitter.com/al_bert_brand medium.com/@albert.brand linkedin.com/in/albertbrand Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 2
  • 3. What is a micro frontend? - Autonomously developed, tested and deployed frontend components - Focused on a single business domain - Implemented end-to-end by a team - Offering more freedom and less dependencies for developers - Very useful in a multi team setting Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 3
  • 4. How can Vue help? - Vue is an opinionated web framework - Can build anything: - large single page apps with client side routing; or - a library of shared UI components; or even - repackage as Web Components - Easy to adjust to needs - Not too much hard choices Seems like a good match! Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 4
  • 5. From monolith to disaster microservices 5
  • 6. Single page app monolith Browser Page Server Backend app Frontend app HTML Assets API API 6
  • 7. Backend microservices Browser Page Server App service Frontend app Micro service API HTML Assets Micro service Proxy API 7
  • 8. Frontend microservices Browser Page Server App service Micro frontend component Micro serviceAPI HTML Proxy Micro service Assets HTML Micro frontend component Micro serviceAPI Micro service Assets HTML 8
  • 10. Wait, why can't I use IFRAMEs? 10
  • 11. More server side concatenation tools - Server side includes - Compoxure - Tailor Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 11
  • 13. Micro frontend domain division Page Menu Footer Product detail Cart 13
  • 14. Example repository structure Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 14 /renderer /templates /domain-navigation /backend /assets /templates /frontend /src /domain-product ... same /domain-cart ... same
  • 15. Local development HTTP servers Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 15 /renderer <- serves at http://localhost:8000 /domain-navigation /backend <- serves at http://localhost:9000 /domain-product/backend <- serves at http://localhost:9001 /domain-cart/backend <- serves at http://localhost:9002
  • 16. Example page render GET request - Renders a template with menu, cart, product and footer component - Queries micro frontend endpoints - Can be queried in parallel, slowest is bottleneck - Need to handle failing micro frontend endpoint - No / short cache period for endpoint result - Returns rendered HTML page Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 16
  • 18. Frontend assets? JSON structure that contains initial JS/CSS for the micro frontend component: { "css": ["/assets/css/app.a4393e1d.css"], "js": ["/assets/js/app.938921fc.js"] } Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 18
  • 19. Navigation Vue JS entrypoint import Vue from "vue"; import Menu from "@/components/Menu.vue"; import Footer from "@/components/Footer.vue"; new Vue({ el: "#menu", render: h => h(Menu) }); new Vue({ el: "#footer", render: h => h(Footer) }); Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 19
  • 20. vue.config.js addition module.exports = { ... configureWebpack: { plugins: [ new HtmlWebpackPlugin({ template: "templates/assets.ejs", filename: "frontend-assets.json", inject: false, minify: false, }), ], } } Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 20
  • 21. Run build /domain-navigation/frontend$ npm run build ⠋ Building for production… Build complete. The ../backend/assets directory is ready to be deployed. Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 21
  • 22. Server side HTML template <head> {{range $css := .Assets.CSS}} <link rel="stylesheet" href="{{$css}}" /> {{end}} </head> <body> {{ .MenuHTML }} {{ .CartHTML }} {{ .ProductDetailHTML }} {{ .FooterHTML }} {{range $js := .Assets.JS}} <script type="text/javascript" src="{{$js}}"></script> {{end}} </body> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 22
  • 23. Rendered template output <head> <link rel="stylesheet" href="/proxy/menu/css/app.a4393e1d.css" /> <link rel="stylesheet" href="/proxy/cart/css/app.ae6c87ce.css" /> ... </head> <body> <div id="menu"/> <div id="cart"/> <div id="product"/> <div id="footer"/> <script type="text/javascript" src="/proxy/menu/js/app.938921fc.js"></script> <script type="text/javascript" src="/proxy/cart/js/app.ffb4.js"></script> ... </body> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 23
  • 24. Client side result <body> <ul class="menu" id="menu"> <li><a href="/">Home</a></li> <li><a href="/shop">Shop</a></li> </ul> <div id="cart"> ... </div> <div id="product"> ... </div> <div class="footer" id="footer"> ... </div> ... </body> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 24
  • 26. Issues - Components are only rendered once - How to send server side data to client side? - How to call authenticated microservice APIs? - Everybody's touching my browser's globals - How do we share components? Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 26
  • 27. Components are only rendered once Instead of looking at IDs, use custom elements: <example-menu></example-menu> <example-product-detail></example-product-detail> <example-cart></example-cart> <example-footer></example-footer> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 27
  • 28. Components are only rendered once Then add a loop in each entrypoint: const components = { "example-menu": Menu, "example-footer": Footer, }; Object.entries(components).forEach(([tagName, Component]) => { document.getElementsByTagName(tagName).forEach(el => { new Vue({ el, render: h => h(Component) }); }); }); Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 28
  • 29. How to send server side data to client side? Continuing on the custom elements solution: <example-menu active="home"></example-menu> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 29
  • 30. How to send server side data to client side? Update the entrypoint: Object.entries(components).forEach(([tagName, Component]) => { document.getElementsByTagName(tagName).forEach(el => { const props = Array.from(el.attributes).reduce((props, attr) => { props[attr.nodeName] = attr.nodeValue; return props; }, {}); new Vue({ el, render: h => h(Component, { props }) }); }); }); Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 30
  • 31. How to send server side data to client side? Alternative solution: treat pieces of document structure as Vue template. Enable the Vue runtime compiler in vue.config.js: module.exports = { ... runtimeCompiler: true, } Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 31
  • 32. How to send server side data to client side? The template should be adjusted: <example-menu class="navigation" active="home"></example-menu> <example-product-detail class="product"></example-product-detail> <example-cart class="cart"></example-cart> <example-footer class="navigation"></example-footer> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 32
  • 33. How to send server side data to client side? Update the entrypoint: const components = { "example-menu": Menu, "example-footer": Footer, }; document.getElementsByClassName("menu").forEach(el => { new Vue({ el, components, }); }); Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 33
  • 34. How to send server side data to client side? Bonus: this makes component composition possible: <example-menu class="navigation" active="home"> <example-menu-item href="/">Home</example-menu-item> <example-menu-item href="/shop">Shop</example-menu-item> </example-menu> Downside is extra 10kb for the runtime compiler in each bundle. Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 34
  • 35. How to call authenticated microservice APIs? You want to use a prope web token auth framework such as OAuth. When that's in place you have basically two options: - store the token on the client and pass it along proxy calls - store the token on the server and use a session cookie on the client The last option requires you to tinker with your proxy and make it session-aware. Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 35
  • 36. Everybody's touching my browser's globals Rules for all teams: - Only touch your own document structure - No pollution of global JS scope (should be fine if using Webpack) - Regulate usage of web APIs (for instance, only 1 client side router allowed) - If needed, communicate on a page via browser events - Prefix CSS and limit to document structure Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 36
  • 37. Browser's globals: CSS Use the scoped attribute on Vue component style tags: <style scoped> h1 { font-size: 2rem; } </style> Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 37
  • 38. Browser's globals: CSS Use a Vue preprocessor to prefix third party CSS: .navigation { @import 'buefy.css' } Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 38
  • 39. How do we share frontend components? 1. Create a Vue component library. 2. Share using a private NPM repo. 3. Include the components that you use in your bundle. There are some advanced Webpack tricks to reduce bundle size! For next time... Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 39
  • 41. Thank you! Albert Brand twitter.com/al_bert_brand medium.com/@albert.brand linkedin.com/in/albertbrand Vue micro frontend implementation patterns - Xebia - @al_bert_brand - 41

Editor's Notes

  1. Business domain -> Bounded context
  2. But first...
  3. Frontend app / app service are still a monolith You can choose to expose microservice APIs but that will probably bite you. Proxy can also be a generic gateway or own deployment as you see fit
  4. App service = app shell The HTML and assets microservice is often called the Backend-for-Frontend
  5. If you squint your eyes this is the high level architecture. A domain should be the focus of a single team.
  6. You probably can! But: - Bad SEO - Load issues - Layout issues - Accessibility issues
  7. Do some research to see what is a good fit (or roll your own of course).
  8. Let's dive into a basic example
  9. Can be single repository or split per domain over multiple repo's. Split will help with autonomy. We are focusing on the micro frontend part, so I left out the API microservices.
  10. In the end, these folders will be packaged and deployed autonomously on some infrastructure. I left that out for your listening pleasure, we're not diving into Docker, Kubernetes and Terraform this time :).
  11. What is queried: retrieve server side rendered HTML fragment for each micro frontend component (this could return a SSR web component) retrieve JS and CSS frontend asset locations that need to be directly loaded (to enable client side behavior and separated styles) Failing endpoint: Short timeout, else user experience suffers Add circuit breaker Caching: Sane redeployment
  12. This assumes that there are exactly 2 component tags on the page. No worries, we will revisit this soon.
  13. The HtmlWebpackPlugin renders embedded Javascript templates, which is not limited to HTML output. We can use it to render the frontend assets JSON file as it has access to the bundled CSS and JS filepaths. Alternative is to build your own plugin.
  14. Writes all bundled / optimized assets in the backend folder. You can make this a part of a containerised build as you see fit.
  15. Hey, it's a Go template. Learn a new language every year.
  16. By not providing a render function, Vue treats the specified `el` as template. This essentially triggers rendering all recognised Vue elements in the element branches marked with the class.