From harness-claude
Configures Webpack Module Federation for micro-frontends, enabling runtime module sharing, singleton shared dependencies like React, and version compatibility across independent apps.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Master module federation for micro-frontend architectures — runtime module sharing across independently deployed applications, shared dependency negotiation, version compatibility strategies, and performance optimization for federated systems.
Configures DataHub instance to register Micro Frontend (MFE) apps, load at /mfe/<path>, add to nav sidebar, setup local dev or production/Kubernetes config, troubleshoot loading issues.
Guides Webpack configuration for bundling JS/CSS/assets with loaders/plugins, code splitting, optimization, tree shaking, HMR dev server, and production builds.
Migrates monoliths to microservices incrementally using Strangler Fig pattern with facade routing, feature flags, and parallel-run validation for zero-downtime feature extraction.
Share bugs, ideas, or general feedback.
Master module federation for micro-frontend architectures — runtime module sharing across independently deployed applications, shared dependency negotiation, version compatibility strategies, and performance optimization for federated systems.
Configure the host application. The host (shell) application declares which remote modules it consumes and which dependencies it shares:
// webpack.config.js (host/shell)
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'shell',
remotes: {
catalog: 'catalog@https://catalog.example.com/remoteEntry.js',
checkout: 'checkout@https://checkout.example.com/remoteEntry.js',
account: 'account@https://account.example.com/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
'@company/design-system': {
singleton: true,
requiredVersion: '^3.0.0',
},
},
}),
],
};
Configure remote applications. Each remote exposes specific modules and declares its shared dependencies:
// webpack.config.js (catalog remote)
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'catalog',
filename: 'remoteEntry.js',
exposes: {
'./ProductList': './src/components/ProductList',
'./ProductDetail': './src/components/ProductDetail',
'./SearchBar': './src/components/SearchBar',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
'@company/design-system': {
singleton: true,
requiredVersion: '^3.0.0',
},
},
}),
],
};
Load remote modules dynamically. Use dynamic imports with error boundaries for resilient loading:
// In the host application
import { lazy, Suspense } from 'react';
import ErrorBoundary from './ErrorBoundary';
const RemoteProductList = lazy(() => import('catalog/ProductList'));
const RemoteCheckout = lazy(() => import('checkout/CheckoutFlow'));
function App() {
return (
<ErrorBoundary fallback={<FallbackCatalog />}>
<Suspense fallback={<ProductListSkeleton />}>
<RemoteProductList />
</Suspense>
</ErrorBoundary>
);
}
Configure shared dependency versioning. Prevent duplicate React instances while allowing compatible version ranges:
shared: {
react: {
singleton: true, // only one instance at runtime
strictVersion: false, // allow compatible versions
requiredVersion: '^18.0.0',
eager: false, // load asynchronously (default)
},
'lodash-es': {
singleton: false, // multiple versions OK
requiredVersion: '^4.17.0',
},
'@company/utils': {
singleton: true,
version: '2.5.0',
requiredVersion: '>=2.0.0 <3.0.0',
},
}
Implement dynamic remote loading. For scenarios where remote URLs are determined at runtime (feature flags, environment configuration):
// Dynamic remote container loading
async function loadRemote(scope: string, module: string, url: string) {
await loadScript(url);
const container = (window as any)[scope];
await container.init(__webpack_share_scopes__.default);
const factory = await container.get(module);
return factory();
}
function loadScript(url: string): Promise<void> {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.onload = () => resolve();
script.onerror = reject;
document.head.appendChild(script);
});
}
// Usage
const ProductList = lazy(() => loadRemote('catalog', './ProductList', getRemoteUrl('catalog')));
Set up health checks and fallbacks. Remote modules can fail to load due to network issues or deployment problems:
class FederationErrorBoundary extends React.Component {
state = { hasError: false, retryCount: 0 };
static getDerivedStateFromError() {
return { hasError: true };
}
handleRetry = () => {
this.setState(prev => ({
hasError: false,
retryCount: prev.retryCount + 1,
}));
};
render() {
if (this.state.hasError) {
if (this.state.retryCount < 3) {
return (
<div>
<p>Failed to load module. </p>
<button onClick={this.handleRetry}>Retry</button>
</div>
);
}
return this.props.fallback;
}
return this.props.children;
}
}
Monitor federation performance. Track remote entry load times and shared dependency negotiation overhead:
// Measure remote module load time
const start = performance.now();
const RemoteModule = await import('catalog/ProductList');
const duration = performance.now() - start;
performance.measure('federation:catalog:ProductList', {
start,
duration,
});
At build time, each federated application generates a remoteEntry.js manifest file that describes its exposed modules and shared dependency requirements. At runtime, the host loads the remote's manifest, negotiates shared dependencies (using the highest compatible version available), and lazily loads the requested module. The shared scope ensures that singleton libraries like React are loaded once and reused across all federated applications, preventing multiple React instance errors and reducing total download size.
When multiple federated applications declare different versions of a shared dependency, the runtime selects the highest version that satisfies all requiredVersion constraints. If no single version satisfies all constraints, the module that cannot be satisfied loads its own bundled version (unless strictVersion: true is set, which throws an error). The singleton: true flag ensures only one version is loaded globally — critical for libraries like React that break with multiple instances.
IKEA's web platform uses module federation to compose product browsing, cart, and checkout from independent applications maintained by separate teams. The shared dependency configuration ensures a single React instance (~40KB) and one design system (~60KB) are loaded regardless of how many micro-frontends are active. Each micro-frontend's remoteEntry.js is ~5KB and loads in <50ms. The total overhead of federation versus a monolithic build is approximately 15KB of runtime code, offset by the ability to deploy and cache each micro-frontend independently.
Sharing too many dependencies as singletons. Only libraries that break with multiple instances (React, React DOM, state management) should be singletons. Utility libraries (lodash, date-fns) can safely have multiple versions, and forcing them to singleton creates unnecessary version conflicts.
Missing error boundaries around remote modules. Without error boundaries, a failing remote crashes the entire host application. Every remote module should be wrapped in both an Error Boundary and a Suspense boundary with meaningful fallback UI.
Eager loading all shared dependencies. Setting eager: true on shared dependencies defeats the purpose of async loading. Only set eager on dependencies that must be available synchronously at bootstrap (rare). Default to eager: false.
Tight coupling between host and remotes. If the host directly imports TypeScript types from a remote's source code, the host depends on the remote at build time. Use shared interface packages published to npm, not direct source imports.