15 March 2021
Micro frontend tutorial: Creating a form with React + Module Federation for Furgonetka.pl
Challenged by Furgonetka.pl with building a form prototype based on React, I placed my bet on a micro frontend architecture using Module Federation. Here’s how combining the two can help you deploy an app with a stack that’s easy to modify.
Why should you use micro frontends
Big-brain developers successfully pushed for a breakdown of the monolithic backend into microservices, and now they want to rebuild the frontend with them. It makes sense.
As applications become more stuffed, micro frontend architecture has been gaining in popularity since 2016. That’s because development is done in modules, which makes programmers feel empowered. They can build faster, deploy with efficiency, and communicate easier with their coding buddies. As digital products become more loaded, aggregating smaller elements into one front-end removes many development roadblocks.
Last year, we ran a survey for our latest State of Frontend report that touched on micro frontends. While only 24.4% of developers experimented with the technology, our friend Luca Mezzalira, Amazon AWS’ Principal Solutions Architect, sees them as a maturing solution that companies will adapt at a scale. Most respondents seem to agree.
Looks intriguing? Browse the State of Frontend 2020 report in a new tab to find more revealing facts and get updated on what fellow professionals think.
It’s incredibly exciting to see how people are embracing micro-frontend architecture nowadays. We already know, that there are many companies around the world using micro frontends – just to mention American Express, DAZN, IKEA, Spotify and Starbucks. Now, with the results of the State of Frontend survey, we also know that practically 1⁄4 of frontend devs have already developed micro frontends.
In this tutorial, rather than to sell you the idea of micro frontend architecture, I’d like to bring you into the coding ring to show you a practical application for micro frontends in an MVP build that +437,000 users might use. If you need a refresher on micro frontends before I continue with my ramble:
- Read a straight-up interview with IKEA’s senior engineer Gustaf N. Kotte about how micro frontends save developers from monolithic coding (and what it has to do with two pizzas)
- You could also listen to a myth-busting micro frontend webinar from Cam Jackson, ThoughtWorks’ lead developer
Upgrading a highly-used order form
As I was getting accustomed to Module Federation’s functionality, I had a chance to test it in a dynamic form project for Furgonetka.pl, which is a Polish logistics company that processes 50.000+ packages daily.
Their programmers wanted to level up their form’s technology (below) based on HTML and VanillaJS to include ReactJs elements, as they make event-based personalization easier.
My mission was to build a proof-of-concept app that:
- Provides asynchronous loading
- Offers a smooth transition between several form styles
- Uses ReactJS to stylize key components on request
- Is ready for automated translation
In my mind, I was designing something that Furgonetka.pl could adopt for the 2M visitors per month that their website serves. I figured that Module Federation is a solid framework for the job because the form could source code from different apps.
The React-based form has 3 key components I’ll present step-by-step so that you can review their logic and learn new, smart tricks. There’s the component library, a loader for federated modules, and a communication protocol for all components.
Packing up components
First, let’s build a simple npm component. Nothing fancy here — just something good enough to be installed and utilized in a React application. Below, there’s the code for a native implementation of a button without style but with basic state management.
Next, we need configuration for the bundler to build our tiny package. We’ll use Webpack 5 later on, as it includes the Module Federation feature.
Don’t repeat this, but this configuration isn’t that relevant. The goal is to use it as a traditional
npm-package as a fallback option in case Module Federation fails. What matters are the externals.
react-dom were installed as dependencies, we need to ensure that there will be only one instance of both in our application. Otherwise, it won’t work properly.
Moving on, we’ll apply the
ModuleFederationPlugin with a customized
Still awake? Let’s review the plugin options used there:
Name should be unique, as it is globally available in our web application. ”Components” is not preferable, but it’s okay for now.
Filename is the name for the remote entry. It is required in the context of exposing modules.
Exposes marks the place where we list all modules to be made available.
Shared options are the last thing. It’s where dependencies are shared with other applications, and where we ensure that react and react-dom won’t be present more than once.
How should this be handled in a React application? The
Webpack configuration is key. React application that consumes exposed modules needs to be informed where to find them. We define that in the setup of the
ModuleFederationPlugin and in the remotes option.
On this side of the apps’ communication, more important than the
Components is the name of our web components container defined earlier in the
webpack.mf.config.js file. This is followed by the URL for the components library dev server (in this case), and the
filename, which we also defined earlier. We will use the “component” key (that’s described by the “remotes”) when we import our component.
For a deeper look into shared components, see this video about coding a Header/Footer duo with Module Federation.
And that’s a wrap! We’re done with the basics. But wait — one piece is missing.
To finish our work on the library, we need to expose components as stand-alone applications to consume them in Vanilla.js environment. That was one of the primary goals for our Furgonetka.pl project. Let’s add three things.
The higher-order function allows us to mount any component
A shareable component that exposes the mount function
A modified webpack configuration
Now, we need a way of using this component that contains these 3 packages.
Load it up
For that purpose, a simple loader was made. When a request is made for the
remoteEntry, a container becomes globally available (hence the importance of a unique name). It exposes two methods:
The Get method allows us to lazy load components, and the init method enables the amazing dependency sharing functionality.
With that in mind, this simple loader was created, where the
SCRIPT environment variable stands for http://localhost:8080/remoteEntry.js with
CONTAINER for container name (in this case for
So what’s sizzling in the code? First,
remoteEntry.js is fetched. and after that, a shared scope is initialized. That’s the white magic of Webpack. Second, we load our component with the previously defined mount function, which allows us to attach it to the DOM element.
How should it be used? Here’s the
Furgonetka.pl needed the components to talk. Since there are many neat in-browser solutions, I decided to work with native events communication. For example, you have the Broadcast API, which sadly, isn’t supported by all browsers (Safari hides in shame). But polyfills are available.
To ensure communication takes place, I created a simple event bus on native events. Two reasons. One was to simplify the verbose native interface. What would be a fancy term for that? A facade? 😉 Second, we don’t pollute global events.
💡 Know more
So what did Furgonetka.pl get from this?
Because of this test project with TSH that took just 48 hours, the company could learn if micro frontends in React can help streamline their development.
- Furgonetka.pl avoided investing months of resource-heavy staff training just to experiment with a new stack
- Programmers can modify single components of the prototype form without rewriting all the code
- They now have a ReactJS solution that can be implemented for all language versions of the website
Furgonetka.pl development team is now testing if the micro frontend architecture that TSH prepared works with the logic of other front-end services on their main page.
When you want to upgrade the front end in bits
Micro frontends add extra complexity to the project, so unless it’s a big app, I wouldn’t poke them. In the case of Furgonetka.pl, the website needs to adjust to several user groups (per country, and B2B/B2C), and that’s where microservices can allow their developers to introduce modular changes without rebuilds.
For multiple teams working on front-end architecture, Module Federation might be invaluable, as the tool enables you to share code and dependencies. You can already use it with a single-spa framework as an alternative to importing maps. In the future, I expect that the Module federation will have native support for Next.js, which makes it much more interesting to explore.
If you’re keen on creating your next micro frontend project, consider adding these tools to your kit:
- Zalando’s Project Mosaic, which is a set of services and libraries for microservice architectures used by large websites
- There’s also the OpenComponents framework for scalability-ready micro frontends
Have some fun and dig into the code for this project on Github — our favorite multiplayer notepad 🙂
Test your software scalability options faster
🚀 Save months of resources with a prototype app developed by The Software House that answers any complex problem. Consult your idea today and join the 98% of customers who recommend us.