4

How to Use Webpack Module Federation in React

 2 years ago
source link: https://betterprogramming.pub/how-to-use-webpack-module-federation-in-react-70455086b2b0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

How to Use Webpack Module Federation in React

Build micro-frontend architectures with ease

0*Ym1GHIV2FAgAwTl_

Photo by Valery Fedotov on Unsplash

Module Federation is a great tool for constructing a micro-frontend architecture in React applications. I will show you how to use it in a step-by-step guide to build a Host-Remote pattern micro-frontend in React.

Why a Micro Frontend?

Micro-frontends help us break large frontend applications into smaller independent applications or modules that can be built and deployed at their own cadence.

Doing this using Module Federation allows us to combine the applications at run time in the client’s browsers and eliminate build-time dependencies and coordination allowing the teams building these applications to develop at scale.

Getting started

The final configuration can be found here: https://github.com/rautio/react-micro-frontend-example

We are building two applications: host and remote.

The host app is the "main" app and remote is a sub-app plugging into it.

Module Federation does support treating the host as a remote and make the architecture peer-to-peer if it fits your use case. More on this later.

We’re going to use create-react-app to simplify the initial steps.

In your root directory:

npx create-react-app hostnpx create-react-app remote

This will create two apps for you:

host/remote/

Dependencies

Within each host/ and remote/ run:

npm install --save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader

This will install wepback and the dependencies we need for our webpack configuration.

Webpack Module Federation is only available in version 5 and above of webpack.

Host App

We are going to start with our own webpack configuration

Create a new webpack.config.js file at the root of host/:

This is a basic webpack example to get our js and jsx code transpiled using babel-loader and injected into an html template.

Update package.json scripts

Next, we need a new start script that utilizes our webpack config:

Now we can get to the meat of the host app.

index.js

First we need the index.js entry to our app. We are importing another file bootstrap.js which renders the React app.

The reason we need this extra layer of indirection is it gives Webpack a chance to load all of the imports it needs to render the remote app.

Otherwise, you would see an error along the lines of:

Shared module is not available for eager consumption

bootstrap.js

Next, we define the bootstrap.js file that renders our React application.

App.js

Now we are ready to write our App.js file where the main logic of the app happens. Here we are going to load 2 components from the remote which we will define later.

import("Remote/App") will dynamically fetch the Remote app's App.js React component.

We need to use a lazy loader and an ErrorBoundary component to create a smooth experience for users in case the fetching takes a long time or introduces errors in our host app.

Add Module Federation

We’re not ready to run the app just yet. Next, we need to add Module Federation to tell our host where to get the Remote/App and Remote/Button components.

In our webpack.config.js we introduce the ModuleFederationPlugin:

Important things to note:

  • name is used to distinguish the modules. It is not as important here because we are not exposing anything but it is very important in the Remote app.
  • remotes is where we define the federated modules we want to consume in this app. You'll notice we specify Remote as the internal name so we can load the components using import("Remote/<component>"). But we also define the location where the remote's module definition is hosted: Remote@http://localhost:4000/moduleEntry.js. This URL tells us three important things. The module's name is Remote, it is hosted on localhost:4000 and its module definition is moduleEntry.js.
  • shared is how we share dependencies between modules. This is very important for React because it has a global state which means you should only ever run one instance of React adn ReactDOM in any given app. To achieve this in our architecture we are telling webpack to treat React and ReactDOM as singleton so the first version loaded from any of the modules is used for the entire app. As long as it satisfies the requiredVersion we define. We are also importing all of our other dependencies from package.json and including them here so we minimize the number of duplicate dependencies between our modules.

Now if we run npm start in the host app we should see something like:

0*xnYjLPivX1xpQiBW.png

This means our host app is fully configured but our remote app is not exposing anything yet. So we need to configure that next.

Remote App

Let’s start with the webpack config. Since we now have some knowledge of Module Federation let's use it from the get-go:

The important things to note are:

  • Our webpack dev server runs at localhost:4000
  • The remote module’s name is Remote
  • The filename is moduleEntry.js

Combined these together will allow our host to find the remote code at Remote@http://localhost:4000/moduleEntry.js

exposes is where we define the code we want to share in the moduleEntry.js file. Here we are exposing two: <App /> and <Button />.

Now let's set up those components and our Remote app so it can run on its own.

index.js

Similar to the Host app we need a dynamic import in our webpack entry.

bootstrap.js

App.js

The Remote app is much simpler than the Host:

Button.js

And we also want to expose a <Button /> component

Now the Remote app is fully configured and if you run npm start you should see a blank page with "Hello from the other side."

Putting it all together

Now if we run npm start in both the host/ and remote/ directories we should see the Host app running on localhost:3000 and the remote app running on localhost:4000.

The host app would look something like this:

0*ahuJQRrFhG6jJVX9.png

Congratulations! You’ve now configured a Micro Frontend app using React.

Development

You can simplify the development flow by configuring yarn workspaces at the root level: https://classic.yarnpkg.com/lang/en/docs/workspaces/

Deployment

We only covered running the Micro Frontend locally. If you want to deploy them you would deploy each app separately to their own CDN or hosting service and configure the webpack definitions to use environment variables or some other way to dynamically update the URLs in the ModuleFederationPlugin definitions.

An example of this can be found in my more advanced example app: https://github.com/rautio/micro-frontend-demo

Resources

Code for this example:

A more advanced example:

Webpack’s example app for peer-to-peer structure:

Webpack docs:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK