---
title: "Webpack Module Federation"
description: "Webpack’s Module Federation is a new feature that was introduced in Webpack5 with the intent of having multiple independent."
url: "https://h3manth.com/scribe/webpack-module-federation/"
canonical_url: "https://h3manth.com/scribe/webpack-module-federation/"
markdown_url: "https://h3manth.com/scribe/blog/webpack-module-federation.md"
publishDate: "2021-06-02T00:00:00.000Z"
author: "Hemanth HM"
category: "web"
tags: ["webpack","javascript","module-federation","microfrontends"]
word_count: 385
reading_time_minutes: 2
x_markdown_tokens: 844
content_signal: "ai-train=yes, search=yes, ai-input=yes"
---

# Webpack Module Federation

> Webpack’s Module Federation is a new feature that was introduced in Webpack5 with the intent of having multiple independent.

Webpack's [Module Federation](https://webpack.js.org/concepts/module-federation/) is a new feature that was introduced in Webpack5 with the intent of having multiple independent separate builds should form a single application, such that they can be shared and deployed exclusively.

Let us walk through a simple example. Assume there are two apps:
- **comic-app**: Standalone react app which fetches random comics from XKCD [remote-app].
- **home-app**: Standalone react app that uses comic-app's exposed component [host-app].

## How do we configure webpack to enable federation?

The `comic-app` is basically `exposing` one of its components that basically fetches the random XKCD comic. Let us say the component name is `FetchComic.jsx`. The `webpack` config for federation in the comic app would look like:

```javascript
plugins: [
  new ModuleFederationPlugin({
    name: "comic",
    filename: "remoteEntry.js",
    exposes: {
      "./FetchComic": "./FetchComic.jsx",
    },
    // always use the higher version found
    shared: [
      {
        react: {
          singleton: true, // only a single version of the shared module is allowed
          eager: true,
        },
        "react-dom": {
          singleton: true,
          eager: true,
        },
      },
    ],
  }),
];
```

- The configuration is exposing `FetchComic.jsx` with `exposes` attribute so that it can be `consumed` by the `home-app`.
- `react` and `react-dom` are the shared dependencies across the applications.

## Consumer Configuration

The `home-app` consumes the exposed component and the config would look like:

```javascript
plugins: [
  new ModuleFederationPlugin({
    name: "home",
    filename: "remoteEntry.js",
    remotes: {
      comic: `comic@https://localhost:1338/remoteEntry.js}`, // 1338 is the comic app port in this example
    },
    shared: [
      {
        react: { singleton: true, eager: true },
        "react-dom": { singleton: true, eager: true },
      },
    ],
  }),
];
```

## Using the Remote Component

Now, the `home-app` can dynamically import the remote component and use it like any other!

```javascript
import React, { useState, lazy, Suspense } from "react";

const FetchComic = lazy(() => import("comic/FetchComic"));

<Suspense fallback={() => "Meow"}>
  <div>
    <FetchComic />
  </div>
</Suspense>;
```

## Important Note on Bootstrapping

If you notice the directory structure is bit different compared to "regular" apps, as we have `eager` sharing, we would see a `Uncaught Error: Shared module is not available for eager consumption` error if we don't `bootstrap` the application, more details at [troubleshooting](https://webpack.js.org/concepts/module-federation/#troubleshooting).

Was discussing alternatives to `bootstrap` with my friend [Nikhil Motiani](https://computnik.dev/) who has been pawing hard at webpack federation.

You can also fork the repo from [webpack-module-federation-sample](https://github.com/hemanth/webpack-module-fedaration-sample) to get a taste of it.
