Skip to content

Repository files navigation

MicroStore

An Angular microfrontend e-commerce application built with Nx, Module Federation, NgRx, and Angular Material. The workspace contains three apps (a host shell and two remote microfrontends) and four shared libraries.

Architecture

Application structure

App Role Dev port
store Host shell — composes the remotes, owns the NgRx store, renders toolbar / banner / footer 4200
products Remote microfrontend — product grid with size selection and add-to-cart 4201
checkout Remote microfrontend — cart summary and order total 4202

Library structure

Library Path Role
shared-data-access libs/shared/shared-data-access NgRx feature slices (products + cart), ProductsService, Product model, facades
shared-ui libs/shared/shared-ui Shared presentational utilities — OptimizedImagePipe (wsrv.nl proxy)
store-feature-shell libs/store/store-feature-shell Page layout (banner, footer, content projection), home tech-features cards
products-feature-shell libs/products/products-feature-shell Products page, ProductCardComponent (dumb), OptimizedImagePipe
checkout-feature-shell libs/checkout/checkout-feature-shell Cart item list, quantity controls, order total

Runtime composition

At startup the host fetches module-federation.manifest.json to discover where the remotes live, then uses @module-federation/enhanced to lazy-load their exposed ./Routes modules on navigation.

graph TD
    Browser -->|":4200"| Store

    subgraph Store ["store (host shell)"]
        Toolbar["Toolbar + cart badge"]
        Shell["StoreFeatureShell\nbanner · footer · router-outlet"]
        Router["Angular Router"]
    end

    Router -->|"/products"| Products
    Router -->|"/checkout"| Checkout

    subgraph Products ["products (remote :4201)"]
        PShell["ProductsFeatureShellComponent"]
        PCard["ProductCardComponent\nsize toggle · add-to-cart"]
        PShell --> PCard
    end

    subgraph Checkout ["checkout (remote :4202)"]
        CShell["CheckoutFeatureShellComponent\ncart items · total"]
    end

    subgraph Shared ["libs/shared/shared-data-access"]
        Facade["StoreFacade / CartFacade"]
        Store2["NgRx singleton store"]
        Facade --> Store2
    end

    Store --> Shared
    Products --> Shared
    Checkout --> Shared
Loading

The NgRx store is provided once in the host (app.config.ts). Because Module Federation shares the Angular runtime, every remote dispatches to and selects from the same singleton store instance — a cart action dispatched in the products remote updates the host toolbar badge in real time.


Docker (production) architecture

graph TD
    Browser -->|"port 80"| Proxy["nginx reverse proxy\nroutes by URL prefix"]

    Proxy -->|"/"| StoreNginx["store\nnginx"]
    Proxy -->|"/products/*"| ProductsNginx["products\nnginx"]
    Proxy -->|"/checkout/*"| CheckoutNginx["checkout\nnginx"]
Loading

The proxy strips the prefix before forwarding, so remotes are referenced with relative paths (/products/mf-manifest.json) — no hardcoded hostnames or ports anywhere.

Browser URL Routed to
/ store container
/products/* products container
/checkout/* checkout container

Each app container is built with a two-stage Dockerfile: a Node build stage runs nx build, then the output is copied into a minimal nginx image.


State management (NgRx)

The app uses the modern NgRx APIs throughout: createFeature, createActionGroup, and the Facade pattern to keep components decoupled from the store.

  • Effects are used only for async work (loading products from the API).
  • Cart is fully synchronous — no effects needed, the reducer handles everything in-memory.
  • Components never import NgRx directly; they talk to a StoreFacade or CartFacade.

Data flow

sequenceDiagram
    participant Component
    participant Facade
    participant Store as NgRx Store
    participant API as Fakestore API

    note over Component,API: Products load
    Component->>Facade: loadProducts()
    Facade->>Store: dispatch action
    Store->>API: GET /api/products
    API-->>Store: Product[]
    Store-->>Facade: selectStoreProducts
    Facade-->>Component: storeProducts$

    note over Component,Store: Add to cart
    Component->>Facade: addToCart(product, size)
    Facade->>Store: dispatch action
    Store-->>Facade: selectCartItems / selectCartCount
    Facade-->>Component: cartItems$ · cartCount$ · cartTotal$
Loading

Getting started

Prerequisites

Local development (without Docker)

Install dependencies and start all three apps with a single command:

npm install
npx nx serve store --devRemotes products,checkout

Open http://localhost:4200.

The host discovers remotes via apps/store/public/module-federation.manifest.json which points to localhost:4201 and localhost:4202.


Docker

Production

Builds all three apps and starts them behind an nginx reverse proxy on port 80.

docker compose up --build

Open http://localhost.

To rebuild a single service after a code change:

docker compose up --build store

To stop and remove containers:

docker compose down

Development (Docker)

Runs nx serve inside a container with the source directory mounted. Useful for teams without a local Node setup or for CI preview environments.

docker compose -f docker-compose.dev.yml up

Open http://localhost:4200.

Note: The first run installs node_modules inside the container — this takes a few minutes. Subsequent runs reuse the node_modules named volume and start much faster.


Key files

├── docker-compose.yml          # production: proxy + 3 app containers
├── docker-compose.dev.yml      # development: single container with nx serve
├── nginx/
│   ├── proxy.conf              # reverse proxy routing rules
│   ├── store.conf              # SPA fallback (try_files → index.html)
│   └── remote.conf             # static file server for remotes
├── apps/
│   ├── store/
│   │   ├── Dockerfile
│   │   └── public/
│   │       ├── module-federation.manifest.json       # dev (localhost URLs)
│   │       └── module-federation.manifest.prod.json  # production (relative paths)
│   ├── products/Dockerfile
│   └── checkout/Dockerfile
├── libs/
│   ├── shared/shared-data-access/  # NgRx + API + models
│   ├── store/store-feature-shell/  # page layout + home
│   ├── products/products-feature-shell/  # product cards
│   └── checkout/checkout-feature-shell/ # cart view

Nx tasks

Run any Nx target directly:

# Build a single app
npx nx build store

# Lint
npx nx lint products

# Test
npx nx test checkout

# Visualize the project graph
npx nx graph

# Add library
npx nx g @nx/angular:lib libs/store/store-data-access --style=scss

About

POC for and Ecommerce app using Angular Microfrontends. (In development)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages