DEV Community

Cover image for Building a Micro Frontend Architecture with Nx Workspace
Serif COLAKEL
Serif COLAKEL

Posted on

Building a Micro Frontend Architecture with Nx Workspace

In today's development landscape, creating a micro frontend architecture has become a popular approach for building scalable and modular applications. Nx Workspace offers a robust platform for implementing such architectures efficiently. In this tutorial, we'll walk through the process of setting up a micro frontend architecture using Nx Workspace, creating host and remote applications, and sharing code between them.

Link for Final Implementation

The final implementation of the micro frontend architecture can be found in the following repository commits:

Live Demo: Micro Frontend Architecture

Introduction

This tutorial will guide you through the process of creating a micro frontend architecture using Nx Workspace. We will create a host and remote application using Nx Workspace, and use packages for sharing code between applications. By the end of this tutorial, you will have a solid understanding of how to create a micro frontend architecture.

Prerequisites

Before we begin, make sure you have the following:

  • Base Repository for creating Nx Workspace with ESLint, Prettier, and Husky Configuration.

Setting Up the Workspace

  1. Clear any existing applications in the apps folder by running the following command:
rm -rf apps/*
Enter fullscreen mode Exit fullscreen mode
  1. Ensure that your package.json file is configured as follows:

Note: You are package.json file must be like this. Note if you are using different nx and related nx packages version set 17.0.1 version.

{
  "name": "@mfe-tutorial/source",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "lint": "pnpm exec nx run-many --target=lint --all",
    "prepare": "husky"
  },
  "private": true,
  "dependencies": {
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-router-dom": "6.11.2",
    "tslib": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.14.5",
    "@babel/preset-react": "^7.14.5",
    "@nx/cypress": "17.0.1",
    "@nx/devkit": "17.0.1",
    "@nx/eslint-plugin": "17.0.1",
    "@nx/jest": "17.0.1",
    "@nx/js": "17.0.1",
    "@nx/linter": "17.0.1",
    "@nx/playwright": "17.0.1",
    "@nx/react": "17.0.1",
    "@nx/vite": "17.0.1",
    "@nx/web": "17.0.1",
    "@nx/webpack": "17.0.1",
    "@nx/workspace": "17.0.1",
    "@playwright/test": "^1.36.0",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
    "@svgr/webpack": "^8.0.1",
    "@swc-node/register": "~1.6.7",
    "@swc/cli": "~0.1.62",
    "@swc/core": "~1.3.85",
    "@swc/helpers": "~0.5.2",
    "@testing-library/react": "14.0.0",
    "@types/jest": "^29.4.0",
    "@types/node": "18.14.2",
    "@types/react": "18.2.24",
    "@types/react-dom": "18.2.9",
    "@typescript-eslint/eslint-plugin": "^5.60.1",
    "@typescript-eslint/parser": "^5.60.1",
    "@vitejs/plugin-react": "~4.0.0",
    "@vitest/coverage-c8": "~0.32.0",
    "@vitest/ui": "~0.32.0",
    "babel-jest": "^29.4.1",
    "cypress": "^13.0.0",
    "eslint": "~8.46.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-airbnb-typescript": "^17.1.0",
    "eslint-config-prettier": "8.1.0",
    "eslint-plugin-cypress": "^2.13.4",
    "eslint-plugin-import": "2.27.5",
    "eslint-plugin-jsx-a11y": "6.7.1",
    "eslint-plugin-playwright": "^0.15.3",
    "eslint-plugin-prettier": "^5.1.3",
    "eslint-plugin-react": "7.32.2",
    "eslint-plugin-react-hooks": "4.6.0",
    "eslint-plugin-simple-import-sort": "^12.0.0",
    "husky": "^9.0.11",
    "jest": "^29.4.1",
    "jest-environment-jsdom": "^29.4.1",
    "jsdom": "~22.1.0",
    "netlify-cli": "^16.6.1",
    "nx": "17.0.1",
    "prettier": "^2.6.2",
    "react-refresh": "^0.10.0",
    "tailwindcss": "3.2.7",
    "ts-jest": "^29.1.0",
    "ts-node": "10.9.1",
    "typescript": "~5.1.3",
    "url-loader": "^4.1.1",
    "vite": "~4.3.9",
    "vite-plugin-dts": "~2.3.0",
    "vitest": "~0.32.0"
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Install the dependencies by running the following command:
  • You must be delete package-lock.json | yarn.lock | pnpm-lock.yaml and node_modules folder. You can use the following command to delete these files and folders.
rm -rf package-lock.json yarn.lock pnpm-lock.yaml node_modules
Enter fullscreen mode Exit fullscreen mode
  • Now, you can install the dependencies using the following command.
# using pnmp
pnpm install

# using yarn
yarn install

# using npm
npm install
Enter fullscreen mode Exit fullscreen mode

Congratulations! You have successfully installed the dependencies.

Creating the Host Application

  1. Create a host and remote application by running the following command:

Reference: Nx Module Federation

You can follow this script for host application we called name as container and The container application is used remote application called info.

With Script:

pnpm exec nx generate @nx/react:host --name=container --devServerPort=3000 --directory=apps/container --remotes=info --projectNameAndRootFormat=as-provided --no-interactive --dry-run
Enter fullscreen mode Exit fullscreen mode

With Nx Console:

Nx Console

  1. After creating the host and remote applications, run linting using the following command.
  // package.json
  "scripts": {
    "lint": "pnpm exec nx run-many --target=lint --all"
  },
Enter fullscreen mode Exit fullscreen mode
pnpm run lint

# or
yarn lint

# or
npm run lint
Enter fullscreen mode Exit fullscreen mode

Note: You can use the following command to fix or disable the basic eslint errors and warnings. ESLint Rules, Prettier Rules

pnpm run lint --fix
Enter fullscreen mode Exit fullscreen mode

Congratulations! You have successfully fixed the linting errors and warnings.

 Hot Reload and Development

This is the next step to run the host and remote applications. You can add the following scripts in the package.json file.

  "scripts": {
    "dev:container": "pnpm exec nx run container:serve --configuration=development",
    "dev:info": "pnpm exec nx run info:serve --configuration=development",
  },
Enter fullscreen mode Exit fullscreen mode
  • Now, you can run the host and remote applications using the following command. If you can do development on remote application first run dev:info and then run dev:container for host application. It's automatically connected to the remote application and hot refresh on changes.
pnpm run dev:info
Enter fullscreen mode Exit fullscreen mode
pnpm run dev:container
Enter fullscreen mode Exit fullscreen mode

Production Build

This is the final step to run the host and remote applications. You can add the following scripts in the package.json file.

  "scripts": {
    "serve:container": "pnpm exec nx run container:serve-static --configuration=production",
    "serve:info": "pnpm exec nx run info:serve-static --configuration=production",
  },
Enter fullscreen mode Exit fullscreen mode
  • Now, you can run the host and remote applications using the following command.
pnpm run serve:info
Enter fullscreen mode Exit fullscreen mode
pnpm run serve:container
Enter fullscreen mode Exit fullscreen mode

Note: You can use Nx Console for running the host and remote applications. Nx Console

Nx Console

🎉 Congratulations! You have successfully created your React application.

Conclusion

In this tutorial, we have learned how to create a micro frontend architecture using Nx Workspace. We have created a host and remote application using Nx Workspace, and shared code between them. By following the steps outlined in this tutorial, you can create a scalable and modular micro frontend architecture for your applications.

This tutorial has provided you with a solid foundation for building modular architecture using Nx Workspace. You can now explore more advanced features and configurations to enhance your micro frontend architecture further.

Thank you for reading! 🚀

References

Top comments (2)

Collapse
 
florianrappl profile image
Florian Rappl

This tutorial has provided you with a solid foundation for building micro frontend architectures using Nx Workspace.

Well, I'd argue it's not. MF is a runtime concept, so unless you make it possible to have multi-repository it will never be a solid foundation. It's a start - but it's not a scalable foundation. If you really want to stay within a monorepo then there are better (easier to manage) alternatives.

With micro frontends you want to be able to scale development - independent if you remain in a single repository or not.

So I'd prefer if you rephrase those things. Maybe call it "modular architecture" instead?

Collapse
 
serifcolakel profile image
Serif COLAKEL

Thank you your feedback. You are right, I may have difficulty defining them because they are technologies I have just gained experience with. Thank you for your suggestion, I will change it. <3