Micro Frontends Part2: Angular, React, Vue together in an app.
In part1 we talked about the motivations for moving towards a Micro Frontend solution . In this part we will take it a step forward where we will see how to have multiple frameworks and serve it as a single application.
In this part our goal is to have an application with 3 sections i.e Header, Dashboard, Footer. We will develop header in react, dashboard in angular and Footer in vue and this will be served through a single Url.
I have gone through multiple blogs and approaches to acheive this but according to me the best suited option would be Single-SPA library. They have excellent documentaion with all major Front end framework support.
Shell App
Our App will contain Shell which will be responsible for connecting all the frameworks that we will use in the current article.
- Create a folder for the shell app and install create-single-spa dependency.
mkdir shell
cd shell
npm i create-single-spa
2. Setup shell project
create-single-spa --layout
When you run above command you cli will ask you multiple inputs
- Directory for new project —
.
- Select type to generate —
single-spa root config
- Which package manager do you want to use? —
npm
- Will this project use TyeScript —
y
- Organization name —
sumit
3. Install dependencies:
npm install
4. Open src/microfrontend-layout.html, and remove the following line:
<application name="@single-spa/welcome"></application>
5. Open src/index.ejs, and remove this line:
"@single-spa/welcome": "https://unpkg.com/single-spa-welcome/dist/single-spa-welcome.js",
6. Start the project, which will run on http://localhost:9000:
npm start
Adding Header Section in React Framework
We will be developing our header section in React. Below are the setup steps
- Create a folder for the React application:
mkdir header-react && cd header-react
2. Setup React project with the Single-Spa CLI:
create-single-spa --framework react
and choose:
- Directory for new project —
.
- Which package manager do you want to use? —
npm
- Will this project use TypeScript —
y
- Organization name —
sumit
- Project name —
header-react
3. Install dependencies:
npm install
4. Change root.component.tsx
import './header.css';
export default function Root(props) {
return (
<div className="header">
<div>Header (React)</div>
</div>
);
}
5. Start the project:
npm start -- --port 8500
The Shell project updates:
6. Update src/index.ejs file import map:
...
<script type="systemjs-importmap">
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"@sumit/root-config": "http://localhost:9000/sumit-root-config.js",
"@sumit/header-react": "http://localhost:8500/sumit-header-react.js"
}
}
</script>...
7. Update src/sumit-root-config.ts:
...
registerApplication(
"@sumit/header-react",
() => System.import("@sumit/header-react"),
(location) => true
);...
8. Update src/microfrontend-layout.html:
...<single-spa-router>
<main>
<route default>
<application name="@sumit/header-react"></application>
</route>
</main>
</single-spa-router>...
That’s it, we are done with our react app setup. Refresh your shell app running on http://localhost:9000 and you should see react header there.
Adding dashboard section in Angular framework
Lets proceed with our dashboard section which we will be developing in Angular framework.
- Create an Angular app using angular CLI and install dependencies
ng new dashboard-angular
cd dashboard-angular
npm install
2. Add single spa package
ng add single-spa-angular
3. Remove src/app/empty-route folder
4. Update src/app/app.component.html
<div class="dashboard">
<div>Dashboard (Angular)</div>
</div>
5. Install systemjs-webpack-interop
module:
npm install systemjs-webpack-interop -save
6. Add src/set-public-path.js:
import { setPublicPath } from "systemjs-webpack-interop";
setPublicPath("@sumit/dashboard-angular");
7. In src/main.single-spa.ts add the line bellow as the first line:
import './set-public-path';
8. Install dependencies (again):
npm install
9. Start the project:
npm run serve:single-spa:poc-angular
Shell project changes:
10. Add zone.js to the src/index.ejs:
...
<script src="https://unpkg.com/zone.js"></script>
...
11. Update import map in the src/index.ejs:
<script type="systemjs-importmap">
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"@sumit/root-config": "http://localhost:9000/sumit-root-config.js",
"@sumit/header-react": "http://localhost:8500/sumit-header-react.js",
"@sumit/dashboard-angular":"http://localhost:4200/main.js",
}
}
</script>
12. Register the app in the src/sumit-root-config.ts:
registerApplication(
"@sumit/dashboard-angular",
() => System.import("@sumit/dashboard-angular"),
(location) => true
);
13. Update src/microfrontend-layout.html:
<single-spa-router>
<main>
<route default>
<application name="@sumit/header-react"></application>
<application name="@sumit/dashboard-angular"></application>
</route>
</main>
</single-spa-router>
That’s it, we are done with our angular app setup. Refresh your shell app running on http://localhost:9000 and you should see react header as well as Angular dashboard sections.
Adding footer section in Vue framework
At last we will add a footer to our application and we will do this in vue framework.
1. Setup using Single-Spa CLI:
create-single-spa --framework vue
and choose:
- Directory for new project —
footer-vue
- Organization name —
sumit
- Please pick a preset —
Default ([Vue 3] babel, eslint)
2. Add src/set-public-path.js:
import { setPublicPath } from "systemjs-webpack-interop";
setPublicPath("@sumit/footer-vue");
3. Install systemjs-webpack-interop
module:
npm install systemjs-webpack-interop -Save
4. Update src/App.vue:
<template>
<div></div>
<div class="footer"> Footer (vue)</div>
</template><script>
export default {
name: 'App'
}
</script>
<style>
.footer {
width: 100%;
background-color: #ffb366;
color: white;
text-align: center;
line-height: 20vh;
height: 20vh;
font-size: 42px;
}
</style>
5. Start the project:
npm run serve
Shell project changes:
6. Update import map in the src/index.ejs:
<script type="systemjs-importmap">
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"@sumit/root-config": "http://localhost:9000/sumit-root-config.js",
"@sumit/header-react": "http://localhost:8500/sumit-header-react.js",
"@sumit/dashboard-angular":"http://localhost:4200/main.js",
"@sumit/footer-vue": "http://localhost:8080/js/app.js"
}
}
</script>
7. Register app in the src/sumit-root-config.ts
registerApplication(
"@sumit/footer-vue",
() => System.import("@sumit/footer-vue"),
(location) => true
);
8. Update src/microfrontend-layout.html:
<single-spa-router>
<main>
<route default>
<application name="@sumit/header-react"></application>
<application name="@sumit/dashboard-angular"></application>
<application name="@sumit/footer-vue"></application>
</route>
</main>
</single-spa-router>
So, we are done with the complete setup. Refresh your shell app running on http://localhost:9000 and you should see header, dashboard and footer sections running together in a single page.
We can further improve our app by introducing routes and other features. Feel free to give suggestions or raise any concerns in comments section. You can check the complete code at https://github.com/Sumitsinha1002/Microfrontend-POC/tree/master
Next Part
Hope you have enjoyed this article, In the next part of our microfrontend series we will see how to communicate between our micro-apps.