WU / DOCSUNIVERSAL MICROFRONTENDS
EN

Compare a shadow version

Run a hidden twin, compare its WU outputs and understand the comparison boundaries.

This page describes WU Framework 4.0.0. Read the Framework 4.0 and CLI 1.2 migration guide before upgrading an existing project.

The primary app stays visible and mounted. wu.shadow mounts a hidden, inert twin, replicates inputs crossing WU and records its facade outputs. Use it to compare a rewrite or update before replacing the visible app.

import { wu } from 'wu-framework/core';
import 'wu-framework/shadow';

// cart must already be registered and mounted.
await wu.shadow.start('cart', { url: '/apps/cart-v2/', rpcTimeout: 5000 });
try {
  await wu.update('cart', { currency: 'EUR' });
  const report = wu.shadow.report('cart');
  console.log(report.equal, report.dom, report.outputs);
} finally {
  await wu.shadow.stop('cart');
}

Inputs and outputs

The twin receives props, events and store reads. Its writes use a private overlay. Its RPC or contract calls receive recorded primary responses for the same channel and arguments. Twin emit, handle and provide operations are recorded without publishing their effects through WU.

Comparison covers facade operations; it does not intercept every browser side effect. A direct fetch or external write performed by twin code remains that app responsibility. It also does not replay user clicks or prove visual layout equivalence.

Read the report

report().dom compares normalized trees without internal attributes; outputs compares recorded operations and arguments. equal means those comparisons found no differences. unmatchedCalls identifies calls without a match; after rpcTimeout they reject with WU_SHADOW_NO_TWIN_CALL. This is not automatic deployment approval.

start returns the first report; report returns the current report or null; stop releases the twin, hooks and waits and returns the final report. sessions lists sessions. The primary must be mounted; a second shadow fails with WU_SHADOW_EXISTS. The twin keeps primary grants and registers as <app>~shadow unless you configure name.

Intercept operations from the host

const release = wu.intercept('cart', (kind, args, next) => {
  if (kind === 'store.set') console.log('cart writes', args[0]);
  return next(...args);
});
// Remove the middleware when the host no longer needs it.
release();

intercept returns a cleanup function. next(...args) continues the operation; returning another result replaces it. Multiple interceptors run in registration order. Preserve the synchronous or asynchronous contract expected by the app.

The shadow report includes props.failures when a props update does not reach the twin. While those failures exist, equal is false; do not interpret a partial comparison as deployment equivalence.

BUILD WU WITH US

Found a bug? Have an idea?

Your experience improves WU. Tell us what went wrong or help support its development.