Building a Micro Frontend Architecture with Nx Workspace
Tags: webdev, javascript, react, beginners
Published: 2024-03-28 22:19:41

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:

- [Micro Front end Setup](https://github.com/serifcolakel/mfe-tutorial/commit/cd91400ced852fb312602e30be1a1eb30a41ca1b)
- [Update remote URL for 'info' module for production on Netlify](https://github.com/serifcolakel/mfe-tutorial/commit/829f4290c2a6253ccf5e58ec6dcafebd6cf7c5d7)
- [Add redirect rule to netlify.toml and Cors error on Netlify](https://github.com/serifcolakel/mfe-tutorial/commit/df4300b143258cea1d4b9df1d237a4291b65b4ce)

> Live Demo: [Micro Frontend Architecture](https://relaxed-mochi-7581fa.netlify.app/)

## 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](https://javascript.plainenglish.io/creating-nx-workspace-with-eslint-prettier-and-husky-configuration-b5f4d2fcb914) 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:

```bash
rm -rf apps/*
```

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

```json
{
  "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"
  }
}
```

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

```bash
rm -rf package-lock.json yarn.lock pnpm-lock.yaml node_modules
```

- Now, you can install the dependencies using the following command.

```bash
# using pnmp
pnpm install

# using yarn
yarn install

# using npm
npm install
```

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](https://nx.dev/concepts/module-federation/faster-builds-with-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:

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

> With Nx Console:

![Nx Console](https://i.hizliresim.com/8hb6j8j.png)

2. After creating the host and remote applications, run linting using the following command.

```json
  // package.json
  "scripts": {
    "lint": "pnpm exec nx run-many --target=lint --all"
  },
```

```bash
pnpm run lint

# or
yarn lint

# or
npm run lint
```

> **Note**: You can use the following command to fix or disable the basic eslint errors and warnings. [ESLint Rules](https://eslint.org/docs/rules/), [Prettier Rules](https://prettier.io/docs/en/options.html)

```bash
pnpm run lint --fix
```

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.

```json
  "scripts": {
    "dev:container": "pnpm exec nx run container:serve --configuration=development",
    "dev:info": "pnpm exec nx run info:serve --configuration=development",
  },
```

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

```bash
pnpm run dev:info
```

```bash
pnpm run dev:container
```

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

```json
  "scripts": {
    "serve:container": "pnpm exec nx run container:serve-static --configuration=production",
    "serve:info": "pnpm exec nx run info:serve-static --configuration=production",
  },
```

- Now, you can run the host and remote applications using the following command.

```bash
pnpm run serve:info
```

```bash
pnpm run serve:container
```

> **Note**: You can use Nx Console for running the host and remote applications. [Nx Console](https://nx.dev/recipes/nx-console/console-run-command#nx-console-run-command)

![Nx Console](https://i.hizliresim.com/bpoacn7.png)

🎉 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

- [Nx Workspace](https://nx.dev/react)
- [Nx Module Federation](https://nx.dev/concepts/module-federation/faster-builds-with-module-federation)
- [Nx Console](https://nx.dev/recipes/nx-console/console-run-command#nx-console-run-command)
- [React](https://reactjs.org/)
- [React Router](https://reactrouter.com/)
- [TypeScript](https://www.typescriptlang.org/)
- [ESLint Rules](https://eslint.org/docs/rules/)
- [Prettier Rules](https://prettier.io/docs/en/options.html)
- [Netlify](https://www.netlify.com/)
- [Netlify Redirects](https://docs.netlify.com/routing/redirects/redirect-options/)
- [Netlify Headers](https://docs.netlify.com/routing/headers/)
- [Netlify Functions](https://docs.netlify.com/functions/overview/)