Microfrontends with React
Ali Goktug Yalcin
Posted on January 10, 2024
In literature, for portability and readability; books dividing into volumes. We can say 1Q84 by Haruki Murakami(My fav author btw) for that issue. 1Q84 has 1256 pages. It is hard to carry and gives a difficult experience for reading. In various countries, publishers divided this book to 3 volume.
Why I gave this example? In our development world, we were building our applications as monolithic. It makes development processes and bug-fixing more difficult.
For this issue, many solutions created for the name of flexibility and functionality like: Microfrontend and Island Architecture. Today we are going to talk about microfrontends.
Microfrontend is an architectural pattern that different micro apps as components running on an app that behaves like hub for other component apps.
We can accept its benefits like efficiency, easy to test and easy to understand.
Most applied microfrontend type is Module Federation, so we follow on this line for subject.
So gave the simple infos about it. We can start to development.
Development of a simple Microfrontend
As first step, we need to create a project that will contain simple header component with Vite
npm create vite@latest microheader -- --template react
After initialization of the app, we need to install Module Federation’s Vite plugin
cd microheader
npm install
npm install @originjs/vite-plugin-federation --save-dev
It is enough for creating configuration. And change the vite.config.js like below:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
react(), // Default React plugin for Vite
federation({
name: 'micro-header', // This modules name
exposes: { // We can think it like modules exports we can extend whatever we want
'./Header': './src/components/Header.jsx'
},
shared: ['react','react-dom'] // Shared dependencies from host
})
],
build: {
target: 'esnext' // Needed for async imports(important!!)
},
})
I created a component named Header inside of src/components, It needs a count getter and setter as parameter from host app.
import React from 'react'
const Header = ({count, setCount}) => {
return <h2 onClick={() => setCount(count+1)}>Header Component: {count}</h2>
}
export default Header
For last step, change the preview script with the code below:
"preview": "vite build && vite preview --port=5432 --strictPort"
You can give any port what do you want. I chose 5432. For last step, run it with npm run preview
.
I merged build and preview as a single script. Also you can run them concurrently with concurrently npm package.
Yup it is same as normal React components. Remote component is ready for federation. It awaits for host.
Now let’s create host app.
Like header component, as first step create a project:
npm create vite@latest microbase -- --template react
Add Module Federation plugin:
cd microbase
npm install
npm install @originjs/vite-plugin-federation --save-dev
Like remote module node, change the vite.config.js file of it:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
react(), // Default React plugin, again...
federation({
name: 'micro-base', //Name of our base app
remotes: { // Like expose's import in here. URL mostly same but port is
// depending on your apps ports like I gave above on header app.
// Module Federation serves with remoteEntry.js file from build/assets.
microHeader: "http://localhost:5432/assets/remoteEntry.js",
microBody: "http://localhost:5008/assets/remoteEntry.js",
},
shared: ['react', 'react-dom'] // We can share common dependencies
})
],
})
And lastly, use components from Federation elements. You need to call them below the remote pathname.
import React from 'react'
import Header from 'microHeader/Header'
import Body from 'microBody/Body'
import './index.css'
function App() {
const [count, setCount] = React.useState(0)
return (
<div className="container">
<Header count={count} setCount={setCount} />
<Body />
</div>
)
}
export default App
We are ready for deploy. Run the host app and start to party!
npm run dev
Preview:
We created and connected apps to them. We can create new modules and boilerplates. Also we can extend it to use Vue, React, Solid and Svelte together on this way.
Happy New Year!
Posted on January 10, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.