Quick Summary:
This blog covers a complete guide on how one can implement a React Micro frontend, along with a firm understanding of the React Microservices Architecture, the benefits of such monolithic applications built using Micro frontend architecture React, the various implementations of the same, and an ideal tutorial for building a Micro frontend with React.
Monolithic architecture, the norm in software development for decades, is being replaced by microservices as an alternate strategy. Initially, the success of monolithic designs has a long history. Consequently, several software vendors and industry leaders firmly believe in its benefits. However, as time changes, new technical advancements appear that are more advantageous than everyone seems accustomed to.
React micro frontend architecture is not a new concept but a progression of earlier architectural patterns. Disruptive innovation trends in social media, cloud computing, and the Internet of Things (IoT) are heavily influencing the platform of microservice architecture to penetrate the market quickly.
Thanks to the move to continuous deployment. Microservices, in the form of React micro frontend help businesses in the following ways:
Utilizing Micro front architecture React can assist you in developing and deploying faster while improving maintainability. Following is the list of the benefits you avail by using micro frontend in React:
Dealing with large and complex codebases becomes challenging for developers. Here, the React microservices frontend plays a vital role as it separates your code into simpler ones. As a result, it makes the codebase more manageable, improves visibility, and provides clarity to write better code.
One of the core benefits of micro front architecture is its improved scalability efficiency. As demand grows, each module in the micro font design scales autonomously. Moreover, horizontal scaling supports the program’s workload and traffic.
It is time-consuming and requires lots of effort to add new functionality to an extensive, outdated, monolithic front-end application. However, with the help of the micro front in React, you can divide the app into distinct parts and add new features and functionality. Also, it enhances gradually by reducing interruption and adding new features without hampering the system’s scalability and performance.
Smaller parts and properly assigned modules make deployment easier and quicker. Moreover, microfront allows the individual deployment of each component. As a result, adding new features and functionality to your React application saves time and effort.
Micro front can divide a large workforce into smaller sub-groups, eventually boosting productivity and performance. In addition, your team can focus on the React micro frontend because of autonomy, promoting higher development cycles. Also, it indicates that each team member can take charge of specific aspects of the product, allowing them to create appliction effectively.
Also, it offers-
Let us show you a tutorial guide on how to build the Micro frontend architecture React. Here, we will be building two applications: a host and remote, where the main application is the host and another is a sub-app that we plug into.
The host app will be our “main” app and the remote app will be a sub-app plugging into it.
First, we will be creating a basic React app using create-react-app.
This will create two apps for you:
1. host-app/
2. remote-app/
Within each host-app/ and remote-app/ run:
npm install –save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader css-loader
This will install the webpack & dependencies that we need for webpack configuration.
NOTE:-Webpack Module Federation is available in version 5 and above of webpack.
After adding dependencies, we can host our app.
Do you wish to create a React Micro Frontend application for your users to hastily find them their solution and to scale your business?
Hire Reactjs developers from Bacancy as we are early adopters of the magnificent possibilities in the frontend. Our veteran React developers have years-long experience with industry-wide domains of small & big dimensions.
Let us start with our webpack configuration
Create a new webpack.config.js file at the root of host-app/ & remote-app/:
//host-app/webpack.config.js const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: "./src/index", mode: "development", devServer: { port: 3000, }, module: { rules: [ { test: /\.(js|jsx)?$/, exclude: /node_modules/, use: [ { loader: "babel-loader", options: { presets: ["@babel/preset-env", "@babel/preset-react"], }, }, ], }, { test: /\.css$/i, use: ["style-loader", "css-loader"], }, ], }, plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html", favicon: "./public/favicon.ico", manifest: "./public/manifest.json", }), ], resolve: { extensions: [".js", ".jsx"], }, target: "web", };
// remote-app/webpack.config.js const HtmlWebpackPlugin = require("html-webpack-plugin"); const path = require("path"); module.exports = { entry: "./src/index", mode: "development", devServer: { static: { directory: path.join(__dirname, "public"), }, port: 4000, }, module: { rules: [ { test: /\.(js|jsx)?$/, exclude: /node_modules/, use: [ { loader: "babel-loader", options: { presets: ["@babel/preset-env", "@babel/preset-react"], }, }, ], }, { test: /\.css$/i, use: ["style-loader", "css-loader"], }, { test: /\.(gif|png|jpe?g|svg)$/, use: [ { loader: "file-loader", options: { name: "[name].[ext]", outputPath: "assets/images/", }, }, ], }, ], }, plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html", favicon: "./public/favicon.ico", manifest: "./public/manifest.json", }), ], resolve: { extensions: [".js", ".jsx"], }, target: "web", };
This basic webpack example is to get our js and jsx code transpiled using babel-loader and injected into an HTML template.
Change the start script in package.json to utilize our webpack config:-
First, we need the index.js as an entry to our app. Another file we are importing is bootstrap.js which renders the React app.
We need this extra layer of indirection because it will give Webpack a chance to load all of the imports it needs to render the remote app.
Otherwise, you will see an error like this:
The shared module is not available for eager consumption
// Note: It is important to import bootstrap file dynamically using import() statement otherwise you will see the same error.
Next, we define the bootstrap.js file for both repos that render our React application.
import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( < React. Strict Mode > < App / > );
Now we can write our App.js file where the app’s main logic happens. Here we will load two components from 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 also 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.
// host-app/src/App.js import React from "react"; import ErrorBoundary from "./ErrorBoundary"; const RemoteApp = React.lazy(() => import("Remote/App")); const RemoteButton = React.lazy(() => import("Remote/Button")); const RemoteWrapper = ({ children }) => ( ); export const App = () => ( ); export default App;{children}
You can add the ErrorBoundary component from this repo.
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:
Add the following code to the plugins.
// host-app/webpack.config.js const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); const { dependencies } = require("./package.json"); module.exports = { //... plugins: [ new ModuleFederationPlugin({ name: "Host", remotes: { Remote: `Remote@http://localhost:4000/moduleEntry.js`, }, shared: { ...dependencies, react: { singleton: true, requiredVersion: dependencies["react"], }, "react-dom": { singleton: true, requiredVersion: dependencies["react-dom"], }, }, }), ], };
Important things to note:
Name:- It is used to distinguish the modules.
Remotes:- It 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 that we can load the components using import(“Remote/
Shared:- It is how we share dependencies between modules. This is very important for React because it has a global state, meaning you should only ever run one instance of React and ReactDOM in any given app. To achieve this in our architecture, we are telling webpack to treat React and ReactDOM as singletons, so the first version loaded from any modules will be 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 to minimize the number of duplicate dependencies between our modules.
Now, if we run npm start in the host app we will be able to see the output on the screen.
This means our host app is configured, but our remote app is not exposing anything yet. So we need to configure that also.
Let’s start with the webpack configuration file. As we have configured it host-app, we have some knowledge of Module Federation:
Add the following code to the plugins.
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); const { dependencies } = require("./package.json"); new ModuleFederationPlugin({ name: "Remote", filename: "moduleEntry.js", exposes: { "./App": "./src/App", "./Button": "./src/Button", }, shared: { ...dependencies, react: { singleton: true, requiredVersion: dependencies["react"], }, "react-dom": { singleton: true, requiredVersion: dependencies["react-dom"], }, }, }),
The important things we can note from the above code are:
exposes is where we define the code we want to share in the moduleEntry.js file. Here we are exposing two files: < App / > and < Button / >.
Now We can set up those components and our Remote app so it can run independently.
import React from "react"; export const App = () => { return Hello from the Remote App; }; export default App;
And we also want to expose a < Button / > component.
Now We have configured the Remote app and if you run npm start we can see a blank page with “Hello from the other side.”
Now you can put both repos in one folder and start both on single command:-
One package.json file will be created. Now add the following changes in package.json:-
"workspaces": { "packages": [ "host", "remote" ] }, "scripts": { "start": "npm run start:host & npm run start:remote", "start:host": "cd ./host-app && npm start", "start:remote": "cd ./remote-app && npm start", "start:all": "yarn workspaces run start", "cleanup": "yarn workspaces run cleanup" },
This will run both repos in a single command. And you can see the output.
The developer doesn’t recommend creating a React micro frontend App using the create-react-app command. However, we hope you found this tutorial helpful.Typically, some crucial elements have contributed significantly to the popularity and momentum of micro frontend architecture.
Most product-based businesses use micro frontend architecture to speed up and lower the cost of development. In the coming years, monolith design might only be used to develop prototypes of new goods. At the same time, micro frontend architecture React that offers modularity and simple program scaling might be employed for mainstream development.
Meanwhile, get in touch with a React js development company that offers efficient and dynamic solutions, if you want more insightful guidance on micro frontend architecture
The core idea behind developing micro frontends is to be technology agnostic, to isolate team code, to establish team prefixes, to favor native browser features over custom APIs, and to build a resilient site.
Some of the evident cons of micro front-end architecture are a lack of control over interfaces between modules, increased payloads, complex development processes, and cohesive UX.
New feature roll outs, performance enhancements, and code reusability are the pros of having a micro front-end architecture.
Your Success Is Guaranteed !
We accelerate the release of digital product and guaranteed their success
We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.