@compassdigital/project-mh v0.6.0
Project MH
Microfrontends Micro Frontends Micro front ends Micro-frontends Micro Front-ends Microfront-ends Micro-front ends
A single-spa + module federation workflow.
Usage
pmh launch <path to pmh.config.json> --apiName=NAME
Launches a local instance of the given Routing Table API in the configuration.
The contents of the config will determine how your micro-application is injected into the local instance.
You can override the Routing Table API's SPAs with a local version of your own. This is for local development.
pmh compile <path to pmh.config.json> [--apiUrl=URL] [--outputDir=DIR]
Compiles your application.
If your application is type core
then --apiURL
is required.
pmh.config.json
for micro-apps looks like:
{
"type": "spa",
"spaName": "C360Home",
"route": "/home",
"localEnv": {
"publicPath": "./dist",
"port": 8501
},
"api": {
"dev": "ROUTING TABLE API",
"staging": "ROUTING TABLE API",
"prod": "ROUTING TABLE API"
}
}
A couple important things to know:
spaName
is a uniqueID in the Routing Table API
api
is a mapping of APIs as convenience for pmh launch
localEnv
is used for spinning up a local SPA.
pmh.config.json
for core app looks like:
{
"type": "spa",
"name" "Cafe360",
}
...that's about it. This is left here for expansion when needed.
name
can propagate into the web application's title.
Roadmap and Open Questions
Current things I am trying to figure out:
Module Sharing
We can share modules and dependencies via Module Federation
What would be the best way to do that and keep everyone (or those who choose to) in sync?
How do BE devs do it???
I think a Federation is just two or more applications agreeing on what to share.
This is probably where Federation is defined
HTML SPA Templating
There may be a possibility that the html template for core needs to be specialized.
We can assume right now that there is no specialized ejs file.
In this way, Cafe360 is just the URL Mapping Table and the EJS is owned by Project MH.
In the case that EJS files must be specialized, then we have to figure out if we can decentralize the EJS file in some way.
- EJS template is part of the Mapping Table
-> would have to reconstruct layout on each route change which might suck, worst case.
-> A possible workaround to the above is to check for layout equality before reconstructing the layout. How many different layouts can a user possibly experience in n route changes?
-> This is a really deep problem and might cost alot going down this path. It probably isn't even worth it.
-> We only really need it for top-level elements which we can hide via CSS anyways.
Questions you want to ask yourself before considering the above:
1) Can we just manipulate single-spa's SPA div containers via CSS isntead? Absolute positioning seems fine. Can this be defined by SPA's? This would be the best solution, I think.
If we cannot decentralize then EJS is no longer a Project MH concern, rather it is a Cafe360 concern. Then it simply is code that lives within the Cafe360 repo which override's Project MH's.
Hot-loading
Considering that we are able to just replace a module with anything (it's in the window context, after all) we can just hot-load a newer version of the SPA over the eexisting older one during runtime.
The current problem is just trying to figure out WHEN we do that.
This is a big ticket item. I want Project MH applications to live forever in the browser that can self-update on the fly.
Architecture
Overview
Project MH is a workflow for implementing microfront-end architectures.
Project MH architectures consist of three components:
1) A Routing Table API
2) A Core App
3) Micro-apps
Routing Table APIs
Currently it doesn't matter what the Routing Table API is.
Contractually it just needs to return a list of [<spaName, route, url>]
This is left to purely a specification for Project MH architectures.
I don't think Project MH is responsible for that stuff!
This is where innovation and business ideas go.
A couple questions you should ask yourself:
1) How will you consolidate routes?
2) Security implications
etc.
There is an idea that Project MH will provide some features around the 'imaginary' API. Things like:
better local development tooling
dashboards
Core App
The core is found in resources/core
.
This is the Project MH engine.
Under the hood, it:
1) Pulls the list of micro-app entries for the given Routing Table URL
2) Registers the application and listens to its route.
3) When the client hits the route, the core-app will download the application, hotload it into the global context, and mount itself.
In this way, we achieve an enterprise application composing of multiple, independently deployed applications.
How robust!
Micro-apps
Currently we only support vue3 applications.
These micro apps need to be in single-spa form.
Transforming your application into a single-spa application is very easy.
On a high level, you simply need to map your framework's lifecycles to single-spa's.
This is because single-spa needs to know how your framework mounts, dismounts, and loads.
But this has been done many times already and there is a large eco system in support of application conversions.
https://single-spa.js.org/docs/ecosystem
Most major frameworks already have utility functions for this.
Motivations
I honestly can't really think of a reason of why would you want to use this style of architecture beyond the specific use-case I am writing this flow for.
This was made for the grandest of ideas and the loosest of requirements.
If you need:
To have a lot of developers working under the same web application
You would like to not have them step in each others toes.
You can split your enterprise application into pieces that actually make sense.