React Micro-Frontends using Vite

abhi0498

Abhishek V

Posted on October 5, 2023

React Micro-Frontends using Vite

Source code for this article is available on GitHub.

In this article


Introduction

Micro Frontends: Enhancing Web Development with Vite and Module Federation

In this article, we'll explore the concept of Micro Frontends—a powerful architectural approach for web applications. Micro Frontends allow you to divide your front-end code into smaller, independently developed and deployable units. These units, known as micro frontends, offer numerous benefits, including increased development speed, scalability, and flexibility. By enabling different teams to work on separate parts of the front end while maintaining integration through an isolation layer, Micro Frontends help manage complexity and promote autonomy in front-end development.

What is a Micro Frontend?

A Micro Frontend is an architectural approach for web applications where the front-end code is divided into smaller, independently developed and deployable units called micro frontends. This approach enhances development speed, scalability, and flexibility by allowing different teams to work on separate parts of the front end while maintaining integration through an isolation layer. It's a way to manage complexity and promote autonomy in front-end development.

Module Federation

Module Federation is a key technology that enables a JavaScript application to load code dynamically from another application while sharing dependencies. When an application consuming a federated module lacks a required dependency, Webpack (the underlying technology) automatically fetches the missing dependency from the federated build source. This allows for efficient sharing and use of common libraries across multiple micro frontends.

Why Vite?

While Module Federation was initially introduced in Webpack, the landscape of JavaScript development has evolved. Vite has emerged as a game-changer by providing lightning-fast build times. Combining Vite and Module Federation can unlock immense capabilities for developing micro frontends quickly and efficiently.

Creating a Micro Frontend using Vite + React

Creating a micro frontend typically involves two main parts:

  1. Host Application: This is the primary application that users interact with. It serves as the container for the micro frontends.

  2. Remote Application: These are the micro frontends themselves, which act as building blocks for the host application.

Now that we have an understanding of the technologies we'll be using, let's dive into the practical implementation.

Setting Up the Host App

To create a host application using Vite and React, run the following command:



# Using npm 6.x
npm create vite@latest host-app --template react

# Using npm 7+, add an extra double-dash:
npm create vite@latest host-app -- --template react


Enter fullscreen mode Exit fullscreen mode

Setting Up the Remote App

For the remote application, execute the following command:



npm create vite@latest todo-components -- --template react


Enter fullscreen mode Exit fullscreen mode

This will create two folders, host-app and todo-components. Next, install the dependencies for both apps:



npm install


Enter fullscreen mode Exit fullscreen mode

Creating Components in the Remote App

In the todo-components app, create the following components:



// components/List.jsx
import React from "react";

const List = (props) => {
  const { items } = props;
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
};

export default List;


Enter fullscreen mode Exit fullscreen mode


// components/Input.jsx
import React from "react";

const Input = (props) => {
  const { value, onChange, onSubmit } = props;
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        onSubmit(e);
      }}
    >
      <div className="flex-row">
        <input
          type="text"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        />
        <button type="submit">Add</button>
      </div>
    </form>
  );
};

export default Input;


Enter fullscreen mode Exit fullscreen mode

Now that the components are ready, make the following changes to the App.jsx file:



// App.jsx
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
import Input from "./components/Input";
import List from "./components/List";

function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <Input value={count} onChange={setCount} onSubmit={console.log} />
      <List items={["Learn React", "Learn Vite", "Make an awesome app"]} />
    </>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

Previewing the Remote App

To preview the components, run the following command in the todo-components app:



npm run dev


Enter fullscreen mode Exit fullscreen mode

You should see the following output.

Remote App Preview

Adding Module Federation to the Remote App

Now, let's add Module Federation to the todo-components app. First, install the necessary dependencies:



npm install @originjs/vite-plugin-federation --save-dev


Enter fullscreen mode Exit fullscreen mode

Next, configure Module Federation in the vite.config.js file:



// vite.config.js in todo-components
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import federation from "@originjs/vite-plugin-federation";

export default defineConfig({
  plugins: [
    react(),
    federation({
      name: "todo-components",
      filename: "remoteEntry.js",
      exposes: {
        "./List": "./src/components/List.jsx",
        "./Input": "./src/components/Input.jsx",
      },
      shared: ["react"],
    }),
  ],
  build: {
    modulePreload: false,
    target: "esnext",
    minify: false,
    cssCodeSplit: false,
  },
});


Enter fullscreen mode Exit fullscreen mode

In this configuration:

  • name: Specifies the name of the remote app.
  • filename: Sets the name of the file generated by Module Federation.
  • exposes: Lists the components to expose from the remote app.
  • shared: Declares shared dependencies, such as React, to optimize the bundle size.

Now, build the remote app:



npm run build


Enter fullscreen mode Exit fullscreen mode

This generates a dist folder in the todo-components app containing a remoteEntry.js file.

Serving the Remote App

Serve the remote app locally:



npm run preview


Enter fullscreen mode Exit fullscreen mode

This serves the remote app on port 4173.

Adding Module Federation to the Host App

To use the remote app components in the host app, set up Module Federation in the vite.config.js file of the host app:



// vite.config.js in host-app
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import federation from "@originjs/vite-plugin-federation";

export default defineConfig({
  plugins: [
    react(),
    federation({
      name: "host-app",
      remotes: {
        todo_components: "http://localhost:4173/assets/remoteEntry.js",
      },
      shared: ["react"],
    }),
  ],
  build: {
    modulePreload: false,
    target: "esnext",

    minify: false,
    cssCodeSplit: false,
  },
});


Enter fullscreen mode Exit fullscreen mode

In this configuration:

  • name: Specifies the name of the host app.
  • remotes: Lists the remote apps to be used by the host app. In this case, we have one remote app, "todo_components," and we provide the URL of its remoteEntry.js file.
  • shared: Declares shared dependencies, such as React, to optimize the bundle size.

Using Remote Components in the Host App

Now, you can import and use the remote app components in the host app's App.jsx:



// App.jsx in host-app
import { useState } from "react";
import List from "todo_components/List";
import Input from "todo_components/Input";

function App() {
  const [newTodo, setNewTodo] = useState("");
  const [todos, setTodos] = useState([]);
  const onSubmit = () => {
    setTodos((prev) => [...prev, newTodo]);
    setNewTodo("");
  };

  return (
    <>
      <Input value={newTodo} onChange={setNewTodo} onSubmit={onSubmit} />
      <List items={todos} />
    </>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

Here, we import the components from the remote app using the specified remote name, "todo_components."

Serving the Host App

To serve the host app locally, run:



npm run dev


Enter fullscreen mode Exit fullscreen mode

Now, you should see that the components from the remote app are being used seamlessly in the host app.

Conclusion

In this article, we've explored the concept of Micro Frontends and demonstrated how to create a micro frontend architecture using Vite and React, enhanced with Module Federation. By leveraging the power of Vite's fast build times and Module Federation's dynamic code loading capabilities, you can efficiently develop and scale web applications in a modular and maintainable way. This approach empowers multiple teams to work on different parts of the app independently, promoting flexibility and agility in front-end development.

For further exploration and to apply these concepts to your own projects, feel free to adapt and expand upon the examples provided here. Micro Frontends, when used judiciously, can significantly streamline your web development workflow.

💖 💪 🙅 🚩
abhi0498
Abhishek V

Posted on October 5, 2023

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

Sign up to receive the latest update from our blog.

Related

React Micro-Frontends using Vite
react React Micro-Frontends using Vite

October 5, 2023