|
| 1 | +# Copilot Instructions — micro-frontend-react |
| 2 | + |
| 3 | +## Project Overview |
| 4 | +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. |
| 5 | + |
| 6 | +## Repository Structure |
| 7 | +``` |
| 8 | +packages/micro-frontend-react/ → @micro-frontend-react/core (ComponentProvider, WebpackConfigs, Context) |
| 9 | +packages/micro-frontend-react-redux/ → @micro-frontend-react/redux (StoreBuilder, ReducerRegistry) |
| 10 | +packages/microsoft-employee-experience/ → @micro-frontend-react/employee-experience (AuthClient, Shell, telemetry, routing) |
| 11 | +samples/sample-react-host/ → Sample host app (core only) |
| 12 | +samples/sample-react-micro-frontend/ → Sample micro-frontend (core only) |
| 13 | +samples/sample-react-redux-host/ → Sample host app (with Redux) |
| 14 | +samples/sample-react-redux-micro-frontend/ → Sample micro-frontend (with Redux) |
| 15 | +samples/sample-employee-experience/ → EE sample app (standalone, internal registry) |
| 16 | +``` |
| 17 | + |
| 18 | +## Build System |
| 19 | +- **npm workspaces** for dependency management (`packages/*` and `samples/sample-react-*`; no lerna, no yarn) |
| 20 | +- **lage** for task orchestration (`npm run build` runs `lage build --no-cache`) |
| 21 | +- **TypeScript** compiled via `tsc` (not webpack) for library packages |
| 22 | +- **webpack 5** for sample apps and the generator example |
| 23 | +- Build order enforced by lage pipeline: core → redux → employee-experience |
| 24 | + |
| 25 | +## Key Commands |
| 26 | +``` |
| 27 | +npm install # Install all workspace dependencies |
| 28 | +npm run build # Build all library packages (lage) |
| 29 | +npm run serve # Serve sample-react-host + sample-react-micro-frontend |
| 30 | +npm run serve:redux # Serve sample-react-redux-host + sample-react-redux-micro-frontend |
| 31 | +npm run install:ee # Install generator example deps (uses internal .npmrc) + link local packages |
| 32 | +npm run serve:ee # Serve the EE generator example |
| 33 | +npm run clean # Clean all build artifacts |
| 34 | +npm run nuke # Full reset: delete node_modules + reinstall + clean |
| 35 | +npm version patch --workspaces --no-git-tag-version # Bump all package versions |
| 36 | +``` |
| 37 | + |
| 38 | +## Architecture Constraints |
| 39 | + |
| 40 | +### UMD Externals Pattern |
| 41 | +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`). |
| 42 | + |
| 43 | +**Do not upgrade these beyond their UMD-available versions:** |
| 44 | +- `react` / `react-dom` / `react-is`: **18.3.1** (last version with official UMD builds; React 19 dropped UMD) |
| 45 | +- `react-router-dom`: **5.3.4** (v6+ dropped UMD; v5 API: `Switch`, `exact`, `render` prop, `withRouter`) |
| 46 | +- `styled-components`: **5.3.11** (v6 dropped UMD) |
| 47 | + |
| 48 | +### Peer Dependencies |
| 49 | +Library packages declare peer deps with `>=` lower bounds (no upper bounds). When modifying peer deps, ensure the range covers what consumers actually use. |
| 50 | + |
| 51 | +### Employee Experience Sample (EE) |
| 52 | +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`). |
| 53 | + |
| 54 | +## TypeScript Configuration |
| 55 | +- Library packages use `moduleResolution: "bundler"` (required for `@redux-devtools/extension` v4) |
| 56 | +- No `typeRoots` — TypeScript's default resolution handles hoisted `@types` correctly in workspaces and for published consumers |
| 57 | +- `skipLibCheck: true` is set on all packages |
| 58 | +- `strict: true` on all packages |
| 59 | + |
| 60 | +## Code Patterns |
| 61 | + |
| 62 | +### ComponentProvider |
| 63 | +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. |
| 64 | + |
| 65 | +### AuthClient (employee-experience) |
| 66 | +Uses `@azure/msal-browser` v5. The `PublicClientApplication` must be initialized async (`await instance.initialize()`) before calling any API methods including `handleRedirectPromise()`. |
| 67 | + |
| 68 | +### StoreBuilder (redux) |
| 69 | +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. |
| 70 | + |
| 71 | +## Version Constraints |
| 72 | + |
| 73 | +### Pinned Dependencies (UMD requirement) |
| 74 | +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: |
| 75 | + |
| 76 | +| Package | Max Version | Why | |
| 77 | +|---------|------------|-----| |
| 78 | +| `react` / `react-dom` / `react-is` | 18.3.1 | React 19 removed official UMD builds | |
| 79 | +| `react-router-dom` | 5.3.4 | v6+ removed UMD; uses v5 API (`Switch`, `exact`, `render` prop, `withRouter`) | |
| 80 | +| `styled-components` | 5.3.11 | v6 removed UMD builds | |
| 81 | + |
| 82 | +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. |
| 83 | + |
| 84 | +### Planned v2.0 — Module Federation |
| 85 | +v2.0 will replace UMD script injection with **webpack Module Federation**: |
| 86 | +- Unblocks React 19+, react-router-dom v7+, styled-components v6+ |
| 87 | +- Shares deps via webpack container API (`singleton: true`) instead of CDN globals |
| 88 | +- Supports dynamic remotes (micro-frontend URLs from backend APIs at runtime) |
| 89 | +- Replaces `window.__MICRO_FRONTENDS__` with federated module imports |
| 90 | +- `ComponentProvider` loading mechanism will be rewritten |
| 91 | +- `IComponentConfig` will change from `{ script, name }` to a federated remote format |
| 92 | +- **Breaking change** for all consumers |
| 93 | + |
| 94 | +## When Making Changes |
| 95 | +1. Always run `npm run build` after changes — lage handles build ordering |
| 96 | +2. After modifying package versions, update all internal cross-references (grep for `@micro-frontend-react/` in package.json files) |
| 97 | +3. Test samples with `npm run serve` and `npm run serve:redux` to verify runtime behavior |
| 98 | +4. The webpack `generateDevServerSettings` uses `server: 'https' | 'http'` (webpack-dev-server v5 API), not the deprecated `https: boolean` |
| 99 | +5. Do not add `react-router-dom` v6/v7 APIs (`Routes`, `element` prop, `useNavigate`) — the project uses v5 APIs throughout |
0 commit comments