5 Steps to Turn a Random React Application Into a Micro Front-End

Get started with micro front-ends, a novel way to run multiple applications, that feel like just one application

Jennifer Fu
Feb 25 · 7 min read
Photo by Duminda Perera on Unsplash

What is a micro front-ends approach? The term micro front-ends first came up in the ThoughtWorks Technology Radar in November 2016. It extends the concepts of microservices to front-end development.

The approach is to split the browser-based code into micro front-ends by breaking down application features. By making smaller and feature-centered codebases, we achieve the software development goal of decoupling.

Although the codebases are decoupled, the user experiences are coherent. In addition, each codebase can be implemented, upgraded, updated, and deployed independently.

Here is the paradise of micro front-ends. JavaScript applications, regardless of frameworks and versions, are launched by a container. These applications, legacy and new, work together seamlessly, and act like one application.

In our example, we will tackle the simpler case of React micro front-ends.


Prior Work to Build a Micro Front-End Container That Launches a React Application

Luckily, Cam Jackson published his micro front-ends work for us to adopt. His work is captured in this location:

  • A Container: Entry point and container application for a micro front-ends demo.
  • A micro front-end for browsing restaurants: Browse.
  • A micro front-end for ordering food from a restaurant: Restaurant-order.
  • A Content server: Place to store static content for the micro front-end demo.

This is the workflow of how micro front-ends work:

  • Launch Content server.
  • Launch Browse and Restaurant-order applications on specific ports.
  • Based on the URL, the Container will route to one of the micro front-ends.
  • The selected micro front-end goes to the specific port to fetch the application’s asset-manifest.json. From this JSON file, the included main.js is put on a script tag and loaded.

A manifest file contains a mapping of all asset filenames to their corresponding output file so that tools can pick it up without having to parse index.html. The centerpiece of this Container is the following MicroFrontend.js:

Lines 13 to 22 contain the code to launch a micro front-end. Usually, there is no communication between micro front-ends, and there is limited communication between the container and micro front-ends.

Typically, it is one way from the container to micro front-ends. Here, line 34 passes the containerId and history for its micro front-ends to be rendered as follows:

ReactDOM.render(<App history={history} />, document.getElementById(containerId));

Line 18 sets the script’s crossOrigin value to be empty, which is equivalent to anonymous. It means that the request for the element will have its mode set to cors and its credentials mode set to same-origin.

We revised Cam’s example a bit in our actual code. Regardless, this is the foundation we use. Based on that, we can show you how to turn an application into a micro front-end.


5 Steps to Turn a Random React Application Into a Micro Front-End

A lot of principles of Facebook’s crown jewel application are described in 10 Fun Facts About Create React App. In this article, we emphasize applying these principles.

Step 1: Modify package.json to set port and use “react-app-rewired”

  • In line 12, react-app-rewired is added as a dependency — This allows customizing the app without ejecting it.
  • In line 15, the app’s start port has been changed from the default port 3000 to a selected 4000 — This avoids the port conflict since the Container itself runs on port 3000.
  • From line 15 to line 17, react-scripts is replaced by react-app-rewired.

With the new port, Create React App shows the UI as follows. (We cheated a bit. Using react-app-rewired requires changing step 2 before the app can run.)

Step 2: Use config-overrides.js to disable code splitting

http://localhost:4000/asset-manifest.json clearly shows the app has been chunked.

This loading optimization causes an issue to mount and unmount micro front-ends. We need to disable chunking by creating or editing config-overrides.js as follows:

Afterward, http://localhost:4000/asset-manifest.json shows no chunking.

If you did not generate your React app from Create React App, step 1 and step 2 can be accomplished by modifying the webpack configuration.

If you use our improved MicroFrontend.js, you don’t have to change to use react-app-rewired in step 1, and step 2 can be completely skipped. The details are described in “You Don’t Have to Lose Optimization for Micro-Frontends”.

Step 3: Make changes in src/index.js to define render and unmount functions

window.renderBrowse and window.unmountBrowse are defined. These methods are invoked by the Container’s MicroFrontend.js. Similar methods need to be defined for Create React App’s src/index.js.

From line 7 to line 19, window.renderCreatereactapp and window.unmountCreatereactapp are added.

Line 23 becomes conditional. If it is an independent application, it will be rendered to root element. If it is a micro front-end, it will be rendered to containerId by window.renderCreatereactapp.

Step 4: Use src/setupProxy.js to set up CORS rule

Access to fetch at ‘http://localhost:4000/asset-manifest.json' from origin ‘http://localhost:3000' has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

The following proxy has to be set up by creating or editing src/setupProxy.js.

Before going to step 5, we do some additional work for the Container.

In the .env file, the new host REACT_APP_CREATEREACTAPP_HOST needs to be added. The port 4000 needs to match the real port that Create React App is running on.

A similar change needs to be done to .env.production as well:

Add a navigation link in AppHeader.js to make it accessible by the UI. This is optional.

Add Createreactapp and its route into the Container’s App.js:

Now let’s try to showcase our micro front-ends.

  • The Content server: npm start.
  • The Browse micro front-end: npm start.
  • The Restaurant-order micro front-end: npm start.
  • The Create React App micro front-end: npm start.
  • The Container: npm start.

Go to localhost:3000/createreactapp to launch the page.

Oops, where is the React spinning log?

Let’s revisit http://localhost:4000/asset-manifest.json. The micro front-end’s logo is a separate file:

We forgot to grab it!

Take a look at the source of this logo SVG file, which is set to /static/media/logo.5d5d9eef.svg. This file is available in Create React App (https://localhost: 4000), but not in the Container (http://localhost: 3000).

Here is our final step.

Step 5: Configure the content host in the .env file and use it to prefix static content

REACT_APP_CONTENT_HOST=http://localhost:4000

When a micro front-end uses static content, it needs to prefix them with %REACT_APP_CONTENT_HOST% in the HTML, and process.env.REACT_APP_CONTENT_HOST in JavaScript.

Here we changed line 9 in src/App.js:

With this change, the logo SVG file is prefixed with http://localhost:4000.

The app works properly now.


Conclusion

Part of this work was contributed by Jonathan Ma.

Thanks for reading. I hope this was helpful.

This is a series about micro front-ends. The following is a list of other articles:

Better Programming

Advice for programmers.

Jennifer Fu

Written by

A seasoned frontend developer https://www.linkedin.com/in/jennifer-fu-53357b/

Better Programming

Advice for programmers.

More From Medium

More from Better Programming

More from Better Programming

More from Better Programming

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade