Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Copilot Instructions — micro-frontend-react

## Project Overview
Monorepo for the `@micro-frontend-react` npm packages enabling micro-frontend architecture on React applications. Host apps load micro-frontends at runtime via script injection and a global `window.__MICRO_FRONTENDS__` registry.

## Repository Structure
```
packages/micro-frontend-react/ → @micro-frontend-react/core (ComponentProvider, WebpackConfigs, Context)
packages/micro-frontend-react-redux/ → @micro-frontend-react/redux (StoreBuilder, ReducerRegistry)
packages/microsoft-employee-experience/ → @micro-frontend-react/employee-experience (AuthClient, Shell, telemetry, routing)
samples/sample-react-host/ → Sample host app (core only)
samples/sample-react-micro-frontend/ → Sample micro-frontend (core only)
samples/sample-react-redux-host/ → Sample host app (with Redux)
samples/sample-react-redux-micro-frontend/ → Sample micro-frontend (with Redux)
samples/sample-employee-experience/ → EE sample app (standalone, internal registry)
```

## Build System
- **npm workspaces** for dependency management (`packages/*` and `samples/sample-react-*`; no lerna, no yarn)
- **lage** for task orchestration (`npm run build` runs `lage build --no-cache`)
- **TypeScript** compiled via `tsc` (not webpack) for library packages
- **webpack 5** for sample apps and the generator example
- Build order enforced by lage pipeline: core → redux → employee-experience

## Key Commands
```
npm install # Install all workspace dependencies
npm run build # Build all library packages (lage)
npm run serve # Serve sample-react-host + sample-react-micro-frontend
npm run serve:redux # Serve sample-react-redux-host + sample-react-redux-micro-frontend
npm run install:ee # Install generator example deps (uses internal .npmrc) + link local packages
npm run serve:ee # Serve the EE generator example
npm run clean # Clean all build artifacts
npm run nuke # Full reset: delete node_modules + reinstall + clean
npm version patch --workspaces --no-git-tag-version # Bump all package versions
```

## Architecture Constraints

### UMD Externals Pattern
React, react-router-dom, and styled-components are loaded as **UMD bundles from CDN** (`ee.azureedge.net`) and declared as webpack externals. This is fundamental to the micro-frontend architecture — host and micro-frontends share a single React instance via globals (`window.React`, `window.ReactDOM`, `window.ReactRouterDOM`, `window.styled`).

**Do not upgrade these beyond their UMD-available versions:**
- `react` / `react-dom` / `react-is`: **18.3.1** (last version with official UMD builds; React 19 dropped UMD)
- `react-router-dom`: **5.3.4** (v6+ dropped UMD; v5 API: `Switch`, `exact`, `render` prop, `withRouter`)
- `styled-components`: **5.3.11** (v6 dropped UMD)

### Peer Dependencies
Library packages declare peer deps with `>=` lower bounds (no upper bounds). When modifying peer deps, ensure the range covers what consumers actually use.

### Employee Experience Sample (EE)
The `samples/sample-employee-experience/` project is **not** in npm workspaces because it depends on internal Microsoft packages (`@coherence-design-system`, `@m365-admin`) from private registries configured in its `.npmrc`. It links to the local `employee-experience` build via `npm link` (handled by `npm run install:ee`).

## TypeScript Configuration
- Library packages use `moduleResolution: "bundler"` (required for `@redux-devtools/extension` v4)
- No `typeRoots` — TypeScript's default resolution handles hoisted `@types` correctly in workspaces and for published consumers
- `skipLibCheck: true` is set on all packages
- `strict: true` on all packages

## Code Patterns

### ComponentProvider
Core mechanism for loading micro-frontends. Injects a `<script>` tag, waits for the UMD bundle to register on `window.__MICRO_FRONTENDS__[fileName][componentName]`, then renders the component. Do not change the loading mechanism without a major version bump.

### AuthClient (employee-experience)
Uses `@azure/msal-browser` v5. The `PublicClientApplication` must be initialized async (`await instance.initialize()`) before calling any API methods including `handleRedirectPromise()`.

### StoreBuilder (redux)
Uses `redux-persist` with a `PersistConfig<T>` generic. The dynamic reducer persist config requires an `as any` cast due to type incompatibility between the generic and `combineReducers` return type.

## Version Constraints

### Pinned Dependencies (UMD requirement)
The micro-frontend architecture loads shared dependencies as UMD bundles from CDN (`ee.azureedge.net`). These packages are pinned to their last UMD-available versions:

| Package | Max Version | Why |
|---------|------------|-----|
| `react` / `react-dom` / `react-is` | 18.3.1 | React 19 removed official UMD builds |
| `react-router-dom` | 5.3.4 | v6+ removed UMD; uses v5 API (`Switch`, `exact`, `render` prop, `withRouter`) |
| `styled-components` | 5.3.11 | v6 removed UMD builds |

React 18 active support ended Dec 2024 (security-only). react-router-dom v5 and styled-components v5 are no longer actively maintained. Do not upgrade these without migrating away from the UMD external pattern.

### Planned v2.0 — Module Federation
v2.0 will replace UMD script injection with **webpack Module Federation**:
- Unblocks React 19+, react-router-dom v7+, styled-components v6+
- Shares deps via webpack container API (`singleton: true`) instead of CDN globals
- Supports dynamic remotes (micro-frontend URLs from backend APIs at runtime)
- Replaces `window.__MICRO_FRONTENDS__` with federated module imports
- `ComponentProvider` loading mechanism will be rewritten
- `IComponentConfig` will change from `{ script, name }` to a federated remote format
- **Breaking change** for all consumers

## When Making Changes
1. Always run `npm run build` after changes — lage handles build ordering
2. After modifying package versions, update all internal cross-references (grep for `@micro-frontend-react/` in package.json files)
3. Test samples with `npm run serve` and `npm run serve:redux` to verify runtime behavior
4. The webpack `generateDevServerSettings` uses `server: 'https' | 'http'` (webpack-dev-server v5 API), not the deprecated `https: boolean`
5. Do not add `react-router-dom` v6/v7 APIs (`Routes`, `element` prop, `useNavigate`) — the project uses v5 APIs throughout
141 changes: 110 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,113 @@
# Micro-Frontend!

This is an open source library that shares a set of utilities that can be used to support Micro-Frontend architecture in your React.js applications.

While the proper documentation is being prepared, please see the following samples:

## React.js

* [Host application](https://github.com/microsoft/microfrontend/blob/main/samples/sample-react-host/src/App.tsx)
* The host application provides shared "Context"
* The host application loads Micro-Frontend applications using or `ComponentProvider` with runtime configuration
``` tsx
// Load a micro-frontend anywhere on the screen
<ComponentProvider
config={{
script: 'http://localhost:8000/bundles/micro-frontend-app.js',
name: 'MicroFrontendApp',
}}
/>
```
* [Micro-Frontend application](https://github.com/microsoft/microfrontend/blob/main/samples/sample-react-micro-frontend/src/MicroFrontendApp.tsx)
* Micro-Frontends are components that are developed and deployed in isolation
* Micro-Frontends will receive receive the "Context" when mounted

## React.js with Redux
* [Host application with Redux](https://github.com/microsoft/micro-frontend/blob/main/samples/sample-react-redux-host/src/App.tsx)
* Setup host application with various redux extensions such as redux-sagas, redux-logger, redux-persist
* Host's "Context" now includes utilities for Redux operations
* [Micro-Frontend application with Redux](https://github.com/microsoft/micro-frontend/blob/main/samples/sample-react-redux-micro-frontend/src/MicroFrontendApp.tsx)
* Retrieve data from host application's Redux store
* Register new reducer and saga to the host application's Redux store
# Micro-Frontend React

An open source library providing utilities to support micro-frontend architecture in React.js applications.

## Packages

| Package | Description |
|---------|-------------|
| `@micro-frontend-react/core` | ComponentProvider, WebpackConfigs, Context |
| `@micro-frontend-react/redux` | StoreBuilder, ReducerRegistry, Redux integration |
| `@micro-frontend-react/employee-experience` | AuthClient, Shell, telemetry, routing (Microsoft EE extension) |

## Prerequisites

- Node.js 18+
- npm 9+

## Getting Started

```bash
# Install dependencies (uses npm workspaces)
npm install

# Build all packages
npm run build

# Serve the basic sample (host on :9000, micro-frontend on :8000)
npm run serve

# Serve the Redux sample
npm run serve:redux
```

### Employee Experience Sample

The EE sample uses internal Microsoft package registries. It is not part of npm workspaces.

```bash
# Install dependencies (uses .npmrc for internal registries) and link local packages
npm run install:ee

# Serve the EE example
npm run serve:ee
```

## How It Works

Host applications load micro-frontends at runtime using `ComponentProvider`:

```tsx
<ComponentProvider
config={{
script: 'http://localhost:8000/bundles/micro-frontend-app.js',
name: 'MicroFrontendApp',
}}
/>
```

Micro-frontends are webpack UMD bundles that register on `window.__MICRO_FRONTENDS__`. Shared dependencies (React, react-router-dom, styled-components) are loaded once from CDN as webpack externals, ensuring a single instance across all micro-frontends.

## Samples

### React.js
* [Host application](samples/sample-react-host/src/App.tsx) — provides shared Context and loads micro-frontends via `ComponentProvider`
* [Micro-Frontend application](samples/sample-react-micro-frontend/src/MicroFrontendApp.tsx) — developed and deployed in isolation, receives Context when mounted

### React.js with Redux
* [Host application with Redux](samples/sample-react-redux-host/src/App.tsx) — host with redux-sagas, redux-logger, redux-persist
* [Micro-Frontend with Redux](samples/sample-react-redux-micro-frontend/src/MicroFrontendApp.tsx) — reads from host Redux store, registers reducers and sagas dynamically

## Version Constraints & Roadmap

### Current Limitations (v1.x)

The micro-frontend architecture relies on UMD bundles loaded from CDN as webpack externals. This constrains several dependencies to their last UMD-available versions:

| Package | Pinned Version | Reason |
|---------|---------------|--------|
| `react` / `react-dom` / `react-is` | 18.3.1 | React 19 removed official UMD builds |
| `react-router-dom` | 5.3.4 | v6+ removed UMD builds; v5 API (`Switch`, `exact`, `render` prop, `withRouter`) |
| `styled-components` | 5.3.11 | v6 removed UMD builds |

React 18 is in security-only support (active support ended Dec 2024). react-router-dom v5 and styled-components v5 are no longer actively maintained.

These libraries cannot be upgraded without replacing the UMD/CDN external loading pattern.

### Planned v2.0 — Module Federation

v2.0 will migrate from UMD script injection to **webpack Module Federation**, which:
- Removes the UMD/CDN dependency, unblocking React 19+, react-router-dom v7+, styled-components v6+
- Shares dependencies at runtime via webpack's container API (`singleton: true`) instead of global variables
- Supports dynamic remotes — micro-frontend URLs resolved at runtime from backend APIs (no build-time configuration required)
- Replaces `window.__MICRO_FRONTENDS__` global registry with federated module imports
- Requires a rewrite of `ComponentProvider`'s script loading mechanism

**v2.0 is a breaking change** for consumers. The `IComponentConfig` interface will change from `{ script, name }` to a federated remote format, and consumers will need to add `ModuleFederationPlugin` to their webpack configs with shared dependency declarations.

## Scripts

| Command | Description |
|---------|-------------|
| `npm install` | Install all workspace dependencies |
| `npm run build` | Build all library packages via lage |
| `npm run serve` | Serve basic sample apps |
| `npm run serve:redux` | Serve Redux sample apps |
| `npm run install:ee` | Install EE generator example + link local packages |
| `npm run serve:ee` | Serve EE generator example |
| `npm run clean` | Clean build artifacts |
| `npm run nuke` | Full reset (delete node_modules, reinstall, clean) |
| `npm version patch --workspaces --no-git-tag-version` | Bump all package versions |

## Contributing

Expand Down
63 changes: 0 additions & 63 deletions generators/microsoft-employee-experience-generator/.gitattributes

This file was deleted.

Loading
Loading