Micro FrontEnd Kit
Introduction
The micro-frontend-kit is a utility for creating a singular mock micro-frontend application that is used to enforce, develop and test a standard micro-frontend contract interface.
The secondary purpose of the micro-frontend-kit is for the production of new microapps. On the basis of the standard contract used in the mock MFE, new micro-frontend applications can be created by copying the mock MFE, along with its contract and using it in any use case you wish.
The goal of this repository is for the following scenarios:
-
The mock micro-frontend is used, internally by the organization, for use in a real-life consumer application such as Unicorn, to test and diagnose issues with 3rd party microapps imported from different teams across the organization, and to determine the source of the issue based on the agreed contract.
-
The mock microapp bundle is deployed and or published to a place where it is accessible by a consumer app.
-
Creates a local dev environment developing the Harness, the micro-frontend and the contract super easy, increasing the dev experience significantly such that you can rapidly develop a solution.
-
The mock application can be used as a basis for developing new micro-frontend bundles for any use case that requires it. You can simply copy the mock src code and copy it alongside, using webpack to point to the new app source code.
Features
The Harness dev environment: micro-frontend-kit incorporates a Harness application localhost:3030
that emulates the conditions of a real-life consumer app, that consumes a micro frontend application via a micro-frontend loader based on single-spa
and systemjs
. It loads the mock bundle as a single spa parcel
. it uses a webpack-dev-server
to spin up an instance of the Harness and uses the Harness entry point source file to bundle in memory, for quick updates.
Serving the mock MFE: The micro-frontend-kit also incorporates a reference micro-frontend app, that also uses its own webpack dev server that serves the manifest and bundle to the Harness, it also can be used by the real-life application (Unicorn developed locally) for integration purposes, by pointing to the mock MFE manifest localhost:3031/manifest.json
, any changes in MFE will be reflected in Unicorn upon refresh of the browser.
Dev Experience: Both servers are spun up with a single command, and all files from the Harness and MFE app are watched for changes and updates the browser with the new changes
Micro Frontend Contract: The micro-frontend-kit includes a publishable @types/micro-frontend-contract module, which can be used by any MFE (via NPM package manager installation) that uses typescript. The contract is composed of two files index.d.ts
and next.d.ts
, which are automatically imported much like the Definitely Typed project, see notes typescriptlang
NOTE : When forking this repo to setup a new micro-frontend please add @types/micro-frontend-contract as a dev dependency and delete the @types folder in the root of the project.
Technologies
- Javascript App
- Javascript Test and Build
- Build, deployment, and publishing
- Best practices contribution tools
Initial Project Setup
This project uses Node 16. Please ensure that this is the version in use before attempting the steps below.
The project will need to have its dependencies installed. You will need to configure your NPM registry, as explained on this guide.
You can use npm
to run this project, but we recommend yarn
going forward.
yarn
Development Setup
No need to build anything for development, it uses webpack-dev-server
to build harness the MFE bundles into memory and watches any source code changes simply run the following to get up and running.
when developing both the harness and the micro-frontend mock.
yarn start
To view the harness and the mock micro-frontend:
localhost:3030
dev-server also hosts the micro-frontend manifest and bundles at the following URL:
localhost:3031/manifest.json
Creating a new micro frontend
You can use the reference mock MFE and copy it under the src
folder under its own folder name, for example:
import React from 'react';
import ReactDOM from 'react-dom';
import singleSpaReact from 'single-spa-react';
const App = () => (
<div id="mfe-root">
hello from mfe copy
</div>
);
const reactLifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary: () => <div>This renders when a catastrophic error occurs</div>
});
const singleSpa = {
bootstrap: [
(props: any) =>
reactLifecycles.bootstrap({
...props,
basename: 'my-new-mfe'
})
],
mount: [
(props: any) => {
props.dispatchEvent({ type: 'LOAD_COMPLETE' });
return reactLifecycles.mount({
...props,
basename: 'my-new-mfe'
});
}
],
unmount: [
(props: any) =>
reactLifecycles.unmount({
...props,
basename: 'my-new-mfe'
})
],
update: [
(props: any) =>
reactLifecycles.update({
...props,
basename: 'my-new-mfe'
})
]
};
export default singleSpa;
Point the webpack configuration within /config/webpack/mfe-common.js
by changing the path of the entry property to the new micro-frontend source code.
module.exports = {
entry: { bundle: './src/my-new-mfe/index.tsx' },
...
...
}
NOTE after any change to webpack config, always start/restart your command yarn start
for the above changes to take effect.
if you wish to run the minified profuction build of you new MFE, then you can do:
yarn build:prod
Unit Testing
When creating new tests, the file should be co-located with the ts/tsx file you are testing against, also the file naming convention should be in the following pattern with the asterisk indicating your specific filename.
*.test.ts
Running your tests once
yarn test
Running your test in watch mode
yarn test --watchAll
Production builds
The production build process command is as follows:
yarn build:prod
The command is intended to be used only by the CI pipelines, where it will prepare a build for a mock MFE bundle, ready for it to be deployed/published to the location where it can be reached by consumer apps.
Currently, at the time of writing, the built bundles are published to the content repo's are used and is accessible via Unicorn NGINX /api/content/microapp/mock-mfe/...
Note: The location may change in the future to be more centralized for example AWS S3 or hosted via a CDN
Production builds are as follows

- PR check: Once you checkout out a feature branch from master and have developed and pushed it to the branch in question, a PR check GoCD pipeline is triggered, which runs the tests and lintify. PR's are blocked by any failure of the checks and require at least one reviewer before being enabled to be merged to master.
- Install, Build and Publish: Once merged to master, will trigger the install build and publish of the mock MFE. The install and build parts will prepare the manifest and bundle in for the next stage. Upon sucesfull completion of Install and Build, the publish portion trigger a publish task and push the latest @types/micro-frontend-contract to a chosen registry for example, artifactory.
- Publish:
- Once Install and Build has completed successfully, the Publish stage is triggered to publish/deploy the newly build manifest and bundle to a place where it is accessible. At the time of writing, this is in our sites content repositories
microapp/mock-mfe
applicable to sites that load a MFE. The stage performs a shallow clone of the content repository (in preview branch) to keep the download time and size to a minimum as its is huge, the manifest and bundle are copied to the content repository under the path previously mentioned, and finally a commit and push to preview is performed. - The next phase is almost the repeat process of the above, except a branch based from
master
is shallow cloned, and a new branch is created and reused mfe-publish-mock
. Since master is effectively a live release, you need to manually create a PR from the newly created branch against master, and seek approval from devs, content editors, or release process management.
Integration Testing
To ensure that the mock micro-frontend contract and unicorn integration is up to date, we have introduced a series of MFE contract tests via the unicorn-medium-tests. When developing or making changes to the MFE standard contract, you must ensure that both Unicorn, Harness, the micro-frontend contracts are developed in unison with each other, that is introduce the props and actions necessary to ensure that API communications are tested locally and that you introduce the new prop/actions for the unicorn-medium-tests.
Contract Testing Page
A contract test page is devised (/example/contract-test
, depending on the basename used, harness uses example
or sports
on unicorn sports site) comprising of table fields of prop key and values, and an actions dropdown to select and trigger an appropriate dispatch event to the consumer app. The page exists so that the unicorn-medium-test can read the page by traversing the document structure and targeting the field and its value, and that the consumer app had passed correct values on invocation of the consumer app (Unicorn in this case).
How this all gets connected
In the past, the development experience was such that on every change made in the micro frontends that are tested in the medium tests, would need to copy the bundle over manually to the medium test fixtures folder and then run the medium tests to check if it worked, this created slow feedback for failures, and laborious, and error-prone experience. to alleviate the developer's pain, a bash copy command is incorporated in MFE-Kit to make copying the bundle easier.
This Bash command will only be accessible if it is a globally installed npm module but since the main MFE-Kit is not published (at the time of writing) we would need to use npm link to bind MFE-Kit and Unicorn medium tests so that in the unicorn-medium-tests path, we can just run the MFE-Kit copy command, which will auto-resolve the paths and copy the contents of micro-frontend-kit/dist
to unicorn/tree/dev/packages/unicorn-medium-tests/config/fixtures
. The linking is done in sequence, that is first MFE-Kit npm link
, and then Unicorn-medium-tests npm link micro-frontend-kit
, please see Preparing MFE-Kit at point 3 and Preparing Unicorn point 3.
The basic idea is that when developing against the MFE-Kit via the harness in dev mode, and at the same time, the production build is built on --watch
any changes you do and is confirmed via the harness, will be in the bundle, at this point, the copy command will transfer the bundle to the unicorn-medium-tests fixtures folder.
Example
Developing the tests
A number of steps need to be performed to get everything set up to develop the Unicorn integration, harness, micro-frontend mock, and integration in the unicorn medium tests.
Preparing MFE-Kit
In this section, we will be setting up the micro-frontend-kit ready to be used as a linked module dependency in the unicorn-medium-tests repo.
- Checkout a new branch for MFE-Kit and perform
yarn
- Open three dedicated command line terminals for MFE-kit, Important ensure your running node 16 on these terminals.
- On
MFE-Kit Terminal-1
to start MFE-Kit development mode yarn start
- On
MFE-Kit Terminal-2
to build the production bundle for use in medium test mock yarn build:prod --watch
, this ensures that all changes are built automatically and ready to be copied over to the unicorn-medium-tests fixtures. - On
MFE-Kit Terminal-3
to perform repo linking operations see below for further steps
- On
MFE-Kit Terminal-3
, we will use this to start the linking process, in order to connect this local version of MFE-kit to the Unicorn repo.
- Ensure you are on a version of node 16 and above (using nvm to switch versions)
- To link MFE-Kit to the global node module space, perform the following
npm link
- To check the above was successful
npm list -g --depth=0
you should see micro-frontend-kit@x.x.x
in the list
Preparing Unicorn
- Checkout a new branch for Unicorn and perform
yarn && yarn build
- Open three dedicated command line terminals for Unicorn Important ensure you are running node 14 on all except the
unicorn-medium-test Terminal-2
where it should be the matching node version you set for MFE-Kit.
- The
unicorn Terminal-1
(unicorn root folder) will be used to start the medium test server yarn stop && yarn medium ballybetaz
for example see https://github.gamesys.co.uk/pages/client-delivery-platform/unicorn/#/local-development/testing?id=running-medium-tests - The
unicorn Terminal-2
(unicorn root folder) will be used to start the unicorn-medium-tests test runs for example yarn start:medium ballybetaz mobile
- The On
unicorn-medium-test Terminal-3
will be used to perform the linking of the MFE-Kit from the global node modules to the unicorn-medium-tests and the copy mfe bundle command, this command line needs to be at the root of the unicorn-medium-tests project cd ./packages/unicorn-medium-tests
-
NOTE: unicorn-medium-test Terminal-3
should be on node 16 matching exactly the version of node on MFE-Kit Terminal-3
on MFE-kit where you performed the initial linking.
- On the
unicorn-medium-test Terminal-3
(for linking and copying mfe) perform the npm link to the already globalized (from step three in Preparing MFE-kit) micro-frontend-kit by performing npm link micro-frontend-kit
. - At this stage, unicorn-medium-tests should be linked to your MFE-kit local repo, in the
unicorn-medium-test Terminal-3
, you can now perform the yarn copy:mfe
command, this should copy the bundle and manifest from the micro-frontend-kit/dist. From now on, you will use unicorn-medium-test Terminal-3
to perform copy commands on any changes you do in the MFE-kit.
-
Any issues encountered, please see the checklist below
- make sure you set the exact version of node 16 (using nvm) on the terminals used for linking on MFE-Kit and Unicorn side.
- be aware, any yarn install you do on both repos will reset the linking so make sure you set up both repos for installation before the linking is done.
Making the test suite changes
At this stage, you are ready to develop the contract test page and make changes to the fields and values to be tested.
- Start running the Unicorn medium tests server in the
unicorn Terminal-1
(outlined in Preparing Unicorn point 2, first bullet). - Make the necessary MFE-Kit changes relating to the elements you wish to test against, and confirm them on the harness
http://localhost:3030/sports/contract-test
. - On every change of the MFE, run the copy command as outlined in (Preparing Unicorn point 4)
- Amend your medium test accordingly and run the medium test to confirm, for example, see https://github.gamesys.co.uk/pages/client-delivery-platform/unicorn/#/local-development/testing?id=running-medium-tests
- Repeat 2 to 4 until your tests are passing.
- Once everything is passed, you can commit the test changes with the newly built manifest and bundle.
Contributing
micro-frontendkit uses Architectural Decision Records (ADR's) in the attempt to try and capture conversations and the resulting decisions around our design choices. It is encouraged that any key design decisions and further development of the project is recorded in an ADR. To make this a little simpler, micro-frontend-kit incorporates a utility for creating ADR templates, using the following commands.
To create a new ADR template:
yarn adr new <name of decision>
To list all ADR's
yarn adr list
╔══════════╤════════════════════╤═════════════════════╗
║ Decision │ Last Modified Date │ Last Status ║
╟──────────┼────────────────────┼─────────────────────╢
║ 1.test │ 2022-03-29 │ 2022-03-29 proposed ║
╟──────────┼────────────────────┼─────────────────────╢
║ 2.test │ 2022-03-29 │ 2022-03-29 proposed ║
╟──────────┼────────────────────┼─────────────────────╢
║ 3.test1 │ 2022-03-29 │ 2022-03-29 proposed ║
╚══════════╧════════════════════╧═════════════════════╝
To search for a bunch of adrs
yarn adr search test1
╔══════════╤═════════════════════╗
║ Decision │ Last Status ║
╟──────────┼─────────────────────╢
║ 3.test1 │ 2022-03-29 proposed ║
╚══════════╧═════════════════════╝
And finally
As your contributions to this repository, please observe some house rules and be sure to read the contributing guidelines in the following link.
Contributing guildlines