Reading notes from Micro Frontends in Action to get background for webpack 5 (TL;DR)...
Micro Frontends in Action (⭐⭐⭐)
When things gets bigger, you divided it and give it autonomy and trust. Yet during reading, I got to know Webpack Federation even more interesting!
Specialist vs Cross Functional Team
Old fashion: divide team based on their skills.
New fashion: vertically divide into each small full stack group.
In old fashion team provides modules/functions, knowledge, tools and asistance. However, they mostly focus on their own target. In real world many new features require full stack integration from front through to backend, therefore with too many dependencies and project moves slow. While with new vertical fashion, team is an independent startup
group (localized decision and management) and move faster. Some sharing cross team can help reduce duplication. Good or bad, I think it's very feasible for agile UX focus features. However, backend world and many other complicate system might still be leaning to old fashion since simply a tool or an infrastructure might cost a whole team effort and these parts are very commonly shared.
Besides hiring, I think the keys of success for micro frontend structure are sharing and communications. Share to reuse knowledge/effort as much as possible. Communication and even compromising to avoid conflicting in integration.
Micro Frontend Framework
Basically, a framework that can integrates pages and page elemnts (fragments) into a solid normal web page.
Page Split
Old MPA way to split. User experience bad.
iframe?
Performance, layout and accessibility make it not feasible. However, how Spotify uses for desktop application is very interesting to give a read. It's Chromium Embedded Framework (CEF) in V8 which is somewhat like iframe (think about open multiple chrome tab windows in your app). It has interesting name Spotlet. Communication is through REST API style.
Ajax
Load and assembly the page. Still cannot solve namespace issues and nasty way to share/communicate in Javascript. Too many queries for different features. One option is to put this assembly in server side (SSR).
Nginx or CDN Providers' Tricks
Server side templating or includes by configuring nginx, old tech to integrate pages/fragments and nginx.conf
form to fill. Many CDN providers also support similar stuff, just do:
<esi:include src="..." />
Not good for server side load. Communication between pages? No way!
Client Side Composition
Client side do the integration and we only take care of traffic. Use webcomponent/custom html element to implement.
class MyNewComponent extends HTMLElement {
constructor() {
// creation
}
disconnectedCallback() {
// destroy
}
connectedCallback() {
// this.innerHTML = `<fancy page/>`
}
attributeChangedCallback() {
// this.getAttribute("my-attr");
}
}
// somewhere
window.customElements.define("my-new-component", MyNewComponent);
Old browser not support (problematic polyfill). Some virtual DOM framework (e.g. React) might have issues fully supporting it.
Shadow DOM can help isolate your JS/CSS!
Since it's in the same html page, communication is fine. Following modern framework's pattern (e.g. Redux), it's easy (think of parent as main page and children as your web component:
parent
--immutable attribute--> children
children
--event report--> parent
Again, for communication, using web component or not, please strictly follow e.g. Redux pattern.
Occasionally, pub/sub etc. can be used for long distance
call 😺.
App Shell/Meta Framework
As in PWA, Cached skeleton (routers and some common things). Keep it lean and simple. Author implemented a toy example to illustrate but actually this skeleton should also handle Meta, error/failure handling, memory/resource management, performance profiling and communication. Some common tasks like auth, polyfill, analytic & tag as well. Actually there are a wheel on github: single-spa.
Key idea is to lazily load each SPA and maintain them in the same page (soft transition to each routes).
However, interactivity is issue with loading/slow page. Later author comes back to mixture of server side and client side.
Server Sider + Client Side
This is called universal rendering in book. Useful for case when first page load matters. Ara Framework will be the wheel. Personal feeling this universal rendering idea creates extra complexity and why would I entangle components like this instead of keeping route path boundary at first place. First loading page can be solved by many other better ways.
Frontend Arch Decision Tree
Also see here.
Doc vs Content Spectrum:
Doc <---- ----> Content
Web Site PWA Web App
SSR CSR
Performance
Build theirs own metrics for teams and aligned together. Common big framework vendor code costs so shares centerilized big vendor code. Sharing cause problem of deploy lock when version updates, so tools like webpack.DllReferencePlugin
comes to play.
Pattern Library
Some philosophy of design decision for centralized/localized library.
Team Boundaries
Like the philosophy part, many similar discussion in sw engineering philosophy. Again I think combine autonomy with traditional sw team structure is the way to go. UX/frontend/application team does full autonomy for fast iteration while other like backend/service/infra team does domain/functional boundary. Of course communication cross-team is very important. Guidance, tech blueprint, are also good ways to help tech decision.
There're also resources for such checklist:
Migration
Some points discussed before but in great details.
Webpack Federation
This shows how to practically start a micro frontend project e.g. as in this repo: https://github.com/mizx/mfe-webpack-demo.