Microfrontends with React

goktugyalcin

Ali Goktug Yalcin

Posted on January 10, 2024

Microfrontends with React

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.

A simple microfrontend structure

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!!)
  },
})
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

For last step, change the preview script with the code below:

"preview": "vite build && vite preview --port=5432 --strictPort"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Add Module Federation plugin:

cd microbase
npm install
npm install @originjs/vite-plugin-federation --save-dev
Enter fullscreen mode Exit fullscreen mode

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
    })
  ],
})
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

We are ready for deploy. Run the host app and start to party!

npm run dev
Enter fullscreen mode Exit fullscreen mode

Preview:

Preview of the microfrontend

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!

💖 💪 🙅 🚩
goktugyalcin
Ali Goktug Yalcin

Posted on January 10, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related