15 March 2021
Micro frontend tutorial: Creating a dynamic 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 – the micro frontend approach
Chances are that your browser history is full of micro frontend articles already. After all, it is now a very popular subject for a number of reasons.
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 micro frontend application development is done in modules, which makes programmers feel empowered.
They can build faster, deploy a micro frontend app 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. Thus, implementing micro frontends holds a lot of potential ways of unlocking the potential in terms of software development and delivery.
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
📚 The State of Frontend 2022 is out and ready for you!
Built on surveys by 3700 frontend developers from 125 countries, enriched with 19 expert commentaries, divided into 13 topical sections State of Frontend is the most up-to-date information source.
Check where do you (and your organization) fit within the modern frontend landscape.
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 JSON file 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.
Because react
and 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 Webpack
configuration.
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 name
is
components@http://localhost:8080/remoteEntry.js
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 a 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 components
).
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 exampleindex.html
file.
Cross-component chatter
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.
For 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, with a number of user interface, app component and container app issues, 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:
- The single-spa framework that lets you use different JavaScript languages for each function of your micro frontend project
- 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.