-
Notifications
You must be signed in to change notification settings - Fork 4
Development Guide
This guide covers building, testing, running, and contributing to the @microfrontend project.
- Node.js (LTS recommended)
- npm (comes with Node.js)
-
Angular CLI 15.x (installed locally via
devDependencies) - Google Chrome (for unit tests and E2E tests)
microfrontend/
├── .github/workflows/ # CI pipeline (GitHub Actions)
├── badges/ # Code coverage badge SVGs
├── dist/ # Build output
├── e2e/ # Playwright E2E tests
│ └── src/
│ ├── app.e2e-spec.ts # Test specs
│ └── app.po.ts # Page Object
├── projects/
│ ├── common/ # @microfrontend/common library
│ ├── controller/ # @microfrontend/controller library
│ ├── client/ # @microfrontend/client library
│ ├── src-a/ # Sample microfrontend A
│ └── src-b/ # Sample microfrontend B
├── src/ # Sample shell application
├── angular.json # Angular workspace configuration
├── package.json # Root package.json
├── playwright.config.ts # Playwright E2E configuration
├── tsconfig.json # Root TypeScript configuration
└── karma.conf.js # Root Karma configuration
git clone https://github.com/demyanets/microfrontend.git
cd microfrontend
npm installLibraries must be built in order due to inter-dependencies:
# Build all libraries (common → controller → client)
npm run build
# Production build with optimizations
npm run build:prodThe build order is:
-
@microfrontend/common(no dependencies) -
@microfrontend/controller(depends oncommon) -
@microfrontend/client(depends oncommon)
Build artifacts are written to dist/.
The sample application consists of three servers:
| Application | Role | Port |
|---|---|---|
| Shell | Host application | 30103 |
| Microfrontend A | Sample child app | 30307 |
| Microfrontend B | Sample child app | 30809 |
# Start all three dev servers concurrently
npm run serveNavigate to http://localhost:30103/ to see the shell with both microfrontends.
Unit tests use Jasmine and Karma with Chrome.
# Run all unit tests
npm run test
# Run with code coverage (ChromeHeadless)
npm run coverageCoverage reports are written to coverage/. The project tracks coverage for all three libraries separately.
E2E tests use Playwright. Playwright automatically starts all three dev servers before running and shuts them down afterwards.
# Run E2E tests in headless mode
npm run e2e
# Run E2E tests with visible browser
npm run e2e:headedCorporate proxy note: If Playwright's browser download fails behind a proxy, either configure
HTTPS_PROXYbefore runningnpx playwright install chromium, or use a locally installed browser by settingchannel: 'chrome'(or'msedge') inplaywright.config.ts.
Each library has its own test directory with:
-
*.spec.ts— Test files -
mocks/— Test doubles for facades and service providers
The facade pattern (thin wrappers around browser APIs) enables comprehensive testing. Facades like FrameFacade, HistoryApiFacade, LocationFacade, and ParentFacade are excluded from coverage since they are thin wrappers tested indirectly.
npm run lintRuns TSLint on library code. Sample applications and unit tests are excluded.
npm run prettierFormats source files using Prettier.
The GitHub Actions workflow (.github/workflows/test.yaml) runs on:
- All pushes
- Pull requests to
master,develop, andreleases/*
Pipeline stages:
-
Build —
npm ci+npm run build -
Test (depends on build) —
npm ci+npm run coverage+ generate coverage badges
Each library is configured for public npm publishing under the @microfrontend scope:
{
"publishConfig": {
"access": "public"
}
}To publish (maintainers):
cd dist/common && npm publish
cd dist/controller && npm publish
cd dist/client && npm publishImportant: Build in production mode before publishing:
npm run build:prod.
All three libraries depend only on tslib. They use no Angular, React, or Vue runtime code. This makes them compatible with any SPA framework.
Browser APIs (window.postMessage, history.pushState, location.hash, document.createElement) are wrapped in facade classes. This:
- Enables unit testing without a real browser DOM
- Decouples business logic from browser APIs
- Allows mock injection via service providers
Classes that hold event listeners or other resources extend Destroyable, providing a destroy() method and guards against use-after-destroy.
The PromiseSingletonDecorator ensures that when multiple navigation requests race (e.g., rapid clicks), only the most recent one resolves. Earlier promises are discarded, preventing stale navigation.
| Term | Meaning |
|---|---|
| Microfrontend (aka Routed Application) | Independently deployed and maintained SPA application |
| Shell (aka Parent Shell) | Parent application controlling microfrontends |
| Outlet | Placeholder for multiple microfrontends. Only one is visible at a time. |
| Controller (aka Meta Router) | Shell controller managing outlets and microfrontends |
| Meta Route | String identifier mapping a microfrontend to a base URL |
| Sub Route | Internal route within a microfrontend |
@microfrontend — MIT License — npm — GitHub
Getting Started
Guides
API Reference
Contributing