The concept of micro front ends is one where you encapsulate separate web apps, possibly even using different technologies in the same website. Where they act as independent components, some of them might listen to different services or communicate to entirely different ones.
In this article we will build Pseudo Micro Front Ends. A term that I came up with and is not refrective of others, since what we will be building wont be exactly a traditional micro front end architecture (at least in the time that this is being written). Some people, actually consider them purely a deployment method. We will be using React and its Component based logic as building blocks too create reusable components, that we will consume on a another application. To achieve that, we will be using webpack and its module federation plugin. And yes, the application is going to support a global Redux store,so our various independent modules can communicate with each other.
Here is what we will be making:
A base ReactJs application with independent components that communicate through a store, that can be used in any sort of arrangement. Like small widgets, able to be imported and used on a consumer project. We will also be serving the Redux store for the consumer use in order to keep all the cross Component functionality intact.
How we will be making it:
The base project is a container where all of our components will be defined, along with their functionality and store. We will be serving those components using webpacks module federation as a JS file bundle called remoteEntry.js .
On our consumer project we will be looking at the base project and fetch a component bundle to use wherever and how we please, as if they were defined locally on that same codebase. Here we can see that we are telling our webpack to look for a remoteEntry.js file at port 3000 of our localhost.
Our Base App
It is a dummy shop web app with 4 components and a redux store, those components are:
- Header, which is a dummy Header.
- TopSellers - a dummy component that is supposed to list the top selling products.
- Products - a component that lists our products, that we can add to our cart.
- Cart - a cart component that uses redux to see what components we added/removed on the Products component.
- The redux store that handles the Cart addition between the Product and Cart.
Taking a closer look at our appplication inside the browser, we can actualy find the remoteEntry.js file that we mentioned earlier. This is the bundle that contains all the code for the Components we are federating for consumber applications to use.
Our Consumer App
It is a web app that uses a simple css grid, to render all of the components defined on the base project, in a re-arranged manner. As you can see here we are using baseproject/nameof_component to import the non existent in the current directory component from our base project.
What we have achieved is share those Components from Base to Consumer and have them be completely independent and re-usable as we please on a second consumer app. In a scenario where you dont have to copy or use the same repository containing the same components, in case you want to have parts of the same application shared between others.
Next Steps and Improvements
As this is something fairly new to myself and i have not experimented enough i believe there are improvements that can be made to the execution Those are:
- Find a better way to structure css files, possibly using webpack to exclude them and have some sort of override method.
- Write a size detection hook to keep track of the dimensions of the component container node to deal with responsiveness.
- Make the store extendable, a good way would be to share the differect components and reducer files as smaller bundles instead of the allReducer and construct that to the consumer.
Issues.
As great of a feature this is, my issue with this method is the dependency you have on you consumer project on your base one. Currently if you build your consumer app for production, your Components bundle will NOT include the ones you need from the base app to work. So if your idea is to keep a Component/Widget store on your development enviroment and feed those your components to various projects, you either have to host those components somewhere, or forget about this methodology and do it as you would using a big mono repo with shared repositories.
You can find a link to the repository and how to run the application yourselves here
Thanks for sticking till the end.