Building A Micro Frontend Consuming A Design System | Part 3

Learn how to create a react application that consumes the design system.

This blogpost is a part of the "Building Design System and Micro Frontends" series. For more content, read the first post and the second post. The source code for all parts of this series can be found in this GitHub repository.

For building our design system, we will use react, tailwind, storybook and webpack.

The blogposts of this series
1. Building design system and micro frontends
2. Building and publishing a design system
3. Building micro frontends consuming a design system (you are here)
4. Building a shell application for micro frontends

In this part, we will create a react application that consumes the design system. The app will have the capability to display itself as a standalone app or as a micro frontend in shell application.

Developing a React App with Mounting Capabilities

The idea here is to create a react app that does not automatically mount to DOM but rather assigns two functions mount and unmount to a property on the window object. The page that wants to display this app will call mount function and give it a host DOMElment plus some configuration. In our case, the configuration will be one property isStandAlone that will indicate if the app should display its own shell or as embedded micro fronted. We will also create an `index.html` file which will be deployed along with the application. If someone tries to access our app directly, the server will serve index.html. HTML will contain a small script that will set up our app in stand-alone mode.

Creating the Nutrition Portal Directory

Create directory nutrition-portal in the same folder as design-systme (next to each other).

Setting Up Project Dependencies

Run following commands from nutrition-portal directory to setup project dependencies:

npm init -y
npm i -P react@17.0.2 react-dom@17.0.2 react-hot-loader@4.13.0
npm i -D webpack@5.38.1 webpack-cli@4.7.0 webpack-dev-server@3.11.2  html-webpack-plugin@5.3.1 cross-env@7.0.3 babel-loader@8.2.2 @hot-loader/react-dom@17.0.1+4.13.0  @babel/preset-react@7.13.13 @babel/preset-env@7.14.4 @babel/core@7.14.3 mini-css-extract-plugin@1.6.0 css-loader@5.2.6

Now we need a few files.

Create file ./.bablrc with the following content:

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

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

import React from "react";
import    from "react-hot-loader/root";
import    from "../../design-system/dist/main";
import "../../design-system/dist/main.css";

class App extends React.Component {
  render() {
    return (
      
); } } export default hot(App);

Make sure paths in lines 3 and 4 are reflecting where you placed your design system.

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

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

function mount(mountNode, args) {
  ReactDOM.render(, mountNode);
}

function unmount(mountNode) {
  let res = ReactDOM.unmountComponentAtNode(mountNode);
}

window.nutritionPortalMount = mount;
window.nutritionPortalUnmount = unmount;

./src/index.js will be our entry point. The important part here is that it is not rendering our react app but rather defines two functions for mounting and unmounting our app. At the end mount and unmount functions are assigned to a property on window object.

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





    
    



    

After deployment, if anyone hits the correct domain he will see this micro frontend rendered in standalone mode. A little script at the end of body will mount application to the div. We also pass arguments to the app making clear it should render with its own shell.

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: 7001
  },
  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;
};

This is a standard webpack setup for an react app.

Finally add following script to ./package.json file (scripts object):

    "start": "cross-env NODE_ENV=development webpack serve --hot --mode development",
    "build-prod": "cross-env NODE_ENV=production webpack --mode production"

You can run the application in stand-mode by running npm start; it should bind to port 7001. Open http://localhost:7001. You should see something like this:

For the other micro frontends you can repeat the setup or simply copy this application and change the following things in the copy:

  • The application package name in package.json (property name at the top of the file). This is important for webpack. You won't be able to load two micro frontends with the same package name in one shell application.

  • Port number in webpack.config.js (the setting is in devServer section, line 45)

  • The name of mount and unmount functions in ./src/index.js (lines 13,14)

  • The name of mount function in ./src/index.html (line 13)

  • Micro frontend name in the App.js (label of the button, line 11).

In the repository with the code for this series I created additional copies: exercise-portal, meals-planner-portal, and recipes-portal.

 

What´s next?

In the next post, we will integrate micro frontends inside the shell application. It will be the last post in this series.

 

Blog 7/16/21

Building A Shell Application for Micro Frontends | Part 4

We already have a design system, several micro frontends consuming this design system, and now we need a shell application that imports micro frontends and displays them.

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 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 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 7/21/20

Understanding F# applicatives and custom operators

In this post, Jonathan Channon, a newcomer to F#, discusses how he learnt about a slightly more advanced functional concept — Applicatives.

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/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 3/17/22

Using NLP libraries for post-processing

Learn how to analyse sticky notes in miro from event stormings and how this analysis can be carried out with the help of the spaCy library.

Service

Value Added Reselling

Our Value Added Reselling approach creates a trusted partnership that maximizes SAM efficiency and ROI for our customers.

Blog 9/17/21

How to gather data from Miro

Learn how to gather data from Miro boards with this step-by-step guide. Streamline your data collection for deeper insights.

Header zu Fullstack Development
Service

Fullstack Development

The trend in Software Development is towards Full-Stack Development. Full-stack developers are programmers who work in both frontend and backend development and thus have competencies in the areas of databases, servers, systems and clients.

Schulung 6/2/23

Practice-oriented training for Google Workspace and GCP

Improve your skills in Google Workspace and GCP with our hands-on training courses. Optimize your workflows and increase your performance.

Blog 5/5/23

How we discover and organise domains in an existing product

Software companies and consultants like to flex their Domain Driven Design (DDD) muscles by throwing around terms like Domain, Subdomain and Bounded Context. But what lies behind these buzzwords, and how these apply to customers' diverse environments and needs, are often not as clear. As it turns out it takes a collaborative effort between stakeholders and development team(s) over a longer period of time on a regular basis to get them right.

Blog 4/28/23

Creating a Social Media Posts Generator Website with ChatGPT

Using the GPT-3-turbo and DALL-E models in Node.js to create a social post generator for a fictional product can be really helpful. The author uses ChatGPT to create an API that utilizes the openai library for Node.js., a Vue component with an input for the title and message of the post. This article provides step-by-step instructions for setting up the project and includes links to the code repository.

Blog 5/20/22

My Weekly Shutdown Routine

Discover my weekly shutdown routine to enhance productivity and start each week fresh. Learn effective techniques for reflection and organization.

Unternehmen

How we work

We think of ourselves as a tour guide for our clients. In this role we want to ensure that the digitalization adventure is a long-term success, because we believe that digitalization is not a one-off event, but a longer journey in a constantly changing world where you need to keep adapting.

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.

Training

Jira Administration Part 1 (Cloud)

Over the course of the "Jira Administration Part 1 (Cloud)" training course participants learn how to set up a new Atlassian Cloud site and Jira Cloud products.

Headerbild IBM Cloud Pak for Data System
Technologie

IBM Cloud Pak for Data System

With the Cloud Pak for Data System (CP4DS), IBM provides the optimal hardware for the use of all Cloud Pak for Data functions industry-wide and thus continues the series of ready-configured systems ("Appliance" or "Hyperconverged System").

Bleiben Sie mit dem TIMETOACT GROUP Newsletter auf dem Laufenden!