Table Of Contents
- Disclaimer
- Configuring the Projects
- Integrating the Micro Frontends into the App Shell/Startup Application
- Automating the Build Scripts
- Installing and Setting Up React.JS
TL;DR
Here is a link to the github repository. Feel free to clone, download or fork and make PRs.
https://github.com/XanderSelorm/MicroFrontendsExample
Disclaimer
Kindly note that this tutorial is for educational purposes only and that this set up or architecture has not been tested in a production environment yet.
In our previous part of this series, we looked setting up the environment and folder structure for the Micro Frontends.
Configuring the Projects
ReactMicroFrontend Project
Since the ReactMicroFrontend
is basically a JavaScript project, NPM will obviously be used as the default package manager.
To initialize NPM in the ReactMicroFrontend
, using the terminal, ensure that you are in the root directory and you have Node.js and NPM installed globally on your computer. If not, download it from here. Then continue by running the following command in the root directory of the project:
npm init
Since this project is for tutorials purposes only, we'll keep the default values when initializing NPM here.
With that done, let's look at how to bundle out JavaScript codes.
Since we're setting up the React Library manually, let's decide on what our bundler will be. For the sake of this tutorial, ‘Parcel’ will be used instead of usual webpack for the bundling of the React application.
Now that we have npm installed and initialized in our project, let's use it to install Parcel. If you want to know more about Parcel
, check it out.
Run the following command in the root directory of the MicroFrontend (React) project in question:
npm install parcel --save-dev
Now that this is done, let's determine where our React code will be bundled to upon build.
- Open the
package.json
file in theReactMicroFrontend
project and modify the following lines:
{
//destination path
"main": "wwwroot/dist/app.js",
//origin path
"source": [
"src/index.jsx"
],
//scripts
"scripts": {
"build": "parcel build src/index.js",
"clean": "del-cli wwwroot/dist/* node_modules",
},
}
When you take a critical look at our clean
script, you'd realize the use of a package called del-cli
. This package is used for permanently deleting files and directories. This packages needs to be installed globally before it can be used.
Run the following command in your terminal to install it:
npm install --global del-cli
MicroFrontendExample.Shell Project
Awesome! With that done, save the file and let's look at how to make sure our JavaScript code from our MicroFrontend is also bundled into the App Shell/Container App.
To do this, we'll have to go back into the directory of our App Shell/Container App and then run a few commands.
In the startup application, ‘Webpack’ will be used to bundle all the JavaScript frameworks together into the main application/App Shell. And since we'll be using NPM here too, we'll initialize NPM in this directory too and then install the Webpack. Use the following commands by running them in the root directory of the startup project/App Shell:
Don't forget to keep the default values for NPM. (Well, you can still go ahead and customize it if you wish)
npm init && npm install webpack --save-dev && npm i -D source-map-loader && npm install --save-dev webpack-cli
If the above commands fail, run them one after the other, like so:
npm init
npm install webpack --save-dev
npm install --save-dev webpack-cli
...and then
npm i -D source-map-loader
Integrating the Micro Frontends into the App Shell/Startup Application
- In the Startup Project’s ‘App.razor’ file, we'll load the entry-files of the class libraries (micro frontends) as assemblies.
Do this by adding the following lines of code to the App.razor
file:
@using System.Reflection
<!-- Default File Content -->
@code {
private List<Assembly> LoadedAssemblies = new List<Assembly>()
{
typeof(ReactMicroFrontend.App).Assembly
};
}
- In the same file, on the
<Router>
tag, add theAdditionalAssemblies
attribute and assign theLoadedAssemblies
value to it.
<!-- AdditionalAssemblies="@LoadedAssemblies" -->
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="@LoadedAssemblies" PreferExactMatches="@true">
- In the Startup Project’s
_Import.razor
file, add the namespaces of the various micro frontend applications in order to make them available throughout the startup project:
@using ReactMicroFrontend
Awesome! A couple of things more to do...
- Let's begin by modifying the
package.json
file over here too. we'll add thebuild
andclean
scripts to thescripts
object.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"clean": "del-cli wwwroot/dist/* node_modules"
},
Now, let's add the configurations for webpack
. We'll do this by adding a new file and name it as webpack.config.js
.
Right click on the project > Add > New item > Javascript File.
Change the name to
webpack.config.js
, and click Add.
In the webpack.config.js
file, add the following block of code, customize it if the need be, and save it.
const path = require('path');
const fs = require("fs");
module.exports = [
{
name: "get-react",
entry: () => fs.readdirSync("../ReactMicroFrontend/wwwroot/dist/").filter(f => f.endsWith(".js")).map(f => `../ReactMicroFrontend/wwwroot/dist/${f}`),
devtool: "source-map",
mode: "development",
output: {
filename: "app.js",
path: path.resolve(__dirname, "./wwwroot/dist/react/")
},
module: {
rules: [
{
test: /\.js$/,
enforce: "pre",
use: ["source-map-loader"]
}
]
}
}
]
- Finally, let's make sure that our React script is added to our
index.html
file. If not, before the closingbody
tag in theindex.html
file, add:
<script src="dist/react/app.js"></script>
Automating the Build Scripts
If you've read up to this point, congratulations! This is the last step and then we'll take out app for a test ride 😀!
By now, I'm sure you are wondering whether we'll be calling the build scripts manually for each project? The answer? Hell no! 😀 We'll automate that too. So that when the build command is called for the dotnet projects, that of our JavaScript microfrontends are called too.
Let's look at how to implement that:
- We'll edit the project files of both the
MicroFrontendExample.Shell
and any of our microfrontend which uses JavaScript code; this includes outReactMicroFrontend
.
If you're using VS Code, it's easy to locate the project files.
But when you're using Visual Studio, right click on the project > Edit Project File.
- Before the
</Project>
closing tag, add the following block of code:
<Target Name="npm restore" BeforeTargets="BeforeBuild">
<Exec Command="npm install" />
</Target>
<Target Name="webpack" AfterTargets="Build">
<Exec Command="npm run build" />
</Target>
<Target Name="webpack clean" AfterTargets="Clean" Condition="Exists('node_modules')">
<Exec Command="npm run clean" />
</Target>
Awesome! Congratulations for making it up to this point! Now we're free to build our application. :D
Ooopss!! There are Errors!?? Chill bro, 😀, this error was expected. 😊
This error occurred because we directed the Parcel
bundler to an index.js
file which doesn't exist. This is because we haven't installed and set up our React.JS yet.
This brings us to our next and final topic:
Installing and Setting Up React.JS
This final step should be fairly easy to do. We'll run a couple of commands, run a few lines of code and then we call it one hell of a guide! 😀
- To begin, let's install react and react-dom. Run the following command in your terminal:
npm install --save react react-dom
Secondly, let's create a new file, name it
index.js
in thesrc
folder.Add the following code block to the new file you created:
import React from "react";
import ReactDOM from "react-dom";
window.renderApp= () => {
const domElement =
document.getElementById("react-app") ||
document.querySelector("#react-app");
if (domElement) {
ReactDOM.render(<h1>Hello, React🌐!</h1>, domElement);
}
};
- Finally, feel free to run the application, navigate to "/ReactMicroFrontend", and experience the power of Blazor!
Your final app should look like this:
Here is a link to the github repository. Feel free to clone, download or fork and make PRs.
https://github.com/XanderSelorm/MicroFrontendsExample
Thank you very much for reading. Follow me for more interesting guides and content. And oh, don't forget to leave a reaction 😉. I'll be grateful 😊
See you later, cheers!
Top comments (7)
Nice article but, and correct me if I'm wrong or missed a point, one of the key concept of micro front-ends is the ability to build each µFront-end independently from another, and, especially, from the shell/container app. Otherwise, it's not really a µFrontend but rather a "modular" app.
I'm sorry for the late reply :).
Well, I wouldn't say you're wrong per your assessment. Personally, I agree with the notion that when a "modular" app has its frontend modules built with different technologies and maintained by different teams, such frontend modules may also be called as Micro-Frontends.
Have a read from the originators of the concept here: thoughtworks.com/radar/techniques/...
Hi. Can you Describe how handle state management in this type projects .
You can take a look at Fluxor. And you'll also need JS InterOp
Hey!
Currently I'm collecting some ideas and experiments for an architecture that I'm defining for a project in my company and I found this article really interesting but I have one big doubt.
Is there any way to do this with different solutions?
For example:
Having an app shell that will call 3/4 microservices that already have their frontend in Blazor? Is this a viable way to do it?
Great thank you
Is there any way to add js packages to this? Tried giving it a go but it doesn't seem to like them.