Vite + Module Federation is AMAZING!

Learn how to create scalable frontend applications using Vite and Module Federation.

Vite + Module Federation is AMAZING!

October 27, 2024

Vite πŸ’» Module Federation React

Table of contents

  1. Introduction
  2. Step 1: Create the host and remote applications
  3. Step 2: Config the remote application
  4. Step 3: Config the host application
  5. Step 4: Build and test the application
  6. Conclusion
  7. References

Introduction

Personally, I love the simplicity of Vite, so for this post we will try to explain in a simple, step by step way how we can modularize our frontend applications to use a microfrontend architecture.

The microfrontend architecture allows us to divide parts of our application into individual and autonomous modules, allowing frontend teams the same level of flexibility and speed that microservices provide to backend teams.

For this post I will use Bun so it will be a dependency to keep in mind if you want to follow it step by step.

You can install Bun by following the instructions in this link.

Step 1: Create the host and remote applications

First, create the host and remote React applications using Vite CLI.

Terminal window
bun create vite host --- --template react-ts
bun create vite remote --- --template react-ts

Step 2: Config the remote application

Now, let’s install the necessary dependencies and add the Module Federation plugin to the remote application.

Terminal window
cd remote
bun install
bun install @module-federation/vite

Create a new folder and file for the component that will be exposed by the remote application.

Terminal window
mkdir ./src/components
touch ./src/components/ExampleComponent.tsx

Add the following code to the ExampleComponent.tsx file.

export default () => {
return <span style={{
backgroundColor: 'lightblue',
borderRadius: '5px',
padding: '5px',
margin: '5px',
display: 'inline-block',
border: '1px solid black',
}}>
Module Federation 😎 </span>;
};

In the vite.config.ts file, add the following configuration to expose the component.

import { federation } from '@module-federation/vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
export default defineConfig(() => ({
build: {
target: 'chrome89',
},
plugins: [
federation({
filename: 'remoteEntry.js',
name: 'remote',
exposes: {
'./remote-app': './src/components/ExampleComponent',
},
remotes: {},
shared: {
react: {
requiredVersion: dependencies.react,
singleton: true,
},
},
}),
react(),
],
}));

Update the package.json scripts to build and preview the remote application using the 4174 port.

"scripts": {
"dev": "vite --port 4174",
"build": "tsc && vite build",
"preview": "bun run build && vite preview --port 4174"
},

Build and preview the remote application.

Terminal window
bun run build
bun run preview

If you open the browser and go to http://localhost:4174/remoteEntry.js, you should see the remote entry file that will be consumed by the host application.

alt text

Step 3: Config the host application

Now, in other terminal, go to the host application and install the necessary dependencies and add the Module Federation plugin.

Terminal window
cd host
bun install
bun install @module-federation/vite

In the vite.config.ts file, add the following configuration to consume the remote component.

import { federation } from '@module-federation/vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
export default defineConfig(() => ({
build: {
target: 'chrome89',
},
plugins: [
federation({
name: 'host',
remotes: {
remote: {
type: 'module',
name: 'remote',
entry: 'http://localhost:4174/remoteEntry.js',
entryGlobalName: 'remote',
shareScope: 'default',
},
},
exposes: {},
filename: 'remoteEntry.js',
shared: {
react: {
requiredVersion: dependencies.react,
singleton: true,
},
},
}),
react(),
],
}));

Update the package.json scripts to build and preview the host application using the 4173 port.

"scripts": {
"dev": "vite --port 4173",
"build": "tsc && vite build",
"preview": "bun run build && vite preview --port 4173"
},

Add the following code to the App.tsx file to consume the remote component.

import { lazy, useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
const RemoteComponent = lazy(
// @ts-ignore
async () => import('remote/remote-app'),
);
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React + <RemoteComponent/> </h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App

Step 4: Build and test the apllication

Build and preview the host application.

Terminal window
bun run build
bun run preview

If you open the browser and go to http://localhost:4173/, you should see the remote entry file that will be consumed by the host application!

alt text

Conclusion

Vite + Module Federation is a powerful combination that allows us to create scalable frontend applications and can be very easy to implement!

I hope you found this guide useful, that you can start using it in your projects and that you can share it with your colleagues.

If you have any questions, feel free to ask via social media.

Happy coding!

References