Skip to content

Native federation: Enabling dependency sharing across different micro frontends #1093

@Aukevanoost

Description

@Aukevanoost

In the default native-federation-runtime (v3), the singleton: true flag often fails to prevent duplicate bundle downloads. This happens because the legacy runtime uses strict string matching for version resolution.

If a Host uses version 18.1.0 and a Remote uses 18.1.1, the runtime treats them as incompatible, ignores the singleton constraint, and loads two separate instances. In Angular, this typically results in NG0203 (Injection Context) errors.
Resolution

The new @softarc/native-federation-orchestrator (v4 architecture) is now stable and resolves this by implementing true SemVer compatibility. It analyzes version ranges (e.g., ^18.0.0) to select the highest compatible version, ensuring singletons are respected across MFEs.

Implementation Comparison

  1. Legacy Runtime (v3)
  • Behavior: Strict version matching; no support for range resolution.

  • Initialization: Global execution without exposed loader scope.

// projects/host/src/main.ts
import { initFederation } from '@angular-architects/native-federation';

initFederation({
  mfe1: 'http://localhost:4201/remoteEntry.json',
})
  .catch(err => console.error(err))
  .then(_ => import('./bootstrap'));
  1. Stable Orchestrator (v4)
  • Behavior: Full SemVer support, customizable caching (localStorage), and plugin support (e.g., es-module-shims).

  • Initialization: Returns a NativeFederationResult containing the loadRemoteModule function.

// projects/host/src/main.ts
import { initFederation } from '@softarc/native-federation-orchestrator';
import { useShimImportMap, consoleLogger } from '@softarc/native-federation-orchestrator/options';

initFederation({
  mfe1: 'http://localhost:4201/remoteEntry.json',
}, {
  ...useShimImportMap({ shimMode: true }),
  logger: consoleLogger,
  logLevel: 'debug'
})
  .then(nf => import('./bootstrap').then(m => m.bootstrap(nf)))
  .catch(err => console.error(err));

Key Migration Steps

  • Install Orchestrator: npm i @softarc/native-federation-orchestrator

  • Update main.ts: Because loadRemoteModule is now scoped to the initialization result, it must be passed into the application (e.g., via an InjectionToken) rather than being imported globally.

  • Optional Caching: Configure storage: localStorageEntry in the options to persist dependency maps across page reloads.

Reference: Orchestrator Docs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions