“Sharing code is not easy. Depending on your scale, it can even be unprofitable.”-Zack Jackson
This was a simple insight that prompted Zack Jackson and his team to come up with Webpack Module Federation (WMF). Sharing code and dependencies between different code bases is painful, especially in large applications. The same reason makes working with multiple teams on large and complex applications together difficult. In fact, this is also the reason why maintaining a monolithic frontend application when several teams are working on the same app is challenging.
Webpack module federation is easy to maintain and can help significantly in scaling up the application. Before we go deep, let’s get a quick overview.
What Is Module Federation?
Webpack Module Federation (WMF) is a feature of Webpack 5 that allows the sharing of code and components between different applications. By using WMF, we can build applications as federated architectures, with different parts of an application loaded on-demand, on the client side. It can improve performance and provide greater flexibility and modularity in application development.
What Are Micro Frontends?
Micro frontends Webpack Module Federation enables the creation of modular, independent components that we can share across different applications. It thus improves the modularity, scalability, and maintainability of the overall application. They allow for greater flexibility. We can develop them using different frameworks or technologies hosted on other servers or domains. It can further be used to implement various features or functionality within an application.
How Does Webpack Module Federation Work?
Webpack Module Federation allows multiple web applications to share code and collaborate on functionality in a distributed way. It enables applications to consume code from other applications without building and deploying a separate version of the shared code. We can do it by allowing applications to expose specific modules and consume modules from other applications at runtime rather than doing that during the build process. It guarantees a more dynamic and flexible architecture where applications can be composed of independent modular pieces that can be updated and changed more easily.
Benefits of Webpack Module Federation
- Improved performance: By loading different parts of an application on-demand, WMF can reduce the initial load time and improve performance.
- Greater modularity and flexibility: WMF allows the creation of federated architectures that can be more modular and flexible than traditional monolithic applications.
- Code sharing: Sharing code and components between different applications becomes easy with WMF. It also reduces development time and improves code quality.
- Independent development: WMF allows teams to work independently on different parts of an application and deploy them separately without affecting other parts.
Here’s a list of key terms and definitions related to Webpack Module Federation.
- Module: A single file or piece of code that is shared between applications using Module Federation Webpack.
- Host: The application serves as an entry point for a module federation. The host application can expose modules that other applications can consume.
- Remote: An application that consumes modules from a host application.
- Exposed module: It is a module that is exposed by a host application and is consumed by other applications.
- Remote module: It is a module that is consumed by a remote application from a host application.
- Container: The Webpack container that enables module federation. The container provides the infrastructure for module federation, enabling the applications to share code at runtime.
- Scope: A unique identifier that is used to namespace modules in a module federation. Scopes help to prevent naming collisions between different applications.
- Shared module: It is a module that is shared between multiple applications. Use shared modules to reduce code duplication and improve code reuse.
Webpack Module Federation Configuration in React Application
- First, make sure you have Webpack installed and create two React apps, let’s call them app1 and app2.
- In the root directory of each app, install the necessary dependencies:
npm install webpack webpack-cli webpack-dev-server react react-dom
- app1 and app2 package.json name (
”name”: “app1”), must be different for different micro frontends.
- In app1, create a webpack.config.js file and add the following code:
In this configuration file, we’re using the ModuleFederationPlugin to expose a React component called Button from app1.
- In app1, create a Button.js file in the src directory and add the following code:
This is the React component that we’ll be exposing.
- In app2, create a webpack.config.js file and add the following code:
In this configuration file, we’re using the ModuleFederationPlugin to consume the Button component from app1.
- In app2, create an App.js file in the src directory and add the following code:
This React component imports the Button component from app1 using the React.lazy() function and renders it inside a React.Suspense component.
- Start both apps using the following commands in their respective directories:
This will start both apps and allow them to communicate with each other using Webpack’s Module Federation.
Now if you go to
http://localhost:3002, you should see a page that says “Hello from App 2!” and a button that says, “Button from App 1”.
Some of the Key Points to Remember
- In module federation, we can federate js files.
- For CSS/SCSS etc, we need to import the style in the component and expose the component. CSS will automatically be federated.
- Package.json has a “name” key, this key must be unique in each micro frontend (it’s important).
- Redux reducers can also be federated, and we can create a single store in the container application.
- Locales can also be federated and merged as a single locale file for the whole application at run time. It’s similar to what we do with reducers.
- If you are using typescript, importing a federated component might show error in IDE, just create a d.ts file and declare the component as a module.