Skip to content
Mount React instances inside each other like they're components.
JavaScript CSS
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci
flow-typed/npm
packages
.editorconfig
.gitignore
README.md
commitlint.config.js
lerna.json
package.json
yarn.lock

README.md

react-micromount

CircleCI

React micromount is an experimental library that lets you mount React instances (or anything else) as though they are components. Unlike many other front end microservice libraries, react-micromount does not force you to microservice your code by routes, or enforce the use of iframes. It effectively allows you to create non-sandboxed micro-frontends.

It enables you to have different parts of the app running different versions of React with different dependencies, or even other Javascript frameworks inside React. This may sound like a silver bullet, but please be aware that running micro-frontends like this has a number of gotchas.

Packages

yarn add react-micromount

API

MicroMount

MicroMount is a React component. It accepts a URL of a micro-frontend to load, which must be a "mountable" object. The MicroMount component fetches it, and handles mounting and unmounting. In future it will also handle updates via props.

Props

  • url is the URL of a micro-frontend (mountable) to mount
  • fallback is rendered until the mountable is loaded
  • ...additionalProps are passed into the mountable
import MicroMount from 'react-micromount';

<MicroMount
    url={process.env.MOUNTABLE_URL}
    fallback={"Loading..."}
    additionalProp={123}
/>

Mountables

Mountables are the Javascript files that react-micromount can mount. They look like this:

window["reactMicromounts"] = window["reactMicromounts"] || [];
window["reactMicromounts"].push({
    mount: (container, props) => {
        // mount your micro-frontend
        // e.g. if you're using React...

        ReactDOM.render(<MyMicrofrontend {...props} />, container);
    },
    unmount: (container) => {
        // unmount your micro-frontend
        // e.g. if you're using React...

        ReactDOM.unmountComponentAtNode(container);
    }
});
  • container is the DOM element to mount onto.
  • props are the initial props passed to the component.

Gotchas

In short:

  • Be very careful to never make breaking changes to your APIs.
  • Don't use globals or micro-frontends that add things to window.
  • Don't pass any non-serialisable data into a micro-frontend (functions, classes etc.), unless you really know what you're doing.
  • Don't expect code splitting on your micro-frontends to work if the micro-frontend's code is in a different parent URL to the rest of the app.
  • Be aware of CSS rules and how they apply to the HTML produced by a micro-frontend.

Globals

When micro-frontends create object on the window, these may clash when running two micro-frontends at once. They might be doing this without you knowing. For instance did you know webpack creates a global to use with its code splitting / chunk loading?

API surface area

All microservices and non-sandboxed micro-frontends must be extremely careful about never making breaking changes to their APIs. When using microservices you gain the ability to separate out build and deployments for parts of a system, but those parts of the system must remain compatible if they are to work together. Non-sandboxed micro-frontends like the ones react-micromount allows can potentially have a very large surface area.

The app and its mountables must always agree on:

  • The shape of their API used for mounting
  • In this case window["reactMicromounts"] = ... described above
  • The shape of their API for passing data
    • In this case all props that are passed in, and if you're passing functions then all parameters and return values
    • Even the versions of special data structures and classes! In future react-micromount will only accept JSON.stringify-able data types by default as protection against these kinds of problems.
  • The HTML structure and class names that are produced are also part of the API if you're applying CSS from the app onto the micro-frontend!
  • Any globals that they use - but don't do this!

Code splitting and chunk loading

Don't expect code splitting on your micro-frontends to work if the micro-frontend's code is in a different parent URL to the rest of the app. Non-sandboxed micro-frontends can't use code splitting or chunk loading if the chunk loader assumes that it's chunks are in the same location as the script doing the loading. Normally this is a very safe assumption to a chunk loader to make, and executing scripts in a different location than where they were designed to run goes against this assumption.

For example, the problem you may encounter is that a micro-frontend that uses code splitting with webpack will try to load additional chunks from the app's location rather than the location where the micro-service script came from (which is where the chunk really is).

Cachebusting

Keep this in mind. You don't really want your users to have to download the same Javascipt file over and over, but you do want them to download the file if changes have occured. In future react-micromount should be able to hgelp with this.

You can’t perform that action at this time.