Building A Shell Application for Micro Frontends | Part 4

In this post, we will create the last piece of our micro frontends with the design system PoC.

In this post, we will create the last piece of our micro frontends with the design system PoC. We now have a design system, several micro frontends consuming this design system, and we need now a shell application that will import micro frontends and display them.

Shell Application Overview

This shell application will import micro frontends using script tags and script URLs hardcoded in index.html in the real project, it would be driven by some sort of configuration.

Aspects Not Covered

This series will not cover two aspects: module federation and mounting microseconds to isolated virtual DOM.

Understanding Module Federation

Module federation helps to lower the size of included script by requesting modules, used by more than one micro frontend, only once. If we want to increase isolation between micro frontend we can create a web component that will mount micro frontend to isolated virtual dom.

 

Setting Up the Shell Application

Create directory fitness-portal-shell in the same directory as design-system and micro frontends.

Running Setup Commands

Run the following commands, from the new directory to setup project dependencies:

Now we need a few files.

Create file ./src/App.js with the following content:

import React from "react";
import    from "react-hot-loader/root";
import MicroFrontend from "./MicroFrontend";

class App extends React.Component {
  render() {
    return [
        "nutritionPortal",
        // Uncomment following lines if you created additional micro frontends
        // "exercisePortal",
        // "mealsPlannerPortal",
        // "recipesPortal"
    ].map((name) => (
      
    ));
  }
}

export default hot(App);

Create file ./src/MicroFrontend.js with the following content:

import React,    from 'react'

export default class MicroFrontend extends Component {

    get containerId() {
        return `mf-$
    

    render() {
        return 

Create file ./src/index.js with the following content:

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

var mountNode = document.getElementById("app");
ReactDOM.render(, mountNode);

Create file ./src/index.html with the following content:





    
    
    
    
    
    


    

    



    

This is a naive implementation where we hard-code links to micro frontends' resources in a real project it would come from the configuration.

No we will configure build.

Create file ./.bablrc with the following content:

{
    presets: [
      [
        '@babel/preset-env',
        {
          modules: false
        }
      ],
      '@babel/preset-react'
    ],
    plugins: [
      'react-hot-loader/babel'
    ]
  }

Create file ./webpack.config.js with the following content:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const config = {
  entry: ["react-hot-loader/patch", "./src/index.js"],
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: "babel-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
            },
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: [".js"],
    alias: {
      "react-dom": "@hot-loader/react-dom",
    },
  },
  devServer: {
    contentBase: "./src",
    watchContentBase: true,
    port: 7000,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS"
    },
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    new MiniCssExtractPlugin(),
  ],
  optimization: {
    runtimeChunk: "single",
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },
};

module.exports = (env, argv) => {
  if (argv.hot) {
    // Cannot use 'contenthash' when hot reloading is enabled.
    config.output.filename = "[name].js";
  }

  return config;
};


Open ./package.json and add following script to scripts section:

"start": "cross-env NODE_ENV=development webpack serve --hot --mode development"

You should be able to build the shell app now. Run npm start. It should bind to port 7000. Remember to build and run micro frontends first.

Blog 7/15/21

Building a micro frontend consuming a design system | Part 3

In this blopgpost, you will learn how to create a react application that consumes a design system.

Blog 7/13/21

Composite UI with Design System and Micro Frontends

Discover how to create scalable composite UIs using design systems and micro-frontends. Enhance consistency and agility in your development process.

Blog 7/14/21

Building and Publishing Design Systems | Part 2

Learn how to build and publish design systems effectively. Discover best practices for creating reusable components and enhancing UI consistency.

Blog 10/1/22

Introduction to Functional Programming in F# – Part 4

Unlock F# collections and pipelines. Manage data efficiently and streamline your functional programming workflow with these powerful tools.

Blog 10/21/20

Consistency and Aggregates in Event Sourcing

Learn how we ensures data consistency in event sourcing with effective use of aggregates, enhancing system reliability and performance.

Blog 9/27/22

Creating solutions and projects in VS code

In this post we are going to create a new Solution containing an F# console project and a test project using the dotnet CLI in Visual Studio Code.

Blog 3/10/21

Introduction to Web Programming in F# with Giraffe – Part 1

In this series we are investigating web programming with Giraffe and the Giraffe View Engine plus a few other useful F# libraries.

Blog 3/11/21

Introduction to Web Programming in F# with Giraffe – Part 2

In this series we are investigating web programming with Giraffe and the Giraffe View Engine plus a few other useful F# libraries.

Blog 3/12/21

Introduction to Web Programming in F# with Giraffe – Part 3

In this series we are investigating web programming with Giraffe and the Giraffe View Engine plus a few other useful F# libraries.

Blog 8/7/20

Understanding F# Type Aliases

In this post, we discuss the difference between F# types and aliases that from a glance may appear to be the same thing.

Blog 11/14/23

Part 2: Data Analysis with powerful Python

Analyzing and visualizing data from a SQLite database in Python can be a powerful way to gain insights and present your findings. In Part 2 of this blog series, we will walk you through the steps to retrieve data from a SQLite database file named gold.db and display it in the form of a chart using Python. We'll use some essential tools and libraries for this task.

Blog 10/6/21

Designing and Running a Workshop series: An outline

Learn how to design and execute impactful workshops. Discover tips, strategies, and a step-by-step outline for a successful workshop series.

Blog 11/3/22

Inbox helps to clear the mind

I hate distractions. They can easily ruin my day when I'm in the middle of working on a cool project. They do that by overloading my mind, buzzing around inside me, and just making me tired. Even though we can think about several things at once, we can only do one thing at a time.

Blog 6/16/23

CSS :has() & Responsive Design

In my journey to tackle a responsive layout problem, I stumbled upon the remarkable benefits of the :has() pseudo-class. Initially, I attempted various other methods to resolve the issue, but ultimately, embracing the power of :has() proved to be the optimal solution. This blog explores my experience and highlights the advantages of utilizing the :has() pseudo-class in achieving flexible layouts.

Blog 7/25/23

Revolutionizing the Logistics Industry

As the logistics industry becomes increasingly complex, businesses need innovative solutions to manage the challenges of supply chain management, trucking, and delivery. With competitors investing in cutting-edge research and development, it is vital for companies to stay ahead of the curve and embrace the latest technologies to remain competitive. That is why we introduce the TIMETOACT Logistics Simulator Framework, a revolutionary tool for creating a digital twin of your logistics operation.

Blog 11/27/23

Part 4: Save Time and Analyze the Database File

ChatGPT-4 enables you to analyze database contents with just two simple steps (copy and paste), facilitating well-informed decision-making.

Blog 6/24/21

Using a Skill/Will matrix for personal career development

Discover how a Skill/Will Matrix helps employees identify strengths and areas for growth, boosting personal and professional development.

Blog 11/30/22

Part 2: Detecting Truck Parking Lots on Satellite Images

In the previous blog post, we created an already pretty powerful image segmentation model in order to detect the shape of truck parking lots on satellite images. However, we will now try to run the code on new hardware and get even better as well as more robust results.

Blog 11/15/22

5 lessons from running a (remote) design systems book club

Last year I gifted a design systems book I had been reading to a friend and she suggested starting a mini book club so that she’d have some accountability to finish reading the book. I took her up on the offer and so in late spring, our design systems book club was born. But how can you make the meetings fun and engaging even though you're physically separated? Here are a couple of things I learned from running my very first remote book club with my friend!

Blog 11/24/23

Part 3: How to Analyze a Database File with GPT-3.5

In this blog, we'll explore the proper usage of data analysis with ChatGPT and how you can analyze and visualize data from a SQLite database to help you make the most of your data.