Microfrontends with React
Published: 2024-01-10 07:21:19


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uczrhi1lpivc553lut09.jpg)

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](https://vitejs.dev/)

    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](https://www.npmjs.com/package/concurrently).

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:

![Preview of the microfrontend](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5ilxlxlw8a1b7gkdtpj.gif)

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!