Micro Frontends Mystery
Let’s try to solve the mystery
Micro Frontends when i heard this word at first i thought it is a small frontend application that uses some framework to develop. But when i read the documentation i come to a conclusion that i answered 50% correctly.
So i started to dig more about what is Micro Frontends by looking at the articles from the medium and videos from YouTube.
Why should you want to read this article
Though there are many articles available online. Everyone has shared their views about Micro Frontends which are in bits & pieces. But if you want to see what’s happening in Micro Frontend in a single shot you can scroll to read.
What you are going to see in this article
- What is Micro Frontends
- Ways to Create Micro Frontends
- Approach #1 Create Micro Frontend using Open Components
- Approach #2 Create Micro Frontend using Web Component
- Approach #3 Angular Custom Elements
- Approach #4 Sharing Data between multiple apps
- Approach #5 Shopping Cart application using multiple angular projects
- What is the mystery behind Micro Frontends
What you can’t see in this article
- Creating Micro Frontend using Single SPA
- How to deploy/host individual applications separately
So, Let’s begin to solve the mystery
1. What is Micro Frontends
Micro Frontend is an architectural style where independent deliverable front end applications are composed into a great whole
Really, just have a look at the below diagram
Monolithic approach
Earlier days when we do programming we have followed the monolithic approach where we will have all the frontend, backend, and database in a single project Example: Java PetStore
Cons of having a monolithic approach
Suppose if the backend team changes any code then we have to build the entire application and deploy
Frontend & Backend Services
In this approach, the backend team has been separated they can focus only on their codes and database and they don’t want to worry about the frontend. similarly, the frontend team also don’t want to update whenever there is a change in backend
Frontend & Micro Services
Now the backend service is even split into multiple teams as a service where individual teams will focus on their respective task and deploy it independently without depending on other service teams
Now the back end team has been split into individual small teams but what about the front ends?
Now in Micro Frontends, we will have a separate team for each feature so we will have multiple frontend teams who will work on the small features.
Key benefits of using Micro Frontend
- Smaller, more cohesive and maintainable codebases
- More scalable organizations with decoupled, autonomous team
- The ability to upgrade, update or even rewrite the parts of the frontend in a more incremental fashion that was previously possible
Companies which are using the Micro Frontend applications are
- Amazon — Ecommerce site
- IKEA
- Zalando
- Expedia
2. Ways to Create Micro Frontends
- OpenComponents
- Single SPA
- Web Components
OpenComponents
Open Components is an open-source Micro Frontend framework that allows fast-moving teams to easily build and deploy front-end components.
- Components
- Template System
- Registry
Components
Small, immutable, units of universal code mainly consisting of HTML, javascript, and CSS. They can optionally contain some logic, allowing a server-side node.js application to compose a model that is used to render the view. After rendering they are pieces of pure HTML to be injected into any HTML page.
Template System
The template system allows for the support of any client-side technology, hiding away all the configuration complexity while avoiding a specific UI framework.
The supported templates are
- React
- Angular JS
Registry
The registry provides a rest API to consume, retrieve and publish components to a library. When components depend on static resources(such as images, CSS files) these are stored, during packaging and publishing, in a publicly-exposed part of the library that serves as CDN
Single SPA
Single-SPA is a framework for bringing together multiple javascript Micro Frontends in a frontend application. Architecting your frontend using Single-SPA enables many benefits, such as:
- Use multiple frameworks on the same page without page refreshing (React, AngularJS, Angular, Ember, or whatever you’re using)
- Deploy your Micro Frontends independently.
- Write code using a new framework, without rewriting your existing app
- Lazy load code for improved initial load time.
Web Components
Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. It can be used with any javascript library or framework that works with HTML
Web components are based on 4 types
- Custom elements — Foundation for designing and using new types of DOM elements
- Shadow DOM — Defines how to use encapsulated style and markup in web components
- ES Modules — Defines the inclusion and reuse of JS documents in a standard-based, modular, performant way
- HTML Template — Defines how to declare fragments of markup that go unused at page load, but can be instantiated later on at runtime.
3. Approach #1 Create Micro Frontend using Open Components
You can refer the code from here
What we have done in the code is we will be having 2 parts
- Components
- Host
Components
Here we will be having the codes like react, vanilla script codes are generated using the oc-template generator
Host
Here all the components are tailored/combined together as a simple application
We will be having only one file index.html
where we would have used the <oc-template>
tag along with the reference similar like anchor tag like below
Run the open component
To run the open registry the command used is
Go to the components directory and open terminal and give the below command
oc dev . 3030// open the open components registry in http://localhost:3030/
Now open another terminal and navigate to host page and run the below command
python -m SimpleHTTPServer 8000// open the micro front end page in http://localhost:8000/
Demo
Open Registry
#Failure: Tried to create an OC Registry in Heroku using AWS S3 but failed
4. Approach #2 Create Micro Frontend using Web Component
If you want to play around with web components click here
You can refer the code from here
The code contains 2 parts similar to Open Components
- Components Folder
- Host / Index Folder
Components Folder
In Components Folder we have created the components using react and angular. Each component have a structure like below
Host / Index Folder
We will be using the same structure similar to Open components
Inside the root package.json, we will be defining the build like below
The command to run the code is npm start which will bundle the file using webpack and open in browser
Demo
5. Approach #3 Angular Custom Elements
Creating exportable components using angular custom elements which can be used in Reactjs, Vue.js, Vanilla javascript
Plugins used for custom elements
Plugins needed for angular elements are
- @angular/elements —
npm i @angular/elements
- @webcomponents/customelements —
npm i @webcomponents/custom-elements
Once the plugins are installed go to polyfills.ts file and import the web components like below
import '@webcomponents/custom-elements/src/native-shim';
import '@webcomponents/custom-elements/custom-elements.min';
Creating an Angular Element
Create a new component and styles/pages you wish and then go to app.module.ts
file and do the below steps
1. Remove the components in bootstrap and make bootstrap as empty
2. Since we are going to use the component as angular element add it in entry components like below
bootstrap: [],
entryComponents: [UserpollComponent]
3. Inside the AppModule class add the below code
export class AppModule {
constructor(public injector: Injector) {}
ngDoBootstrap() {
const e1 = createCustomElement(UserpollComponent, { injector: this.injector });
customElements.define('user-poll', e1);
}
In the above code, we are creating a custom element with the component which we have created earlier and then defining a tag for the element we created
4. In the index.html
file removes all the predefined ones and adds the component which you have created like below
<user-poll></user-poll>
5. Inside the userpoll.component
@Component
decorator add the encapsulation
tag like below
@Component({
selector: 'app-userpoll',
templateUrl: './userpoll.component.html',
styleUrls: ['./userpoll.component.css'],
encapsulation: ViewEncapsulation.ShadowDom,
})
6. When we build the project in production mode
we will have the static files in different versions like below
'main-es2015.js',
'main-es5.js',
'polyfills-es2015.js',
'polyfills-es5.js',
'runtime-es2015.js',
'runtime-es5.js'
but we need a single js file to achieve it we need to install a plugin named
- concat —
npm i concat
- fs-extra —
npm i fs-extra
once the plugins are installed create a new file build-script.js
in the root folder and add the below code
const fs = require('fs-extra');
const concat = require('concat');
(async function build() {
const files = [
'./dist/elementsApp/main-es2015.js',
'./dist/elementsApp/main-es5.js',
'./dist/elementsApp/polyfills-es2015.js',
'./dist/elementsApp/polyfills-es5.js',
'./dist/elementsApp/runtime-es2015.js',
'./dist/elementsApp/runtime-es5.js'
]
await fs.ensureDir('elements')
await concat(files, 'elements/user-poll.js')
})()
Inside the package.json
file add the below scripts to build the elements
"build:elements": "ng build --prod --output-hashing none && node build-script.js"
and when we run the project with the command npm run build:elements
it will create the build file with a single js file
7. Now we can upload the js file to any storage and we can use the reference in the script tag
8. Now create an HTML project and inside the index.html page import the script tag and import the tag like below <user-poll> </user-poll>
Now we can run the angular project in any language like
- Reactjs
- Vue.js
- Vanilla script
- Normal HTML Page
Demo
6. Approach #4 Sharing Data between multiple apps
Sharing data between multiple apps which are created in Angular, React and Vue.js
Versions used
Steps to create shared data
- Initialize npm with the command
npm init — yes
to create a package.json file - Created a typescript file and created a function called createID which would generate the current timestamp like below
3. Inside the package.json file add the script to convert tsc file to js file like below
Steps to create a Vue.js project
- Install the vue.cli if you are a new user using the command
npm install -g @vue/cli
- Once the CLI is installed create a new Vue project using the command
vue create a project name
- Install the dependency from the shared-stuff using the command
npm i path to your shared-stuff
- Once the dependency is installed you can see the updated
package.json
like below
5. Navigate to the components folder and add import the shared-stuff dependency like below
Now you will face some issues like the createID is declared and not used as well as the build gets failed in shared-stuff.
For that create a new file named vue.config.js
in the root of vue project and add the below the code
module.exports = {
chainWebpack: config => config.resolve.symlinks(false)
}
Steps to create an Angular project
- Create a new angular project using the command
ng new project name
- Once the project is created install the shared-stuff dependency similar like Vue.js
- Once the plugin is installed open
app.component.ts
and import the dependency - Change the title with the createID() and run the project
Steps to create a React project
- Create a new react project using the command
create react-app project name
- Once the project is created install the shared-stuff similar like Vue.js
- Once the plugin is installed open
src/components/App.js
and import the dependency and call the createID()
Demo
7. Approach #5 Shopping Cart application using multiple angular projects
If you want to play around with web components click here
We have created 3 separate angular projects using the command ng new project-name
namely
- product
- orders
- shopping-cart
Product Project
It has 2 components
- Catalog page
- Add Product page
Order Project
It has 1 component
- All orders page
Shopping-cart Project
- Login page
Data communication between root shell to product, order page
I have created
- Products.json
- Orders.json
From root shell, the communication takes places to the product and order page using the routes and inside the product, project add the code like below
getProducts() { this.http.get('assets/data/product.json').subscribe((res: any) =>{ this.productList = res.response; });
}
Similarly in the order project add the code like below
getOrders() { this.http.get('assets/data/order.json').subscribe((res: any) => { this.ordersList = res.response; });}
Root Shell Routes
Demo
8. What is the mystery behind Micro Frontends
So far the findings from Micro Frontends are
- We can share the data from one application to another
- We can create a custom element and can use it any js application
- We can create separate components/projects based on features
What mystery is yet to be found out
- How incremental update is happening for each product
- Is it possible to deploy each project separately
Conclusion
We have solved some of the mysteries in the Micro Frontends, will solve other mysteries soon.
Happy Learning :)
Resource Links
- https://github.com/jherr/oc-pdp-demo
- https://opencomponents.github.io/
- https://www.youtube.com/watch?v=DczecISRKVU
- https://www.youtube.com/watch?v=9CG0LeswOoM&list=PLNqp92_EXZBIjRHstP4tzzIAT3XjJ1kmr&index=3
- https://medium.com/javascript-in-plain-english/create-micro-frontends-using-web-components-with-support-for-angular-and-react-2d6db18f557a
- https://medium.embengineering.com/micro-front-end-and-web-components-ce6ae87c3b7f
- https://github.com/manfredsteyer/Angular_MicroApps_Different_Technologies
- https://medium.com/disney-streaming/combining-multiple-angular-applications-into-a-single-one-e87d530d6527
- https://fireship.io/lessons/angular-elements-quick-start-guide/
- https://fireship.io/lessons/how-to-structure-a-large-web-app-project/
- https://medium.com/@ketangote/micro-front-end-with-angular-kubernetes-part1-f54f59e28262
- https://www.youtube.com/watch?v=na2DqaoBlUc
- https://youtu.be/z32yzy4TrKM
Github Links
- Web Components — https://github.com/nidhinkumar06/micro-front-end-web-components
- Open Components — https://github.com/nidhinkumar06/micro-front-end-open-component
- Angular Elements — https://github.com/nidhinkumar06/angularelements
- MultiAngular Apps — https://github.com/nidhinkumar06/multi-angular
- Shared-stuff — https://github.com/nidhinkumar06/Big-App
- Shopping Cart-Product — https://github.com/nidhinkumar06/shoppingcart-product
- Shopping Cart-Order — https://github.com/nidhinkumar06/shoppingcart-order
- Shopping Cart-Root — https://github.com/nidhinkumar06/shoppingcart-shell
Errors Faced
- Vue plugin issue — https://github.com/vuejs/vue-cli/issues/2948
- Routing issue — https://stackoverflow.com/questions/60315206/angular-multiple-projects-routing-url-gets-changed-but-page-not-rendering/60325879#60325879
- Angular 9 — Production build doesn’t create module.ngfactory.js — https://stackoverflow.com/questions/60409504/angular-9-production-build-doesnt-create-named-chunk-file