Skip to content

Module federation support - #613

Open
dlebedynskyi wants to merge 12 commits into
uni-stack:mainfrom
dlebedynskyi:demo/uniwind-module-federation-conflicts
Open

Module federation support#613
dlebedynskyi wants to merge 12 commits into
uni-stack:mainfrom
dlebedynskyi:demo/uniwind-module-federation-conflicts

Conversation

@dlebedynskyi

@dlebedynskyi dlebedynskyi commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a runnable Module Federation reproduction with one host and two independently compiled remotes on web and iOS.

The demo isolates two Uniwind collision modes:

  • Shared class names use the last-loaded remote's definition.
  • Shared CSS variables use the last-loaded remote's value.
  • On native, each generated stylesheet calls Uniwind.__reinit(...), replacing the complete registry and removing owner-only styles from earlier graphs.

No Uniwind source or collision fix is included. This PR only demonstrates the failures and documents the Metro/MF compatibility work required to load all three graphs.

Related discussion: #612

Demo structure

Three Metro servers run in parallel:

  • Host 8081 Green #16a34a
  • Remote A 8082 Yellow #facc15
  • Remote B 8083 Blue #2563eb

Each panel renders three signals:

  • An owner-only class, showing whether that graph's stylesheet or native registry remains available.
  • A shared mf-conflict class with a different definition in every graph.
  • A shared --mf-shared-color variable consumed by mf-variable-probe.

Every signal prints both its declared color and the value currently resolved by Uniwind. Missing native classes are shown as not registered, so the reproduction does not depend on visually distinguishing colors.

Reproduced behavior

Web

Each graph's stylesheet remains installed, so owner-only classes keep their original colors.

Shared selectors and variables remain global:

  • Loading A then B makes every shared signal blue.
  • Loading B then A makes every shared signal yellow.
  • Reversing the load order reverses the winner.

iOS

Each CSS entry executes Uniwind.__reinit(...), replacing the complete native registry, variables, and caches:

  • Loading A then B removes the host and Remote A owner-only classes. Shared signals resolve to Remote B blue.
  • Loading B then A removes the host and Remote B owner-only classes. Shared signals resolve to Remote A yellow.
  • Earlier owner-only signals report not registered.

Metro and Module Federation compatibility

The demo includes integration code required to load three independently compiled Metro graphs into one Expo 57 runtime:

  • Shares React, React Native, and the Uniwind package root as versioned singletons.
  • Applies Module Federation before withUniwindConfig and explicitly composes their resolvers.
  • Resolves imports originating inside Uniwind through the base resolver to avoid shared-proxy cycles.
  • Initializes the MF host explicitly before Expo installs its runtime.
  • Captures each graph's active Metro __r under its federation-prefixed name.
  • Replaces mf:async-require with a graph-aware Expo-compatible demo loader.
  • Resolves mf:remote-hmr to a no-op because it is imported only by generated remote entries and is not currently graph-safe.
  • Adds cross-port CORS headers.
  • Uses the existing Expo/Uniwind culori/require Babel alias.
  • Builds a local iOS development client instead of relying on Expo Go.

These are compatibility bridges for the reproduction, not proposed production implementations.

Running the demo

Web:

  bun install
  bun run --cwd apps/module-federation web

Run the headed browser assertions in another terminal:

bun run --cwd apps/module-federation verify:web

iOS Simulator:

bun run --cwd apps/module-federation ios

Stop all three managed servers:

bun run --cwd apps/module-federation stop

Capture

Web demo

MF-web-demo.mov

iOS demo

mf-native-demo.mov

Summary by CodeRabbit

  • New Features

    • Added a Module Federation demo with a host app and two dynamically loaded remote panels for web and iOS.
    • Added federated style isolation with shared, remote-only, and conflicting style examples.
    • Added runtime reload support, loading states, error handling, and visual style-resolution indicators.
    • Added asynchronous remote bundle loading and reliable remote style merging.
    • Added configurable shared style candidates and theme validation.
  • Documentation

    • Added setup, platform workflow, verification, and expected-results documentation.
  • Bug Fixes

    • Improved stylesheet load, unload, reload, and media-query change detection.

Loading
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.

2 participants