The following software is required to run the sample:
- Git
- Node.js
- NPM
- Bash
Clone the repository:
git clone https://github.com/ArtOfMicrofrontends/10-spa-composition.git
Go to the repository's directory and start the application, which also installs all required package dependencies:
./run.sh
Follow these steps to implement the same from scratch.
- Start with the app shell, initialize a new Node.js project and install the dependencies
npm init -y
npm install bootstrap bootstrap-icons regenerator-runtime --save
npm install parcel-bundler --save-dev
-
Create an index.html file with the skeleton design of the application with a placeholder for the content (e.g.,
#app-content
) -
Add the script (app.js) and stylesheet (style.css) reference
-
In the script load all configured MF scripts coming from the scripts.json:
[
"/mfes/balance/balance.js",
"/mfes/tax/tax.js",
"/mfes/settings/settings.js"
]
with the loading logic being as simple as
import("./scripts.json").then((scripts) =>
scripts.forEach((url) => {
const script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
})
);
-
Hook on to the
hashchange
andpopstate
listeners to introduce routing -
Introduce lifecycle functions for
bootrap
,mount
, andunmount
of components - hooked up in therenderComponent
function:
window.renderComponent = (name, componentName, target, props = {}) => {
const id = makeId(name, componentName);
const info = registry[id];
if (info !== undefined) {
const user = {
target,
props,
data: undefined,
state: "init",
};
info.used.push(user);
info.wait = bootstrapComponent(info, user);
info.wait = mountComponent(info, user);
}
};
- Create the MFs, e.g., for the
tax
MF you'll need to initialize and set up the project
npm init -y
npm install file-loader svelte svelte-loader webpack webpack-cli --save-dev
where you'll need to add a proper Webpack configuration for the framework of your choice
- The index.js of each MF will have boilerplate code to register the lifecycle of the exposed components; for instance:
window.registerComponent("<namespace-name>", "<component-name>", {
bootstrap: () => {
// load component
},
mount: (target, props) => {
// mount component
},
unmount: (target, info) => {
// unmount component
},
});