Skip to content

chore(mf)!: Remove Native Federation - #1121

Merged
Aukevanoost merged 2 commits into
mainfrom
chore/remove-native-federation
Aug 7, 2026
Merged

chore(mf)!: Remove Native Federation#1121
Aukevanoost merged 2 commits into
mainfrom
chore/remove-native-federation

Conversation

@Aukevanoost

@Aukevanoost Aukevanoost commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Native Federation has moved to its own organization at https://github.com/native-federation. This repository now ships only the Module Federation packages. The deprecated v3 sources for Angular 21 stay available on the 21.x.x backport branch, so nothing needs preserving on main.

Removed the five NF libs (native-federation, -core, -esbuild, -node, -runtime) and apps/native-federation-e2e.

Also removed the mfe1, mfe2 and playground demo apps with their e2e projects. Despite the names, all three were Native Federation demos: NF build executor, initFederation() from @angular-architects/native-federation, and withNativeFederation() configs. Transforming them to Module Federation would have rewritten every federation-relevant line while carrying forward NgModule-era boilerplate and a repair bill CI had already given up on -- they sat behind --exclude mfe1 mfe2 playground with a "remove exclude when apps are fixed" TODO, and their Cypress suites still used the Nx-12-era cypress.json format against Cypress 15. Module Federation demos will be rebuilt separately, generated through the plugin's own init-webpack schematic so they double as end-to-end coverage of it. libs/playground-lib is kept for that: it is the sharedMappings demo target, and Module Federation has the same feature.

The ng-add/init schematic no longer offers the native-federation-esbuild stack, which also drops its hardcoded
@angular-architects/native-federation@^19.0.0 install task.

Config fallout: 2 dependencies and 21 devDependencies whose only consumers were NF libs (167 packages out of node_modules), the NF targetDefault and the @nx/vite plugin from nx.json, and six @softarc/native-federation paths from tsconfig.base.json. serve.js went with the demo apps -- it was hardcoded to dist/apps/playground -- as did update-local-nf.sh and error.png, the latter referenced only by the NF readme. esbuild's ">=0.27.1 <0.27.4 || >0.27.4" range moved from devDependencies into overrides, where it can actually constrain the transitive copy @angular/build pulls in.

CI drops the Playwright install step, which existed for native-federation-runtime's vitest browser mode, and no longer needs the app exclusion list: nx affected -t lint test build now covers everything that remains.

The three @softarc/native-federation-* entries in DEFAULT_SKIP_LIST are kept deliberately. They are inert strings, and dropping them would silently change share behaviour for anyone running both plugin families during migration.

BREAKING CHANGE: ng add @angular-architects/module-federation no longer offers the Native Federation stack. Use github.com/native-federation/angular-adapter instead.

Native Federation has moved to its own organization at
github.com/native-federation. This repository now ships only the Module
Federation packages. The deprecated v3 sources for Angular 21 stay available on
the 21.x.x backport branch, so nothing needs preserving on main.

Removed the five NF libs (native-federation, -core, -esbuild, -node, -runtime)
and apps/native-federation-e2e.

Also removed the mfe1, mfe2 and playground demo apps with their e2e projects.
Despite the names, all three were Native Federation demos: NF build executor,
initFederation() from @angular-architects/native-federation, and
withNativeFederation() configs. Transforming them to Module Federation would
have rewritten every federation-relevant line while carrying forward
NgModule-era boilerplate and a repair bill CI had already given up on -- they
sat behind `--exclude mfe1 mfe2 playground` with a "remove exclude when apps are
fixed" TODO, and their Cypress suites still used the Nx-12-era cypress.json
format against Cypress 15. Module Federation demos will be rebuilt separately,
generated through the plugin's own init-webpack schematic so they double as
end-to-end coverage of it. libs/playground-lib is kept for that: it is the
sharedMappings demo target, and Module Federation has the same feature.

The ng-add/init schematic no longer offers the native-federation-esbuild stack,
which also drops its hardcoded
@angular-architects/native-federation@^19.0.0 install task.

Config fallout: 2 dependencies and 21 devDependencies whose only consumers were
NF libs (167 packages out of node_modules), the NF targetDefault and the
@nx/vite plugin from nx.json, and six @softarc/native-federation paths from
tsconfig.base.json. serve.js went with the demo apps -- it was hardcoded to
dist/apps/playground -- as did update-local-nf.sh and error.png, the latter
referenced only by the NF readme. esbuild's ">=0.27.1 <0.27.4 || >0.27.4" range
moved from devDependencies into overrides, where it can actually constrain the
transitive copy @angular/build pulls in.

CI drops the Playwright install step, which existed for
native-federation-runtime's vitest browser mode, and no longer needs the app
exclusion list: `nx affected -t lint test build` now covers everything that
remains.

The three @softarc/native-federation-* entries in DEFAULT_SKIP_LIST are kept
deliberately. They are inert strings, and dropping them would silently change
share behaviour for anyone running both plugin families during migration.

BREAKING CHANGE: `ng add @angular-architects/module-federation` no longer offers
the Native Federation stack. Use github.com/native-federation/angular-adapter
instead.
Fills the gap left by 6faeafe, which removed the mfe1, mfe2 and playground apps
-- all three Native Federation demos despite their names -- and noted that
Module Federation demos would be rebuilt separately.

A dynamic host and two remotes, all built against the sources in libs/:

- shell (:4200) declares no build-time remotes. initFederation() fetches
  public/mf.manifest.json before Angular boots, so remotes can move or be added
  without rebuilding the host.
- mfe1 (:4201) exposes './routes' and owns everything under /flights, while
  mfe2 (:4202) exposes './Component' and the shell routes to it directly. Both
  loadRemoteModule granularities are covered.
- libs/playground-lib is shared as a singleton through sharedMappings, which is
  what 6faeafe kept it for. A name typed into the shell's login box is read back
  by both remotes out of the same AuthService instance.
- Each app also boots standalone on its own port.

`nx serve shell` starts all three, since the remotes are serve-time
dependencies of the host. Angular 22 standalone components and route-level
federation throughout, rather than the NgModule-era boilerplate the old demos
carried.

Verified in headless Chrome over CDP in both development and production
configurations: both remotes render inside the shell, both observe the
shell-set AuthService.userName, each remoteEntry.js loads cross-origin while
@angular/core is downloaded from a single origin, and both remotes still boot
standalone. Cypress cannot drive this -- its script rewriting breaks
import.meta in the type="module" output the plugin emits.

Three concessions to living inside the plugin's own repository, all documented
in apps/README.md:

- The webpack configs require ../../dist/libs/mf/webpack instead of
  @angular-architects/module-federation/webpack, since the package is never
  installed here. Both the build and serve targets dependsOn mf:build so the
  output exists before webpack loads the config.
- The shell aliases the runtime to libs/mf/src and libs/mf-runtime/src rather
  than dist/. Building mf also rebuilds mf-runtime, and ng-packagr recreates
  dist/libs/mf-runtime, which yanks the module out from under a dev-server that
  is already watching it. Sources also mean editing a library live-reloads the
  demo.
- shell/tsconfig.app.json sets strict: false, because libs/mf-runtime is itself
  compiled with strict: false and violates both strictNullChecks and
  noImplicitAny, which a strict program cannot consume. Only the app build is
  relaxed -- the specs still type-check strictly, and mfe1 and mfe2 stay fully
  strict. Making libs/mf-runtime strict-clean would remove this; it is 9 errors,
  all in dynamic-federation.ts, and the enhanced entry point is already clean.

The configs match what init-webpack generates for an Nx workspace
(@nx/angular:webpack-browser and :dev-server, commonChunk: false,
extractLicenses: false, a CORS header per remote), but they were written by hand
rather than produced by running the schematic, so they do not yet double as
end-to-end coverage of it the way 6faeafe intended.

One known cosmetic defect, documented rather than worked around: under
`nx serve` every page load logs "SyntaxError: Cannot use 'import.meta' outside
a module". withModuleFederationPlugin sets experiments.outputModule, so webpack
emits ESM for all entry points, but Angular's index-html generator injects the
styles entry with defer rather than type="module". The failing chunk holds only
webpack runtime boilerplate, global CSS still applies through the separate
stylesheet link, and production builds emit no styles script at all.
@Aukevanoost
Aukevanoost merged commit ea5eac6 into main Aug 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant