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/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 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.

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 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 1/29/20

Tracing IO in .NET Core

Learn how we leverage OpenTelemetry for efficient tracing of IO operations in .NET Core applications, enhancing performance and monitoring.

App 8/8/22

Teamworkx Connector for Jira

Collaboration across different applications - this is possible with the "Teamworkx Connector for Jira". It creates connections to SAP®, other Jira instances or third-party applications.

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.

Headerbild zu Digitale Transformation bei Versicherern
Leistung

Mastering digital transformation in insurance

Digital transformation is the transformation of the corporate world through new technologies and the Internet ► Learn how insurers can master this.

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.

Titelbild OneIdentity by Quest
Partner

One Identity

OneIdentity, a brand of Quest Software, offers community-based solutions that simplify IT management and create more room for innovation.

Headerbild zu Managed Services
Service

Managed Services & Support

Our Managed Services ensure that applications are operated for you with a holistic understanding of infrastructure, licenses, support, applications and the corresponding expertise. This is done regardless of whether the application is to be operated at a hyperscale such as IBM Cloud, Google, AWS, Azure or onPrem.

Headerbild Talend Application Integration
Technologie

Talend Application Integration / ESB

With Talend Application Integration, you create a service-oriented architecture and connect, broker & manage your services and APIs in real time.

Two people discussing in front of a computer
Lösung 2/14/22

The COBOL Survival Team for IBM i (AS400)

COBOL developers on IBM i (AS400) are a rare commodity. PKS provides a powerful team especially for this application!

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 2/21/22

The Power of Event Sourcing

This is how we used Event Sourcing to maintain flexibility, handle changes, and ensure efficient error resolution in application development.

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 9/15/22

Introduction to Functional Programming in F# – Part 3

Dive into F# data structures and pattern matching. Simplify code and enhance functionality with these powerful features.

Bleiben Sie mit dem TIMETOACT GROUP Newsletter auf dem Laufenden!