| null {
+ const { resetKeys = [] } = props;
+ const { prevResetKeys } = state;
+
+ // Reset error state if resetKeys have changed
+ if (state.hasError && resetKeys.some((key, idx) => key !== prevResetKeys[idx])) {
+ return {
+ hasError: false,
+ error: null,
+ errorInfo: null,
+ prevResetKeys: resetKeys
+ };
+ }
+
+ return { prevResetKeys: resetKeys };
+ }
+
+ componentDidCatch(error: Error, errorInfo: ErrorInfo) {
+ console.error('[ErrorBoundary] Caught an error:', error);
+ console.error('[ErrorBoundary] Error info:', errorInfo);
+
+ this.setState({
+ error,
+ errorInfo
+ });
+
+ // Call optional error handler
+ if (this.props.onError) {
+ this.props.onError(error, errorInfo);
+ }
+
+ // Log to external service if in production
+ if (process.env.NODE_ENV === 'production') {
+ this.logErrorToService(error, errorInfo);
+ }
+ }
+
+ componentWillUnmount() {
+ if (this.resetTimeoutId) {
+ clearTimeout(this.resetTimeoutId);
+ }
+ }
+
+ private logErrorToService(error: Error, errorInfo: ErrorInfo) {
+ // Implementation for logging to external error tracking service
+ // This could be Sentry, LogRocket, Bugsnag, etc.
+ console.log('[ErrorBoundary] Would log to error service:', { error, errorInfo });
+ }
+
+ private handleRetry = () => {
+ this.setState({
+ hasError: false,
+ error: null,
+ errorInfo: null
+ });
+ };
+
+ private handleAutoRetry = () => {
+ this.resetTimeoutId = window.setTimeout(() => {
+ // Check if component is still mounted before retrying
+ if (this.state.hasError) {
+ console.log('[ErrorBoundary] Auto-retrying after error...');
+ this.handleRetry();
+ }
+ }, 5000);
+ };
+
+ private renderDefaultFallback() {
+ const { error, errorInfo } = this.state;
+ const isModuleFederationError = error?.message?.includes('Loading') ||
+ error?.message?.includes('remote') ||
+ error?.name === 'ChunkLoadError';
+
+ return (
+
+
+ {isModuleFederationError ?
+ '🔌 Remote Module Loading Error' :
+ '⚠️ Something went wrong'
+ }
+
+
+
+ {isModuleFederationError ? (
+ <>This usually happens when a remote module is unavailable or the URL is incorrect.>
+ ) : (
+ <>An unexpected error occurred while rendering this component.>
+ )}
+
+
+
+
+ 🔄 Retry
+
+
+ {isModuleFederationError && (
+
+ ⏰ Auto-retry in 5s
+
+ )}
+
+
+ {process.env.NODE_ENV === 'development' && (
+
+
+ 🐛 Debug Information
+
+
+ Error: {error?.toString()}
+ {errorInfo?.componentStack && (
+ <>
+ {'\n\n'}Component Stack: {errorInfo.componentStack}
+ >
+ )}
+
+
+ )}
+
+ );
+ }
+
+ render() {
+ if (this.state.hasError) {
+ // Render custom fallback UI or default
+ return this.props.fallback || this.renderDefaultFallback();
+ }
+
+ return this.props.children;
+ }
+}
+
+/**
+ * Hook version of Error Boundary for functional components
+ * Note: This is a wrapper that uses the class-based ErrorBoundary
+ */
+export function withErrorBoundary(
+ Component: React.ComponentType
,
+ errorBoundaryProps?: Omit
+) {
+ const WrappedComponent = (props: P) => (
+
+
+
+ );
+
+ WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`;
+
+ return WrappedComponent;
+}
+
+export default ErrorBoundary;
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app1/src/index.js b/advanced-api/dynamic-remotes-synchronous-imports/app1/src/index.js
index 51623bd18f0..59ff5d5e0d1 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app1/src/index.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app1/src/index.js
@@ -1,5 +1,38 @@
+/**
+ * Dynamic Remote URL Initialization
+ *
+ * This file demonstrates how to set up global variables that the runtime plugin
+ * will use to dynamically resolve remote URLs while maintaining synchronous imports.
+ */
+
import { app2Module } from '../../moduleConfig';
+// Set up the global variable that the runtime plugin will check
+// This allows dynamic URL resolution at runtime
window[app2Module.urlGlobalVariable] = app2Module.url;
-import('./bootstrap');
+console.log(`[Dynamic Remote Init] Setting ${app2Module.urlGlobalVariable} to:`, app2Module.url);
+
+// Example: You could dynamically change this based on environment or user settings
+// window.app2Url = process.env.REACT_APP_REMOTE_URL || app2Module.url;
+
+// You could also set multiple remotes dynamically:
+// window.app3Url = '//different-host:4001';
+// window.app4Url = '//cdn.example.com/remotes';
+
+// Bootstrap the application after setting up dynamic configurations
+import('./bootstrap').catch(error => {
+ console.error('[Dynamic Remote Init] Failed to bootstrap application:', error);
+
+ // Optionally show user-friendly error message
+ document.body.innerHTML = `
+
+
Application Failed to Load
+
Unable to initialize the application. Please check the console for details.
+
+ Error Details
+ ${error.message}
+
+
+ `;
+});
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app1/src/types/module-federation.d.ts b/advanced-api/dynamic-remotes-synchronous-imports/app1/src/types/module-federation.d.ts
new file mode 100644
index 00000000000..7c3ce31d53b
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app1/src/types/module-federation.d.ts
@@ -0,0 +1,86 @@
+/**
+ * Type definitions for Module Federation dynamic remotes
+ */
+
+declare module 'app2/Widget' {
+ import { ComponentType } from 'react';
+ const WidgetRemote: ComponentType;
+ export default WidgetRemote;
+}
+
+// Global window extensions for dynamic remote URL configuration
+declare global {
+ interface Window {
+ /**
+ * Global variable for app2 remote URL
+ * Set this before the application loads to dynamically configure the remote URL
+ */
+ app2Url?: string;
+
+ /**
+ * Fallback URL for app2 remote
+ * Used when the primary URL fails to load
+ */
+ app2FallbackUrl?: string;
+
+ /**
+ * Module Federation debugging utilities
+ */
+ __MF_DEBUG__?: {
+ getDynamicRemotePluginState?: () => {
+ resolvedUrls: Record;
+ failedRemotes: string[];
+ retryAttempts: Record;
+ } | null;
+ };
+
+ /**
+ * Internal Module Federation plugin state (for debugging)
+ */
+ __MF_PLUGIN_STATE__?: () => {
+ resolvedUrls: Record;
+ failedRemotes: string[];
+ retryAttempts: Record;
+ };
+ }
+}
+
+/**
+ * Module Federation runtime plugin types
+ */
+export interface ModuleFederationRuntimePlugin {
+ name: string;
+ version?: string;
+ init?: (args: any) => any;
+ beforeRequest?: (args: BeforeRequestArgs) => BeforeRequestArgs;
+ afterResolve?: (args: any) => any;
+ errorLoadRemote?: (args: ErrorLoadRemoteArgs) => any;
+ getPluginState?: () => PluginState;
+}
+
+export interface BeforeRequestArgs {
+ id: string;
+ options: {
+ remotes: RemoteConfig[];
+ };
+}
+
+export interface RemoteConfig {
+ name: string;
+ entry: string;
+ [key: string]: any;
+}
+
+export interface ErrorLoadRemoteArgs {
+ id: string;
+ error: Error | string;
+ origin?: string;
+}
+
+export interface PluginState {
+ resolvedUrls: Record;
+ failedRemotes: string[];
+ retryAttempts: Record;
+}
+
+export {};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app1/tsconfig.json b/advanced-api/dynamic-remotes-synchronous-imports/app1/tsconfig.json
new file mode 100644
index 00000000000..209cb11c2b6
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app1/tsconfig.json
@@ -0,0 +1,32 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src/**/*",
+ "runtimePlugin.js",
+ "../moduleConfig.js"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app1/webpack.config.js b/advanced-api/dynamic-remotes-synchronous-imports/app1/webpack.config.js
index 4301b41c248..8cd1feb2475 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app1/webpack.config.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app1/webpack.config.js
@@ -1,35 +1,30 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require('@module-federation/enhanced');
-const path = require('path');
-const deps = require('./package.json').dependencies;
const { app2Module, app1Module } = require('../moduleConfig');
+const deps = require('./package.json').dependencies;
module.exports = {
- entry: ['./src/index'],
+ entry: './src/index',
mode: 'development',
- target: 'web',
devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
+ port: app1Module.port,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
},
- port: app1Module.port,
},
- output: {
- publicPath: 'auto',
+ resolve: {
+ extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
},
module: {
rules: [
{
- test: /\.jsx?$/,
+ test: /\.(js|jsx|ts|tsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
- presets: ['@babel/preset-react'],
+ presets: ['@babel/preset-react', '@babel/preset-typescript'],
},
},
],
@@ -39,7 +34,7 @@ module.exports = {
name: app1Module.name,
filename: app1Module.fileName,
remotes: {
- app2: app2Module.federationConfig,
+ app2: 'app2@//localhost:3002/remoteEntry.js',
},
runtimePlugins: [require.resolve('./runtimePlugin.js')],
shared: {
@@ -61,4 +56,4 @@ module.exports = {
template: './public/index.html',
}),
],
-};
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app2/package.json b/advanced-api/dynamic-remotes-synchronous-imports/app2/package.json
index e4de469391f..434327fb8c3 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app2/package.json
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app2/package.json
@@ -4,10 +4,14 @@
"devDependencies": {
"@babel/core": "7.24.7",
"@babel/preset-react": "7.24.7",
+ "@babel/preset-typescript": "^7.24.7",
"@module-federation/enhanced": "0.17.1",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
"babel-loader": "9.1.3",
"html-webpack-plugin": "5.6.0",
"serve": "14.2.3",
+ "typescript": "^5.5.3",
"webpack": "5.101.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4"
@@ -20,8 +24,8 @@
},
"dependencies": {
"moment": "^2.29.4",
- "react": "^16.13.0",
- "react-dom": "^16.13.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
"react-redux": "^7.2.0",
"redux": "^4.2.1"
}
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app2/src/App.js b/advanced-api/dynamic-remotes-synchronous-imports/app2/src/App.js
index 940f914e63c..68b916ef536 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app2/src/App.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app2/src/App.js
@@ -3,7 +3,7 @@ import React from 'react';
const App = () => (
-
Dynamic System Host
+ 🌐 Dynamic System Host
App 2
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app2/src/Widget.js b/advanced-api/dynamic-remotes-synchronous-imports/app2/src/Widget.js
index b6186724b42..2e55a645e66 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app2/src/Widget.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app2/src/Widget.js
@@ -1,22 +1,232 @@
-import React from 'react';
+import React, { useState, useEffect, useRef } from 'react';
import moment from 'moment';
+/**
+ * Enhanced remote Widget component for App 2
+ *
+ * This component is exposed via Module Federation and consumed by other applications.
+ *
+ * Demonstrates:
+ * - Remote component with modern React patterns
+ * - Shared dependency usage (moment.js)
+ * - State management and effects in federated components
+ * - Performance optimizations
+ * - Accessibility features
+ * - Error resilience
+ */
export default function Widget() {
+ const [loadTime] = useState(() => new Date().toLocaleTimeString());
+ const [isVisible, setIsVisible] = useState(false);
+ const [clickCount, setClickCount] = useState(0);
+ const [currentTime, setCurrentTime] = useState(() => moment());
+ const [isRunning, setIsRunning] = useState(true);
+ const intervalRef = useRef();
+
+ useEffect(() => {
+ // Animate in after mount
+ const timer = setTimeout(() => setIsVisible(true), 200);
+ return () => clearTimeout(timer);
+ }, []);
+
+ useEffect(() => {
+ // Update time every second when running
+ if (isRunning) {
+ intervalRef.current = setInterval(() => {
+ setCurrentTime(moment());
+ }, 1000);
+ } else {
+ if (intervalRef.current) {
+ clearInterval(intervalRef.current);
+ }
+ }
+
+ return () => {
+ if (intervalRef.current) {
+ clearInterval(intervalRef.current);
+ }
+ };
+ }, [isRunning]);
+
+ const handleInteraction = () => {
+ setClickCount(prev => prev + 1);
+ };
+
+ const toggleTimer = () => {
+ setIsRunning(prev => !prev);
+ };
+
+ const formatTimeZone = () => {
+ return moment().format('Z');
+ };
+
return (
e.key === 'Enter' && handleInteraction()}
+ tabIndex={0}
+ role="button"
+ aria-label="Remote widget from App 2"
>
-
App 2 Widget
-
- Using momentjs for format the date
-
-
{moment().format('MMMM Do YYYY, h:mm:ss a')}
+ {/* Animated background effect */}
+
+
+
+
+
+ 🔌 App 2 Remote Widget
+
+
+
+ Loaded: {loadTime}
+
+
+
+
+ This is a remote component from App 2, federated via Module Federation.
+ It demonstrates dynamic loading with synchronous import syntax.
+
+
+
+
+
+ 📅 Live Time (via shared moment.js):
+
+
{
+ e.stopPropagation();
+ toggleTimer();
+ }}
+ style={{
+ background: 'rgba(255, 255, 255, 0.2)',
+ color: 'white',
+ border: 'none',
+ padding: '4px 8px',
+ borderRadius: '4px',
+ fontSize: '10px',
+ cursor: 'pointer'
+ }}
+ aria-label={isRunning ? 'Pause timer' : 'Start timer'}
+ >
+ {isRunning ? '⏸️ Pause' : '▶️ Start'}
+
+
+
+
+ {currentTime.format('MMMM Do YYYY, h:mm:ss a')}
+
+
+
+ Timezone: {formatTimeZone()}
+
+
+
+
+
+ 🖱️ Interactions: {clickCount}
+
+
+
+
+ {isRunning ? '🟢 LIVE' : '🔴 PAUSED'}
+
+
+
+ REMOTE
+
+
+
+
+ {clickCount > 0 && (
+
+ 🎉 Remote component interaction successful!
+ This proves the federated module is working correctly.
+
+ )}
+
);
}
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app2/src/bootstrap.js b/advanced-api/dynamic-remotes-synchronous-imports/app2/src/bootstrap.js
index a8680f71cdf..a68d81c41fd 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app2/src/bootstrap.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app2/src/bootstrap.js
@@ -1,5 +1,8 @@
import App from './App';
import React from 'react';
-import ReactDOM from 'react-dom';
+import { createRoot } from 'react-dom/client';
-ReactDOM.render( , document.getElementById('root'));
+// Using React 18 createRoot API for better performance and concurrent features
+const container = document.getElementById('root');
+const root = createRoot(container);
+root.render( );
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app2/tsconfig.json b/advanced-api/dynamic-remotes-synchronous-imports/app2/tsconfig.json
new file mode 100644
index 00000000000..067ccdcef2a
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app2/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src/**/*",
+ "../moduleConfig.js"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/app2/webpack.config.js b/advanced-api/dynamic-remotes-synchronous-imports/app2/webpack.config.js
index 839012280dd..32cd524a812 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/app2/webpack.config.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/app2/webpack.config.js
@@ -1,6 +1,5 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
-const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;
-const path = require('path');
+const { ModuleFederationPlugin } = require('@module-federation/enhanced');
const { app2Module } = require('../moduleConfig');
const deps = require('./package.json').dependencies;
@@ -8,19 +7,12 @@ module.exports = {
entry: './src/index',
mode: 'development',
devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
+ port: app2Module.port,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
},
- port: app2Module.port,
- },
- target: 'web',
- output: {
- publicPath: 'auto',
},
module: {
rules: [
@@ -42,10 +34,6 @@ module.exports = {
exposes: {
'./Widget': './src/Widget',
},
- // adds react as shared module
- // version is inferred from package.json
- // there is no version check for the required version
- // so it will always use the higher version found
shared: {
react: {
requiredVersion: deps.react,
@@ -68,4 +56,4 @@ module.exports = {
template: './public/index.html',
}),
],
-};
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/e2e/checkDynamicRemotesSynchImportApps.spec.ts b/advanced-api/dynamic-remotes-synchronous-imports/e2e/checkDynamicRemotesSynchImportApps.spec.ts
new file mode 100644
index 00000000000..db7ca0328e8
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/e2e/checkDynamicRemotesSynchImportApps.spec.ts
@@ -0,0 +1,325 @@
+import { test, expect, Page } from '@playwright/test';
+
+// Helper functions
+async function openLocalhost(page: Page, port: number) {
+ await page.goto(`http://localhost:${port}`);
+ await page.waitForLoadState('networkidle');
+}
+
+async function checkElementWithTextPresence(page: Page, selector: string, text: string, timeout: number = 10000) {
+ // Use getByText for exact text matching to avoid conflicts with partial matches
+ await page.locator(selector).filter({ hasText: new RegExp(`^${text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`) }).first().waitFor({ timeout });
+}
+
+async function checkElementVisibility(page: Page, selector: string, timeout: number = 10000) {
+ await page.locator(selector).waitFor({ state: 'visible', timeout });
+}
+
+async function checkElementBackgroundColor(page: Page, selector: string, expectedColor: string) {
+ const element = page.locator(selector);
+ await element.waitFor({ state: 'visible' });
+ const backgroundColor = await element.evaluate((el) => {
+ return window.getComputedStyle(el).backgroundColor;
+ });
+ if (backgroundColor !== expectedColor) {
+ throw new Error(`Expected background color ${expectedColor}, but got ${backgroundColor}`);
+ }
+}
+
+async function clickElementWithText(page: Page, selector: string, text: string) {
+ await page.locator(selector).filter({ hasText: text }).click();
+}
+
+async function waitForDynamicImport(page: Page, timeout: number = 5000) {
+ // Wait for any dynamic imports to complete
+ await page.waitForTimeout(1000);
+ await page.waitForLoadState('networkidle', { timeout });
+}
+
+async function checkDateFormat(page: Page) {
+ // Check for moment.js formatted date (MMMM Do YYYY, h:mm format)
+ const dateElement = page.locator('text=/[A-Z][a-z]+ \\\\d{1,2}[a-z]{2} \\\\d{4}, \\\\d{1,2}:\\\\d{2}/');
+ await dateElement.waitFor({ timeout: 5000 });
+}
+
+const appsData = [
+ {
+ headerSelector: 'h1',
+ subHeaderSelector: 'h2',
+ headerText: '🌐 Dynamic System Host',
+ appNameText: 'App 1 - Demonstrating Synchronous Imports with Dynamic Remotes',
+ widgetName: ['App 1 Widget', 'App 2 Widget'],
+ widgetParagraph: ["Moment shouldn't download twice", "Moment shouldn't download twice"],
+ widgetColor: ['rgb(255, 0, 0)', 'rgb(0, 0, 255)'],
+ widgetIndexNumber: 1,
+ isTwoWidgets: true,
+ host: 3001,
+ },
+ {
+ headerSelector: 'h1',
+ subHeaderSelector: 'h2',
+ headerText: '🌐 Dynamic System Host',
+ appNameText: 'App 2',
+ widgetName: ['App 1 Widget', 'App 2 Widget'],
+ widgetParagraph: ["Moment shouldn't download twice", "Moment shouldn't download twice"],
+ widgetColor: ['rgb(255, 0, 0)', 'rgb(0, 0, 255)'],
+ widgetIndexNumber: 2,
+ isTwoWidgets: false,
+ host: 3002,
+ },
+];
+
+test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
+
+ appsData.forEach((appData) => {
+ const { host, appNameText, headerText, widgetName, widgetParagraph, widgetColor, widgetIndexNumber, isTwoWidgets } = appData;
+
+ test.describe(`Check ${appNameText}`, () => {
+ test(`should display ${appNameText} elements correctly`, async ({ page }) => {
+ const consoleErrors: string[] = [];
+ page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await openLocalhost(page, host);
+
+ // Check header and subheader exist
+ await checkElementWithTextPresence(
+ page,
+ appData.headerSelector,
+ headerText
+ );
+ await checkElementWithTextPresence(
+ page,
+ appData.subHeaderSelector,
+ appNameText
+ );
+
+ // Verify no critical console errors
+ const criticalErrors = consoleErrors.filter(error =>
+ error.includes('Failed to fetch') ||
+ error.includes('ChunkLoadError') ||
+ error.includes('Module not found') ||
+ (error.includes('TypeError') && !error.includes('DevTools'))
+ );
+ expect(criticalErrors).toHaveLength(0);
+ });
+
+ test(`should display widgets correctly in ${appNameText}`, async ({ page }) => {
+ await openLocalhost(page, host);
+
+ if (isTwoWidgets) {
+ // App 1 has two widgets (local + remote)
+ for (let i = 0; i < widgetName.length; i++) {
+ const widgetSelector = i === 0 ? '[data-e2e="WIDGET__1"]' : '[data-e2e="WIDGET__2"]';
+
+ // Check widget visibility
+ await checkElementVisibility(page, widgetSelector);
+
+ // Check widget title
+ await checkElementWithTextPresence(
+ page,
+ appData.subHeaderSelector,
+ widgetName[i]
+ );
+
+ // Check widget paragraph text
+ await checkElementWithTextPresence(
+ page,
+ 'p',
+ widgetParagraph[i]
+ );
+
+ // Check moment.js date formatting
+ await checkDateFormat(page);
+
+ // Check widget background color
+ await checkElementBackgroundColor(page, widgetSelector, widgetColor[i]);
+ }
+ } else {
+ // App 2 has one widget
+ const widgetSelector = '[data-e2e="WIDGET__2"]';
+
+ // Check widget visibility
+ await checkElementVisibility(page, widgetSelector);
+
+ // Check widget title
+ await checkElementWithTextPresence(
+ page,
+ appData.subHeaderSelector,
+ widgetName[widgetIndexNumber - 1]
+ );
+
+ // Check widget paragraph text
+ await checkElementWithTextPresence(
+ page,
+ 'p',
+ widgetParagraph[widgetIndexNumber - 1]
+ );
+
+ // Check moment.js date formatting
+ await checkDateFormat(page);
+
+ // Check widget background color
+ await checkElementBackgroundColor(page, widgetSelector, widgetColor[1]);
+ }
+ });
+ });
+ });
+
+ test.describe('Synchronous Import Pattern Tests', () => {
+ test('should demonstrate synchronous imports with dynamic URL resolution', async ({ page }) => {
+ const consoleMessages: string[] = [];
+ page.on('console', (msg) => {
+ if (msg.type() === 'log' && msg.text().includes('get-remote-from-window-plugin')) {
+ consoleMessages.push(msg.text());
+ }
+ });
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Should have runtime plugin logs indicating dynamic URL resolution
+ const runtimePluginLogs = consoleMessages.filter(msg =>
+ msg.includes('app2Url') || msg.includes('get-remote-from-window-plugin')
+ );
+
+ // Verify runtime plugin is working for dynamic URL resolution
+ expect(runtimePluginLogs.length).toBeGreaterThan(0);
+ });
+
+ test('should load remote modules synchronously', async ({ page }) => {
+ const networkRequests: string[] = [];
+
+ page.on('request', (request) => {
+ networkRequests.push(request.url());
+ });
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Check that App 2 widget is loaded synchronously (no dynamic import button clicks)
+ await page.waitForSelector('[data-e2e="WIDGET__2"]', { timeout: 10000 });
+
+ // Verify the remote entry was loaded
+ const remoteEntryRequests = networkRequests.filter(url =>
+ url.includes('localhost:3002') && url.includes('remoteEntry.js')
+ );
+
+ expect(remoteEntryRequests.length).toBeGreaterThan(0);
+ });
+
+ test('should handle runtime URL modification correctly', async ({ page }) => {
+ // Monitor for URL resolution in runtime plugin
+ const consoleMessages: string[] = [];
+ page.on('console', (msg) => {
+ consoleMessages.push(msg.text());
+ });
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Verify both widgets are present (demonstrating successful remote loading)
+ await page.waitForSelector('[data-e2e="WIDGET__1"]');
+ await page.waitForSelector('[data-e2e="WIDGET__2"]');
+
+ // Check that runtime plugin logged URL processing
+ const urlResolutionLogs = consoleMessages.filter(msg =>
+ msg.includes('app2Url') || msg.includes('beforeRequest')
+ );
+
+ expect(urlResolutionLogs.length).toBeGreaterThan(0);
+ });
+ });
+
+ test.describe('Module Federation Features', () => {
+ test('should efficiently share dependencies between applications', async ({ page }) => {
+ const networkRequests: string[] = [];
+
+ page.on('request', (request) => {
+ networkRequests.push(request.url());
+ });
+
+ // Navigate to host (loads both local and remote widgets synchronously)
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Navigate to remote standalone
+ await page.goto('http://localhost:3002');
+ await page.waitForLoadState('networkidle');
+
+ // Verify React is shared efficiently
+ const reactRequests = networkRequests.filter(url =>
+ url.includes('react') && !url.includes('react-dom')
+ );
+ expect(reactRequests.length).toBeLessThan(8);
+
+ // Verify moment.js is shared between remotes
+ const momentRequests = networkRequests.filter(url => url.includes('moment'));
+ expect(momentRequests.length).toBeLessThan(5);
+ });
+
+ test('should handle CORS correctly for federated modules', async ({ page }) => {
+ const corsErrors: string[] = [];
+ page.on('response', (response) => {
+ if (response.status() >= 400 && response.url().includes('localhost:300')) {
+ corsErrors.push(`${response.status()} - ${response.url()}`);
+ }
+ });
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Should have no CORS errors
+ expect(corsErrors).toHaveLength(0);
+ });
+
+ test('should demonstrate moment.js sharing', async ({ page }) => {
+ await openLocalhost(page, 3001);
+
+ // Check that moment.js date is formatted correctly in both widgets
+ const dateElements = page.locator('text=/[A-Z][a-z]+ \\d{1,2}[a-z]{2} \\d{4}, \\d{1,2}:\\d{2}/');
+
+ // Should have date formatting in both local and remote widgets
+ await expect(dateElements).toHaveCount(2);
+ });
+ });
+
+ test.describe('Error Handling and Resilience', () => {
+ test('should handle missing window variables gracefully', async ({ page }) => {
+ const consoleErrors: string[] = [];
+ page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Should handle any missing window variables gracefully
+ const criticalErrors = consoleErrors.filter(error =>
+ error.includes('Uncaught') &&
+ !error.includes('webpack-dev-server') &&
+ !error.includes('DevTools') &&
+ !error.includes('Warning:')
+ );
+ expect(criticalErrors).toHaveLength(0);
+ });
+
+ test('should maintain application stability during remote loading', async ({ page }) => {
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Verify main application elements remain stable
+ await page.waitForSelector('h1:has-text("Dynamic System Host")');
+ await page.waitForSelector('h2:has-text("App 1")');
+
+ // Verify both widgets loaded successfully
+ await page.waitForSelector('[data-e2e="WIDGET__1"]');
+ await page.waitForSelector('[data-e2e="WIDGET__2"]');
+ });
+ });
+});
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/base-test.ts b/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/base-test.ts
new file mode 100644
index 00000000000..2ef9807d630
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/base-test.ts
@@ -0,0 +1,65 @@
+import { Page } from '@playwright/test';
+
+export class BasePage {
+ constructor(public page: Page) {}
+
+ async openLocalhost(port: number) {
+ await this.page.goto(`http://localhost:${port}`);
+ await this.page.waitForLoadState('networkidle');
+ }
+
+ async checkElementWithTextPresence(selector: string, text: string, timeout: number = 10000) {
+ await this.page.locator(selector).filter({ hasText: text }).waitFor({ timeout });
+ }
+
+ async checkElementVisibility(selector: string, timeout: number = 10000) {
+ await this.page.locator(selector).waitFor({ state: 'visible', timeout });
+ }
+
+ async checkElementBackgroundColor(selector: string, expectedColor: string) {
+ const element = this.page.locator(selector);
+ await element.waitFor({ state: 'visible' });
+ const backgroundColor = await element.evaluate((el) => {
+ return window.getComputedStyle(el).backgroundColor;
+ });
+ if (backgroundColor !== expectedColor) {
+ throw new Error(`Expected background color ${expectedColor}, but got ${backgroundColor}`);
+ }
+ }
+
+ async clickElementWithText(selector: string, text: string) {
+ await this.page.locator(selector).filter({ hasText: text }).click();
+ }
+
+ async waitForDynamicImport(timeout: number = 5000) {
+ // Wait for any dynamic imports to complete
+ await this.page.waitForTimeout(1000);
+ await this.page.waitForLoadState('networkidle', { timeout });
+ }
+
+ async checkDateFormat() {
+ // Check for moment.js formatted date (MMMM Do YYYY, h:mm format)
+ const dateElement = this.page.locator('text=/[A-Z][a-z]+ \\d{1,2}[a-z]{2} \\d{4}, \\d{1,2}:\\d{2}/');
+ await dateElement.waitFor({ timeout: 5000 });
+ }
+
+ getDateWithFormat(): string {
+ // Get current date in moment.js format: "MMMM Do YYYY, h:mm"
+ const now = new Date();
+ const months = ['January', 'February', 'March', 'April', 'May', 'June',
+ 'July', 'August', 'September', 'October', 'November', 'December'];
+
+ const day = now.getDate();
+ const suffix = day === 1 || day === 21 || day === 31 ? 'st' :
+ day === 2 || day === 22 ? 'nd' :
+ day === 3 || day === 23 ? 'rd' : 'th';
+
+ const month = months[now.getMonth()];
+ const year = now.getFullYear();
+ const hour = now.getHours() % 12 || 12;
+ const minute = now.getMinutes().toString().padStart(2, '0');
+
+ return `${month} ${day}${suffix} ${year}, ${hour}:${minute}`;
+ }
+}
+
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/constants.ts b/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/constants.ts
new file mode 100644
index 00000000000..3533a24a590
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/constants.ts
@@ -0,0 +1,25 @@
+export const Constants = {
+ elementsText: {
+ dynamicRemotesApp: {
+ header: '🌐 Dynamic System Host',
+ synchronousImportWidgetsNames: ['App 1 Widget', 'App 2 Widget'],
+ },
+ },
+ commonConstantsData: {
+ commonCountAppNames: {
+ app1: 'App 1 - Demonstrating Synchronous Imports with Dynamic Remotes',
+ app2: 'App 2',
+ },
+ },
+ commonPhrases: {
+ dynamicRemotesApp: {
+ widgetParagraphText: [
+ "Moment shouldn't download twice",
+ "Moment shouldn't download twice"
+ ],
+ },
+ },
+ color: {
+ dynamicRemotesWidgetColor: ['rgb(255, 0, 0)', 'rgb(0, 0, 255)'],
+ },
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/selectors.ts b/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/selectors.ts
new file mode 100644
index 00000000000..8b62786ec6d
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/e2e/utils/selectors.ts
@@ -0,0 +1,13 @@
+export const selectors = {
+ dataTestIds: {
+ app1Widget: '[data-e2e="WIDGET__1"]',
+ app2Widget: '[data-e2e="WIDGET__2"]',
+ },
+ tags: {
+ headers: {
+ h1: 'h1',
+ h2: 'h2',
+ },
+ paragraph: 'p',
+ },
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/moduleConfig.js b/advanced-api/dynamic-remotes-synchronous-imports/moduleConfig.js
index 1a0a6dbafcd..72d690ce634 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/moduleConfig.js
+++ b/advanced-api/dynamic-remotes-synchronous-imports/moduleConfig.js
@@ -1,28 +1,264 @@
+/**
+ * Enhanced Module Federation Configuration
+ *
+ * This configuration demonstrates advanced patterns for dynamic remote URL resolution
+ * while maintaining synchronous imports. Features include:
+ * - Dynamic URL resolution via window variables
+ * - Fallback URL support for resilience
+ * - Environment-based configuration
+ * - Multi-environment support (dev, staging, prod)
+ * - CDN and local development support
+ */
+
const moduleFileName = 'remoteEntry.js';
-// Host module
-const app1Module = {
- fileName: moduleFileName,
- name: 'app1',
- port: 3001,
+/**
+ * Environment detection and configuration
+ */
+const getEnvironment = () => {
+ if (typeof window !== 'undefined') {
+ return window.location.hostname === 'localhost' ? 'development' : 'production';
+ }
+ return process.env.NODE_ENV || 'development';
};
-// Remote module
-const app2Module = {
- fileName: moduleFileName,
- name: 'app2',
- port: 3002,
+/**
+ * Base configuration class for modules
+ */
+class ModuleConfig {
+ constructor(name, port, options = {}) {
+ this.name = name;
+ this.port = port;
+ this.fileName = options.fileName || moduleFileName;
+ this.environment = getEnvironment();
+ this.cdnUrl = options.cdnUrl;
+ this.stagingUrl = options.stagingUrl;
+ }
+
+ /**
+ * Get the base URL for this module based on environment
+ */
get url() {
+ switch (this.environment) {
+ case 'production':
+ return this.cdnUrl || `//cdn.example.com/${this.name}`;
+ case 'staging':
+ return this.stagingUrl || `//staging.example.com/${this.name}`;
+ default:
+ return `//localhost:${this.port}`;
+ }
+ }
+
+ /**
+ * Get development URL (always localhost)
+ */
+ get devUrl() {
return `//localhost:${this.port}`;
- },
+ }
+
+ /**
+ * Get the full remote entry URL
+ */
+ get remoteEntryUrl() {
+ return `${this.url}/${this.fileName}`;
+ }
+}
+
+// Host module configuration
+const app1Module = new ModuleConfig('app1', 3001, {
+ cdnUrl: '//cdn.example.com/app1',
+ stagingUrl: '//staging.example.com/app1'
+});
+
+// Remote module configuration with enhanced features
+const app2Module = new ModuleConfig('app2', 3002, {
+ cdnUrl: '//cdn.example.com/app2',
+ stagingUrl: '//staging.example.com/app2'
+});
+
+// Add dynamic configuration methods
+Object.assign(app2Module, {
+ /**
+ * Global variable name that the runtime plugin will check
+ * The plugin looks for window[urlGlobalVariable] to override the URL
+ */
urlGlobalVariable: 'app2Url',
+
+ /**
+ * Fallback global variable name for resilience
+ */
+ fallbackGlobalVariable: 'app2FallbackUrl',
+
+ /**
+ * Federation configuration string with placeholder syntax
+ * Format: remoteName@[window.globalVariableName]/remoteEntry.js
+ *
+ * The enhanced runtime plugin will:
+ * 1. Look for window.app2Url (primary)
+ * 2. If not found, look for window.app2FallbackUrl (fallback)
+ * 3. If neither found, use the default URL
+ * 4. Implement retry logic for failed loads
+ *
+ * This pattern enables resilient dynamic URL resolution while keeping synchronous imports
+ */
get federationConfig() {
- // app2@[window.app2Url]/remoteEntry.js
return `${this.name}@[window.${this.urlGlobalVariable}]/${this.fileName}`;
},
+
+ /**
+ * Configuration with fallback support
+ * Uses the fallback URL if the primary fails
+ */
+ get federationConfigWithFallback() {
+ return `${this.name}@[window.${this.fallbackGlobalVariable}]/${this.fileName}`;
+ },
+
+ /**
+ * Static configuration for development (no dynamic resolution)
+ * Useful for local development when you want predictable URLs
+ */
+ get federationConfigStatic() {
+ return `${this.name}@${this.devUrl}/${this.fileName}`;
+ },
+
+ /**
+ * Get all possible URLs for this remote (for debugging/monitoring)
+ */
+ getAllPossibleUrls() {
+ const urls = {
+ development: this.devUrl,
+ static: `${this.devUrl}/${this.fileName}`,
+ federationConfig: this.federationConfig
+ };
+
+ if (this.stagingUrl) {
+ urls.staging = `${this.stagingUrl}/${this.fileName}`;
+ }
+
+ if (this.cdnUrl) {
+ urls.production = `${this.cdnUrl}/${this.fileName}`;
+ }
+
+ // Add runtime URLs if available
+ if (typeof window !== 'undefined') {
+ if (window[this.urlGlobalVariable]) {
+ urls.runtimePrimary = `${window[this.urlGlobalVariable]}/${this.fileName}`;
+ }
+ if (window[this.fallbackGlobalVariable]) {
+ urls.runtimeFallback = `${window[this.fallbackGlobalVariable]}/${this.fileName}`;
+ }
+ }
+
+ return urls;
+ }
+});
+
+/**
+ * Utility functions for dynamic remote configuration
+ */
+const configUtils = {
+ /**
+ * Set up dynamic URLs for all remotes
+ * Call this before your application starts to configure remote URLs
+ *
+ * @param {Object} remoteUrls - Object mapping remote names to URLs
+ * @example
+ * configUtils.setupDynamicUrls({
+ * app2: '//production-server.com/app2',
+ * app3: '//another-server.com/app3'
+ * });
+ */
+ setupDynamicUrls(remoteUrls) {
+ if (typeof window === 'undefined') {
+ console.warn('[Module Config] Cannot setup dynamic URLs in non-browser environment');
+ return;
+ }
+
+ Object.entries(remoteUrls).forEach(([remoteName, url]) => {
+ const globalVarName = `${remoteName}Url`;
+ window[globalVarName] = url;
+ console.log(`[Module Config] Set ${globalVarName} = ${url}`);
+ });
+ },
+
+ /**
+ * Set up fallback URLs for resilience
+ *
+ * @param {Object} fallbackUrls - Object mapping remote names to fallback URLs
+ */
+ setupFallbackUrls(fallbackUrls) {
+ if (typeof window === 'undefined') {
+ console.warn('[Module Config] Cannot setup fallback URLs in non-browser environment');
+ return;
+ }
+
+ Object.entries(fallbackUrls).forEach(([remoteName, url]) => {
+ const globalVarName = `${remoteName}FallbackUrl`;
+ window[globalVarName] = url;
+ console.log(`[Module Config] Set fallback ${globalVarName} = ${url}`);
+ });
+ },
+
+ /**
+ * Get current configuration for debugging
+ */
+ getCurrentConfig() {
+ return {
+ environment: getEnvironment(),
+ app1: {
+ ...app1Module,
+ currentUrl: app1Module.url
+ },
+ app2: {
+ ...app2Module,
+ currentUrl: app2Module.url,
+ allUrls: app2Module.getAllPossibleUrls()
+ }
+ };
+ },
+
+ /**
+ * Validate remote URLs for common issues
+ */
+ validateConfiguration() {
+ const issues = [];
+
+ // Check if required ports are configured
+ if (app1Module.port === app2Module.port) {
+ issues.push('app1 and app2 are using the same port');
+ }
+
+ // Check if global variables are set when needed
+ if (typeof window !== 'undefined') {
+ const primaryUrl = window[app2Module.urlGlobalVariable];
+ const fallbackUrl = window[app2Module.fallbackGlobalVariable];
+
+ if (!primaryUrl && !fallbackUrl) {
+ issues.push(`Neither ${app2Module.urlGlobalVariable} nor ${app2Module.fallbackGlobalVariable} is set`);
+ }
+ }
+
+ return {
+ isValid: issues.length === 0,
+ issues
+ };
+ }
};
+// Export configuration and utilities
module.exports = {
app1Module,
app2Module,
+ configUtils,
+ getEnvironment,
+ ModuleConfig
};
+
+// Make utilities available globally for debugging
+if (typeof window !== 'undefined') {
+ window.__MF_CONFIG__ = {
+ ...module.exports,
+ getCurrentConfig: configUtils.getCurrentConfig,
+ validateConfiguration: configUtils.validateConfiguration
+ };
+}
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/package.json b/advanced-api/dynamic-remotes-synchronous-imports/package.json
index 1058175297a..dd2e28ef70b 100644
--- a/advanced-api/dynamic-remotes-synchronous-imports/package.json
+++ b/advanced-api/dynamic-remotes-synchronous-imports/package.json
@@ -11,9 +11,11 @@
"build": "pnpm --filter dynamic-remotes-synchronous-imports_app* --parallel build",
"serve": "pnpm --filter dynamic-remotes-synchronous-imports_app* --parallel serve",
"clean": "pnpm --filter dynamic-remotes-synchronous-imports_app* --parallel clean",
- "e2e:ci": "pnpm start & wait-on http-get://localhost:3001/ && npx cypress run --config-file ../../cypress-e2e/config/cypress.config.ts --config '{\"supportFile\": \"../../cypress-e2e/support/e2e.ts\"}' --spec \"./e2e/*.cy.ts\" --browser=chrome"
+ "e2e:ci": "npx playwright test",
+ "legacy:e2e:ci": "npx playwright test"
},
"devDependencies": {
+ "@playwright/test": "^1.54.2",
"wait-on": "7.2.0"
}
}
diff --git a/advanced-api/dynamic-remotes-synchronous-imports/playwright.config.ts b/advanced-api/dynamic-remotes-synchronous-imports/playwright.config.ts
new file mode 100644
index 00000000000..b506b75a73b
--- /dev/null
+++ b/advanced-api/dynamic-remotes-synchronous-imports/playwright.config.ts
@@ -0,0 +1,46 @@
+import { defineConfig, devices } from '@playwright/test';
+
+export default defineConfig({
+ testDir: './e2e',
+ timeout: 60000,
+ expect: {
+ timeout: 15000,
+ },
+ fullyParallel: true,
+ forbidOnly: !!process.env.CI,
+ retries: process.env.CI ? 1 : 0,
+ workers: process.env.CI ? 1 : undefined,
+ reporter: [
+ ['html', { outputFolder: 'playwright-report', open: 'never' }],
+ ['list'],
+ ],
+ use: {
+ baseURL: 'http://localhost:3001',
+ trace: 'on-first-retry',
+ screenshot: 'only-on-failure',
+ video: 'retain-on-failure',
+ viewport: { width: 1920, height: 1080 },
+ },
+
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ ],
+
+ webServer: [
+ {
+ command: 'pnpm --filter dynamic-remotes-synchronous-imports_app1 start',
+ port: 3001,
+ reuseExistingServer: !process.env.CI,
+ timeout: 120000,
+ },
+ {
+ command: 'pnpm --filter dynamic-remotes-synchronous-imports_app2 start',
+ port: 3002,
+ reuseExistingServer: !process.env.CI,
+ timeout: 120000,
+ },
+ ],
+});
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app1/package.json b/advanced-api/dynamic-remotes/app1/package.json
index bb660262f4c..4114d595521 100644
--- a/advanced-api/dynamic-remotes/app1/package.json
+++ b/advanced-api/dynamic-remotes/app1/package.json
@@ -4,14 +4,19 @@
"devDependencies": {
"@babel/core": "7.24.7",
"@babel/preset-react": "7.24.7",
+ "@babel/preset-typescript": "^7.24.7",
"@module-federation/enhanced": "0.17.1",
"@module-federation/runtime": "0.17.1",
"@rspack/cli": "1.4.11",
"@rspack/core": "1.4.11",
"@rspack/dev-server": "1.1.3",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
"babel-loader": "9.1.3",
"html-webpack-plugin": "5.6.0",
"serve": "14.2.3",
+ "ts-loader": "^9.5.1",
+ "typescript": "^5.5.4",
"webpack": "5.101.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4"
diff --git a/advanced-api/dynamic-remotes/app1/rspack.config.js b/advanced-api/dynamic-remotes/app1/rspack.config.js
index cb91134113b..0e9c0829761 100644
--- a/advanced-api/dynamic-remotes/app1/rspack.config.js
+++ b/advanced-api/dynamic-remotes/app1/rspack.config.js
@@ -2,49 +2,50 @@ const {
HtmlRspackPlugin,
} = require('@rspack/core');
const {ModuleFederationPlugin} = require('@module-federation/enhanced/rspack')
-
const path = require('path');
+const { createSharedConfig, createDevServerConfig, swcConfig } = require('../shared-config');
module.exports = {
entry: './src/index',
mode: 'development',
target: 'web',
- devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
- },
- port: 3001,
- },
+ devServer: createDevServerConfig(3001),
output: {
publicPath: 'auto',
},
+ resolve: {
+ extensions: ['.tsx', '.ts', '.jsx', '.js'],
+ alias: {
+ '@module-federation/runtime$': require.resolve('@module-federation/runtime'),
+ },
+ },
module: {
rules: [
{
- test: /\.(js|jsx)$/,
+ test: /\.(ts|tsx)$/,
include: path.resolve(__dirname, 'src'),
use: {
loader: 'builtin:swc-loader',
options: {
+ ...swcConfig,
jsc: {
+ ...swcConfig.jsc,
parser: {
- syntax: 'ecmascript',
- jsx: true,
- },
- transform: {
- react: {
- runtime: 'automatic',
- },
+ syntax: 'typescript',
+ tsx: true,
},
},
},
},
},
+ {
+ test: /\.(js|jsx)$/,
+ include: path.resolve(__dirname, 'src'),
+ use: {
+ loader: 'builtin:swc-loader',
+ options: swcConfig,
+ },
+ },
],
},
plugins: [
@@ -54,36 +55,18 @@ module.exports = {
// version is inferred from package.json
// there is no version check for the required version
// so it will always use the higher version found
- shared: {
- react: {
- import: 'react',
- shareKey: 'react',
- shareScope: 'default',
- singleton: true,
- requiredVersion: '^18.3.1',
- strictVersion: true,
- },
- 'react/jsx-runtime': {
- singleton: true,
- },
- 'react/jsx-dev-runtime': {
- singleton: true,
- },
- 'react-dom': {
- singleton: true,
- requiredVersion: '^18.3.1',
- strictVersion: true,
- },
+ shared: createSharedConfig(),
+ dts: {
+ generateTypes: true,
+ generateAPITypes: true,
+ },
+ manifest: {
+ fileName: 'mf-manifest.json',
+ getPublicPath: () => 'auto',
},
}),
new HtmlRspackPlugin({
template: './public/index.html',
}),
],
- // it will be fixed soon...
- resolve: {
- alias: {
- '@module-federation/runtime$': require.resolve('@module-federation/runtime'),
- },
- },
};
diff --git a/advanced-api/dynamic-remotes/app1/src/App.js b/advanced-api/dynamic-remotes/app1/src/App.tsx
similarity index 55%
rename from advanced-api/dynamic-remotes/app1/src/App.js
rename to advanced-api/dynamic-remotes/app1/src/App.tsx
index fdb7fc71ce2..82dbbd6e1e1 100644
--- a/advanced-api/dynamic-remotes/app1/src/App.js
+++ b/advanced-api/dynamic-remotes/app1/src/App.tsx
@@ -1,21 +1,32 @@
import React, { useState, useEffect, Suspense } from 'react';
import { init, loadRemote } from '@module-federation/runtime';
+import { createDefaultPlugins } from '../../runtime-plugins';
+import type { RemoteComponentProps, DynamicImportHook } from '../../types/module-federation';
-class ErrorBoundary extends React.Component {
- constructor(props) {
+interface ErrorBoundaryState {
+ hasError: boolean;
+ error: Error | null;
+}
+
+interface ErrorBoundaryProps {
+ children: React.ReactNode;
+}
+
+class ErrorBoundary extends React.Component {
+ constructor(props: ErrorBoundaryProps) {
super(props);
this.state = { hasError: false, error: null };
}
- static getDerivedStateFromError(error) {
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { hasError: true, error };
}
- componentDidCatch(error, errorInfo) {
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
console.error('Remote component error:', error, errorInfo);
}
- render() {
+ render(): React.ReactNode {
if (this.state.hasError) {
return (
{
+const getRemoteEntry = (port: number): string => {
const baseUrl = process.env.NODE_ENV === 'production'
? (process.env.REACT_APP_REMOTE_BASE_URL || window.location.origin)
: 'http://localhost';
return `${baseUrl}:${port}/remoteEntry.js`;
};
+// Initialize runtime with plugins for enhanced error handling and performance
init({
name: 'app1',
remotes: [
@@ -74,64 +86,96 @@ init({
entry: getRemoteEntry(3003),
},
],
+ plugins: createDefaultPlugins({
+ retry: {
+ onRetry: (attempt, error, args) => {
+ console.log(`Retrying ${args.id} (attempt ${attempt}):`, error.message);
+ },
+ onFailure: (error, args) => {
+ console.error(`Failed to load ${args.id} after all retries:`, error);
+ }
+ },
+ performance: {
+ onSlowLoad: (loadTime, args) => {
+ console.warn(`Slow load detected for ${args.id}: ${loadTime}ms`);
+ }
+ },
+ errorBoundary: {
+ onError: (errorInfo) => {
+ // In a real app, you might send this to an error reporting service
+ console.error('Module Federation Error Report:', errorInfo);
+ }
+ }
+ })
});
-function useDynamicImport({ module, scope }) {
- const [component, setComponent] = useState(null);
- const [loading, setLoading] = useState(false);
- const [error, setError] = useState(null);
+function useDynamicImport({ module, scope }: RemoteComponentProps): DynamicImportHook {
+ const [component, setComponent] = useState
(null);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
+ const [retryCount, setRetryCount] = useState(0);
+
+ const loadComponent = async (isRetry: boolean = false): Promise => {
+ if (isRetry) {
+ setRetryCount(prev => prev + 1);
+ } else {
+ setRetryCount(0);
+ }
+
+ setLoading(true);
+ setError(null);
+ if (!isRetry) setComponent(null);
+
+ try {
+ console.log(`Loading remote module: ${scope}/${module}${isRetry ? ` (retry ${retryCount + 1})` : ''}`);
+ const { default: Component } = await loadRemote(`${scope}/${module}`);
+ setComponent(() => Component);
+ console.log(`Successfully loaded: ${scope}/${module}`);
+ } catch (error) {
+ console.error(`Error loading remote module ${scope}/${module}:`, error);
+ setError(error as Error);
+ } finally {
+ setLoading(false);
+ }
+ };
useEffect(() => {
if (!module || !scope) {
setComponent(null);
setError(null);
+ setRetryCount(0);
return;
}
- const loadComponent = async () => {
- setLoading(true);
- setError(null);
- setComponent(null);
-
- try {
- console.log(`Loading remote module: ${scope}/${module}`);
- const { default: Component } = await loadRemote(`${scope}/${module}`);
- setComponent(() => Component);
- console.log(`Successfully loaded: ${scope}/${module}`);
- } catch (error) {
- console.error(`Error loading remote module ${scope}/${module}:`, error);
- setError(error);
- } finally {
- setLoading(false);
- }
- };
-
loadComponent();
}, [module, scope]);
- return { component, loading, error };
+ return { component, loading, error, retryCount, retry: () => loadComponent(true) };
}
-function App() {
- const [{ module, scope }, setSystem] = useState({});
+function App(): JSX.Element {
+ const [{ module, scope }, setSystem] = useState>({});
- const setApp2 = () => {
+ const setApp2 = (): void => {
setSystem({
scope: 'app2',
module: 'Widget',
});
};
- const setApp3 = () => {
+ const setApp3 = (): void => {
setSystem({
scope: 'app3',
module: 'Widget',
});
};
- const { component: Component, loading, error } = useDynamicImport({ module, scope });
+ const { component: Component, loading, error, retryCount, retry } = useDynamicImport({
+ module: module || '',
+ scope: scope || ''
+ });
- const renderRemoteComponent = () => {
+ const renderRemoteComponent = (): React.ReactNode => {
if (loading) {
return (
🔄 Loading {scope}/{module}...
+ {retryCount > 0 && (
+
+ Retry attempt {retryCount}
+
+ )}
);
}
@@ -157,6 +206,28 @@ function App() {
}}>
⚠️ Failed to Load Remote Component
Could not load {scope}/{module}
+ {retryCount > 0 && (
+
+ Retry attempts: {retryCount}
+
+ )}
+
+
+ {loading ? 'Retrying...' : 'Retry Load'}
+
+
Error Details
diff --git a/advanced-api/dynamic-remotes/app1/tsconfig.json b/advanced-api/dynamic-remotes/app1/tsconfig.json
new file mode 100644
index 00000000000..8f061d58aa4
--- /dev/null
+++ b/advanced-api/dynamic-remotes/app1/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "es6"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src/**/*",
+ "../types/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app1/webpack.config.js b/advanced-api/dynamic-remotes/app1/webpack.config.js
index 1e9c4b2810f..3107be662cb 100644
--- a/advanced-api/dynamic-remotes/app1/webpack.config.js
+++ b/advanced-api/dynamic-remotes/app1/webpack.config.js
@@ -1,34 +1,31 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('@module-federation/enhanced').ModuleFederationPlugin;
const path = require('path');
+const { createSharedConfig, createDevServerConfig, babelConfig } = require('../shared-config');
module.exports = {
entry: './src/index',
mode: 'development',
target: 'web',
- devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
- },
- port: 3001,
- },
+ devServer: createDevServerConfig(3001),
output: {
publicPath: 'auto',
},
+ resolve: {
+ extensions: ['.tsx', '.ts', '.jsx', '.js'],
+ },
module: {
rules: [
+ {
+ test: /\.(ts|tsx)$/,
+ loader: 'ts-loader',
+ exclude: /node_modules/,
+ },
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
- options: {
- presets: ['@babel/preset-react'],
- },
+ options: babelConfig,
},
],
},
@@ -39,23 +36,14 @@ module.exports = {
// version is inferred from package.json
// there is no version check for the required version
// so it will always use the higher version found
- shared: {
- react: {
- import: 'react',
- shareKey: 'react',
- shareScope: 'default',
- singleton: true,
- requiredVersion: '^18.3.1',
- strictVersion: true,
- },
- 'react-dom': {
- singleton: true,
- requiredVersion: '^18.3.1',
- strictVersion: true,
- },
- 'react/jsx-runtime': {
- singleton: true,
- },
+ shared: createSharedConfig(),
+ dts: {
+ generateTypes: true,
+ generateAPITypes: true,
+ },
+ manifest: {
+ fileName: 'mf-manifest.json',
+ getPublicPath: () => 'auto',
},
}),
new HtmlWebpackPlugin({
diff --git a/advanced-api/dynamic-remotes/app2/package.json b/advanced-api/dynamic-remotes/app2/package.json
index 5a8fe394821..d8b55adfa6b 100644
--- a/advanced-api/dynamic-remotes/app2/package.json
+++ b/advanced-api/dynamic-remotes/app2/package.json
@@ -4,13 +4,18 @@
"devDependencies": {
"@babel/core": "7.24.7",
"@babel/preset-react": "7.24.7",
+ "@babel/preset-typescript": "^7.24.7",
"@module-federation/enhanced": "0.17.1",
"@rspack/cli": "1.4.11",
"@rspack/core": "1.4.11",
"@rspack/dev-server": "1.1.3",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
"babel-loader": "9.1.3",
"html-webpack-plugin": "5.6.0",
"serve": "14.2.3",
+ "ts-loader": "^9.5.1",
+ "typescript": "^5.5.4",
"webpack": "5.101.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4"
diff --git a/advanced-api/dynamic-remotes/app2/rspack.config.js b/advanced-api/dynamic-remotes/app2/rspack.config.js
index 8b08b700066..54a77b1fba7 100644
--- a/advanced-api/dynamic-remotes/app2/rspack.config.js
+++ b/advanced-api/dynamic-remotes/app2/rspack.config.js
@@ -5,21 +5,12 @@ const {ModuleFederationPlugin} = require('@module-federation/enhanced/rspack')
const path = require('path');
const deps = require('./package.json').dependencies;
+const { createSharedConfig, createDevServerConfig, swcConfig } = require('../shared-config');
module.exports = {
entry: './src/index',
mode: 'development',
target: 'web',
- devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
- },
- port: 3002,
- },
+ devServer: createDevServerConfig(3002),
output: {
publicPath: 'auto',
},
@@ -33,19 +24,7 @@ module.exports = {
include: path.resolve(__dirname, 'src'),
use: {
loader: 'builtin:swc-loader',
- options: {
- jsc: {
- parser: {
- syntax: 'ecmascript',
- jsx: true,
- },
- transform: {
- react: {
- runtime: 'automatic',
- },
- },
- },
- },
+ options: swcConfig,
},
},
],
@@ -57,30 +36,19 @@ module.exports = {
exposes: {
'./Widget': './src/Widget',
},
- shared: {
+ shared: createSharedConfig({
moment: {
requiredVersion: deps.moment,
singleton: false,
},
- 'react/jsx-runtime': {
- singleton: true,
- },
- 'react/jsx-dev-runtime': {
- singleton: true,
- },
- react: {
- requiredVersion: '^18.3.1',
- import: 'react',
- shareKey: 'react',
- shareScope: 'default',
- singleton: true,
- strictVersion: true,
- },
- 'react-dom': {
- requiredVersion: '^18.3.1',
- singleton: true,
- strictVersion: true,
- },
+ }),
+ dts: {
+ generateTypes: false,
+ generateAPITypes: false,
+ },
+ manifest: {
+ fileName: 'mf-manifest.json',
+ getPublicPath: () => 'auto',
},
}),
new HtmlRspackPlugin({
diff --git a/advanced-api/dynamic-remotes/app2/tsconfig.json b/advanced-api/dynamic-remotes/app2/tsconfig.json
new file mode 100644
index 00000000000..8f061d58aa4
--- /dev/null
+++ b/advanced-api/dynamic-remotes/app2/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "es6"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src/**/*",
+ "../types/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app2/webpack.config.js b/advanced-api/dynamic-remotes/app2/webpack.config.js
index 7351c6ebbbd..37eb82a8e1d 100644
--- a/advanced-api/dynamic-remotes/app2/webpack.config.js
+++ b/advanced-api/dynamic-remotes/app2/webpack.config.js
@@ -2,21 +2,12 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('@module-federation/enhanced').ModuleFederationPlugin;
const path = require('path');
const deps = require('./package.json').dependencies;
+const { createSharedConfig, createDevServerConfig, babelConfig } = require('../shared-config');
module.exports = {
entry: './src/index',
mode: 'development',
target: 'web',
- devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
- },
- port: 3002,
- },
+ devServer: createDevServerConfig(3002),
output: {
publicPath: 'auto',
@@ -27,9 +18,7 @@ module.exports = {
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
- options: {
- presets: ['@babel/preset-react'],
- },
+ options: babelConfig,
},
],
},
@@ -40,27 +29,19 @@ module.exports = {
exposes: {
'./Widget': './src/Widget',
},
- shared: {
+ shared: createSharedConfig({
moment: {
requiredVersion: deps.moment,
singleton: false,
},
- react: {
- requiredVersion: '^18.3.1',
- import: 'react',
- shareKey: 'react',
- shareScope: 'default',
- singleton: true,
- strictVersion: true,
- },
- 'react-dom': {
- requiredVersion: '^18.3.1',
- singleton: true,
- strictVersion: true,
- },
- 'react/jsx-runtime': {
- singleton: true,
- },
+ }),
+ dts: {
+ generateTypes: true,
+ generateAPITypes: true,
+ },
+ manifest: {
+ fileName: 'mf-manifest.json',
+ getPublicPath: () => 'auto',
},
}),
new HtmlWebpackPlugin({
diff --git a/advanced-api/dynamic-remotes/app3/package.json b/advanced-api/dynamic-remotes/app3/package.json
index c71dc2776e1..de077853503 100644
--- a/advanced-api/dynamic-remotes/app3/package.json
+++ b/advanced-api/dynamic-remotes/app3/package.json
@@ -4,13 +4,18 @@
"devDependencies": {
"@babel/core": "7.24.7",
"@babel/preset-react": "7.24.7",
+ "@babel/preset-typescript": "^7.24.7",
"@module-federation/enhanced": "0.17.1",
"@rspack/cli": "1.4.11",
"@rspack/core": "1.4.11",
"@rspack/dev-server": "1.1.3",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
"babel-loader": "9.1.3",
"html-webpack-plugin": "5.6.0",
"serve": "14.2.3",
+ "ts-loader": "^9.5.1",
+ "typescript": "^5.5.4",
"webpack": "5.101.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4"
diff --git a/advanced-api/dynamic-remotes/app3/rspack.config.js b/advanced-api/dynamic-remotes/app3/rspack.config.js
index bb5f0970a09..a6ed0365c6e 100644
--- a/advanced-api/dynamic-remotes/app3/rspack.config.js
+++ b/advanced-api/dynamic-remotes/app3/rspack.config.js
@@ -5,20 +5,11 @@ const {ModuleFederationPlugin} = require('@module-federation/enhanced/rspack')
const path = require('path');
const deps = require('./package.json').dependencies;
+const { createSharedConfig, createDevServerConfig, swcConfig } = require('../shared-config');
module.exports = {
entry: './src/index',
mode: 'development',
- devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
- },
- port: 3003,
- },
+ devServer: createDevServerConfig(3003),
target: 'web',
output: {
publicPath: 'auto',
@@ -30,19 +21,7 @@ module.exports = {
include: path.resolve(__dirname, 'src'),
use: {
loader: 'builtin:swc-loader',
- options: {
- jsc: {
- parser: {
- syntax: 'ecmascript',
- jsx: true,
- },
- transform: {
- react: {
- runtime: 'automatic',
- },
- },
- },
- },
+ options: swcConfig,
},
},
],
@@ -54,26 +33,7 @@ module.exports = {
exposes: {
'./Widget': './src/Widget',
},
- shared: {
- react: {
- requiredVersion: '^18.3.1',
- import: 'react',
- shareKey: 'react',
- shareScope: 'default',
- singleton: true,
- strictVersion: true,
- },
- 'react-dom': {
- requiredVersion: '^18.3.1',
- singleton: true,
- strictVersion: true,
- },
- 'react/jsx-runtime': {
- singleton: true,
- },
- 'react/jsx-dev-runtime': {
- singleton: true,
- },
+ shared: createSharedConfig({
moment: {
requiredVersion: deps.moment,
singleton: false,
@@ -86,6 +46,14 @@ module.exports = {
requiredVersion: deps.redux,
singleton: true,
},
+ }),
+ dts: {
+ generateTypes: false,
+ generateAPITypes: false,
+ },
+ manifest: {
+ fileName: 'mf-manifest.json',
+ getPublicPath: () => 'auto',
},
}),
new HtmlRspackPlugin({
diff --git a/advanced-api/dynamic-remotes/app3/tsconfig.json b/advanced-api/dynamic-remotes/app3/tsconfig.json
new file mode 100644
index 00000000000..8f061d58aa4
--- /dev/null
+++ b/advanced-api/dynamic-remotes/app3/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "es6"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src/**/*",
+ "../types/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app3/webpack.config.js b/advanced-api/dynamic-remotes/app3/webpack.config.js
index 46c78cb785c..1a0bb6cd52d 100644
--- a/advanced-api/dynamic-remotes/app3/webpack.config.js
+++ b/advanced-api/dynamic-remotes/app3/webpack.config.js
@@ -2,20 +2,11 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('@module-federation/enhanced').ModuleFederationPlugin;
const path = require('path');
const deps = require('./package.json').dependencies;
+const { createSharedConfig, createDevServerConfig, babelConfig } = require('../shared-config');
module.exports = {
entry: './src/index',
mode: 'development',
- devServer: {
- static: {
- directory: path.join(__dirname, 'dist'),
- },
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
- },
- port: 3003,
- },
+ devServer: createDevServerConfig(3003),
target: 'web',
output: {
publicPath: 'auto',
@@ -26,9 +17,7 @@ module.exports = {
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
- options: {
- presets: ['@babel/preset-react'],
- },
+ options: babelConfig,
},
],
},
@@ -39,23 +28,7 @@ module.exports = {
exposes: {
'./Widget': './src/Widget',
},
- shared: {
- react: {
- requiredVersion: deps.react,
- import: 'react',
- shareKey: 'react',
- shareScope: 'default',
- singleton: true,
- strictVersion: true,
- },
- 'react-dom': {
- requiredVersion: '^18.3.1',
- singleton: true,
- strictVersion: true,
- },
- 'react/jsx-runtime': {
- singleton: true,
- },
+ shared: createSharedConfig({
moment: {
requiredVersion: deps.moment,
singleton: false,
@@ -68,6 +41,14 @@ module.exports = {
requiredVersion: deps.redux,
singleton: true,
},
+ }),
+ dts: {
+ generateTypes: true,
+ generateAPITypes: true,
+ },
+ manifest: {
+ fileName: 'mf-manifest.json',
+ getPublicPath: () => 'auto',
},
}),
new HtmlWebpackPlugin({
diff --git a/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts b/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts
index 1289765ab6f..d8daebb4902 100644
--- a/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts
+++ b/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts
@@ -1,28 +1,102 @@
-import { test, expect } from './utils/base-test';
-import { selectors } from './utils/selectors';
-import { Constants } from './utils/constants';
+import { test, expect, Page } from '@playwright/test';
+
+// Helper functions
+async function openLocalhost(page: Page, port: number) {
+ await page.goto(`http://localhost:${port}`);
+ await page.waitForLoadState('networkidle');
+
+ // Wait for module federation to load (give it extra time for federated components)
+ await page.waitForTimeout(2000);
+
+ // Wait for React to render
+ await page.waitForFunction(() => {
+ const elements = document.querySelectorAll('h1, h2, button, p');
+ return elements.length > 0;
+ }, { timeout: 30000 });
+}
+
+async function checkElementWithTextPresence(page: Page, selector: string, text: string) {
+ const element = page.locator(`${selector}:has-text("${text}")`);
+ await expect(element).toBeVisible();
+}
+
+async function clickElementWithText(page: Page, selector: string, text: string) {
+ const element = page.locator(`${selector}:has-text("${text}")`);
+
+ // Wait for element to be ready
+ await element.waitFor({ state: 'visible', timeout: 10000 });
+
+ // Remove any overlays that might interfere
+ await page.evaluate(() => {
+ const overlays = document.querySelectorAll('#webpack-dev-server-client-overlay, iframe[src*="webpack-dev-server"]');
+ overlays.forEach(overlay => overlay.remove());
+ });
+
+ // Try clicking with retries
+ let attempts = 0;
+ while (attempts < 3) {
+ try {
+ await element.click({ timeout: 5000 });
+ break;
+ } catch (error) {
+ attempts++;
+ if (attempts >= 3) throw error;
+ await page.waitForTimeout(1000);
+ }
+ }
+
+ // Wait for any dynamic loading to complete
+ await page.waitForTimeout(3000);
+}
+
+async function checkElementVisibility(page: Page, selector: string) {
+ const element = page.locator(selector);
+ await expect(element).toBeVisible();
+}
+
+async function checkElementBackgroundColor(page: Page, selector: string, expectedColor: string) {
+ const element = page.locator(selector);
+ await expect(element).toHaveCSS('background-color', expectedColor);
+}
+
+async function waitForDynamicImport(page: Page) {
+ // Wait for dynamic import to complete - looking for loading states to disappear
+ await page.waitForTimeout(3000); // Give time for dynamic loading
+
+ // Wait for any network activity to settle
+ await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => {
+ // Ignore timeout - loading might already be complete
+ });
+}
+
+async function checkDateFormat(page: Page) {
+ // Check for moment.js formatted date (format: "Month Day Year, time")
+ const dateRegex = /\w+ \d+\w+ \d{4}, \d+:\d+/;
+ const textContent = await page.textContent('body');
+ expect(textContent).toMatch(dateRegex);
+}
test.describe('Dynamic Remotes E2E Tests', () => {
test.describe('Host Application (App 1)', () => {
- test('should display host application elements correctly', async ({ basePage }) => {
+ test('should display host application elements correctly', async ({ page }) => {
const consoleErrors: string[] = [];
- basePage.page.on('console', (msg) => {
+ page.on('console', (msg) => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
- await basePage.openLocalhost(3001);
+ await openLocalhost(page, 3001);
// Check main elements exist
- await basePage.checkElementWithTextPresence('h1', 'Dynamic System Host');
- await basePage.checkElementWithTextPresence('h2', 'App 1');
- await basePage.checkElementWithTextPresence('p', 'The Dynamic System will take advantage of Module Federation');
+ await checkElementWithTextPresence(page, 'h1', 'Dynamic System Host');
+ await checkElementWithTextPresence(page, 'h2', 'App 1');
+ await checkElementWithTextPresence(page, 'p', 'The Dynamic System will take advantage of Module Federation');
// Check both buttons exist
- await basePage.checkElementWithTextPresence('button', 'Load App 2 Widget');
- await basePage.checkElementWithTextPresence('button', 'Load App 3 Widget');
+ await checkElementWithTextPresence(page, 'button', 'Load App 2 Widget');
+ await checkElementWithTextPresence(page, 'button', 'Load App 3 Widget');
// Verify no critical console errors
const criticalErrors = consoleErrors.filter(error =>
@@ -33,27 +107,27 @@ test.describe('Dynamic Remotes E2E Tests', () => {
expect(criticalErrors).toHaveLength(0);
});
- test('should dynamically load App 2 widget successfully', async ({ basePage }) => {
+ test('should dynamically load App 2 widget successfully', async ({ page }) => {
const consoleErrors: string[] = [];
- basePage.page.on('console', (msg) => {
+ page.on('console', (msg) => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
- await basePage.openLocalhost(3001);
+ await openLocalhost(page, 3001);
// Click to load App 2 widget
- await basePage.clickElementWithText('button', 'Load App 2 Widget');
- await basePage.waitForDynamicImport();
+ await clickElementWithText(page, 'button', 'Load App 2 Widget');
+ await waitForDynamicImport(page);
// Verify App 2 widget loaded
- await basePage.checkElementVisibility(selectors.dataTestIds.app2Widget);
- await basePage.checkElementWithTextPresence('h2', 'App 2 Widget');
- await basePage.checkElementBackgroundColor(selectors.dataTestIds.app2Widget, 'rgb(255, 0, 0)');
+ await checkElementVisibility(page, '[data-e2e="APP_2__WIDGET"]');
+ await checkElementWithTextPresence(page, 'h2', 'App 2 Widget');
+ await checkElementBackgroundColor(page, '[data-e2e="APP_2__WIDGET"]', 'rgb(255, 0, 0)');
// Check for moment.js date formatting
- await basePage.checkDateFormat();
+ await checkDateFormat(page);
// Verify no module federation errors
const moduleErrors = consoleErrors.filter(error =>
@@ -63,27 +137,27 @@ test.describe('Dynamic Remotes E2E Tests', () => {
expect(moduleErrors).toHaveLength(0);
});
- test('should dynamically load App 3 widget successfully', async ({ basePage }) => {
+ test('should dynamically load App 3 widget successfully', async ({ page }) => {
const consoleErrors: string[] = [];
- basePage.page.on('console', (msg) => {
+ page.on('console', (msg) => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
- await basePage.openLocalhost(3001);
+ await openLocalhost(page, 3001);
// Click to load App 3 widget
- await basePage.clickElementWithText('button', 'Load App 3 Widget');
- await basePage.waitForDynamicImport();
+ await clickElementWithText(page, 'button', 'Load App 3 Widget');
+ await waitForDynamicImport(page);
// Verify App 3 widget loaded
- await basePage.checkElementVisibility(selectors.dataTestIds.app3Widget);
- await basePage.checkElementWithTextPresence('h2', 'App 3 Widget');
- await basePage.checkElementBackgroundColor(selectors.dataTestIds.app3Widget, 'rgb(128, 0, 128)');
+ await checkElementVisibility(page, '[data-e2e="APP_3__WIDGET"]');
+ await checkElementWithTextPresence(page, 'h2', 'App 3 Widget');
+ await checkElementBackgroundColor(page, '[data-e2e="APP_3__WIDGET"]', 'rgb(128, 0, 128)');
// Check for moment.js date formatting
- await basePage.checkDateFormat();
+ await checkDateFormat(page);
// Verify no module federation errors
const moduleErrors = consoleErrors.filter(error =>
@@ -93,61 +167,61 @@ test.describe('Dynamic Remotes E2E Tests', () => {
expect(moduleErrors).toHaveLength(0);
});
- test('should handle sequential loading of both widgets', async ({ basePage }) => {
- await basePage.openLocalhost(3001);
+ test('should handle sequential loading of both widgets', async ({ page }) => {
+ await openLocalhost(page, 3001);
// Load App 2 widget first
- await basePage.clickElementWithText('button', 'Load App 2 Widget');
- await basePage.waitForDynamicImport();
+ await clickElementWithText(page, 'button', 'Load App 2 Widget');
+ await waitForDynamicImport(page);
// Verify App 2 widget is loaded and get its content
- await basePage.checkElementVisibility(selectors.dataTestIds.app2Widget);
- await basePage.checkElementWithTextPresence('h2', 'App 2 Widget');
+ await checkElementVisibility(page, '[data-e2e="APP_2__WIDGET"]');
+ await checkElementWithTextPresence(page, 'h2', 'App 2 Widget');
// Then load App 3 widget (this replaces the previous widget in this implementation)
- await basePage.clickElementWithText('button', 'Load App 3 Widget');
- await basePage.waitForDynamicImport();
+ await clickElementWithText(page, 'button', 'Load App 3 Widget');
+ await waitForDynamicImport(page);
// Verify App 3 widget is loaded
- await basePage.checkElementVisibility(selectors.dataTestIds.app3Widget);
- await basePage.checkElementWithTextPresence('h2', 'App 3 Widget');
+ await checkElementVisibility(page, '[data-e2e="APP_3__WIDGET"]');
+ await checkElementWithTextPresence(page, 'h2', 'App 3 Widget');
// Note: In this dynamic remotes implementation, widgets replace each other
// rather than accumulating, so we verify the latest widget is visible
});
- test('should show loading states and handle errors gracefully', async ({ basePage }) => {
- await basePage.openLocalhost(3001);
+ test('should show loading states and handle errors gracefully', async ({ page }) => {
+ await openLocalhost(page, 3001);
// Check that buttons are initially enabled
- const app2Button = basePage.page.locator('button').filter({ hasText: 'Load App 2 Widget' });
+ const app2Button = page.locator('button').filter({ hasText: 'Load App 2 Widget' });
await expect(app2Button).toBeEnabled();
// Monitor for any error boundaries or error states
- const errorMessages = basePage.page.locator('text="⚠️"');
+ const errorMessages = page.locator('text="⚠️"');
await expect(errorMessages).toHaveCount(0);
});
});
test.describe('Remote Application - App 2', () => {
- test('should display App 2 standalone correctly', async ({ basePage }) => {
+ test('should display App 2 standalone correctly', async ({ page }) => {
const consoleErrors: string[] = [];
- basePage.page.on('console', (msg) => {
+ page.on('console', (msg) => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
- await basePage.openLocalhost(3002);
+ await openLocalhost(page, 3002);
// Check App 2 widget displays correctly when accessed directly
- await basePage.checkElementVisibility(selectors.dataTestIds.app2Widget);
- await basePage.checkElementWithTextPresence('h2', 'App 2 Widget');
- await basePage.checkElementBackgroundColor(selectors.dataTestIds.app2Widget, 'rgb(255, 0, 0)');
+ await checkElementVisibility(page, '[data-e2e="APP_2__WIDGET"]');
+ await checkElementWithTextPresence(page, 'h2', 'App 2 Widget');
+ await checkElementBackgroundColor(page, '[data-e2e="APP_2__WIDGET"]', 'rgb(255, 0, 0)');
// Check moment.js functionality
- await basePage.checkElementWithTextPresence('p', "Moment shouldn't download twice");
- await basePage.checkDateFormat();
+ await checkElementWithTextPresence(page, 'p', "Moment shouldn't download twice");
+ await checkDateFormat(page);
// Verify no critical console errors (filter out expected warnings)
const criticalErrors = consoleErrors.filter(e =>
@@ -161,23 +235,23 @@ test.describe('Dynamic Remotes E2E Tests', () => {
});
test.describe('Remote Application - App 3', () => {
- test('should display App 3 standalone correctly', async ({ basePage }) => {
+ test('should display App 3 standalone correctly', async ({ page }) => {
const consoleErrors: string[] = [];
- basePage.page.on('console', (msg) => {
+ page.on('console', (msg) => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
- await basePage.openLocalhost(3003);
+ await openLocalhost(page, 3003);
// Check App 3 widget displays correctly when accessed directly
- await basePage.checkElementVisibility(selectors.dataTestIds.app3Widget);
- await basePage.checkElementWithTextPresence('h2', 'App 3 Widget');
- await basePage.checkElementBackgroundColor(selectors.dataTestIds.app3Widget, 'rgb(128, 0, 128)');
+ await checkElementVisibility(page, '[data-e2e="APP_3__WIDGET"]');
+ await checkElementWithTextPresence(page, 'h2', 'App 3 Widget');
+ await checkElementBackgroundColor(page, '[data-e2e="APP_3__WIDGET"]', 'rgb(128, 0, 128)');
// Check for moment.js date formatting
- await basePage.checkDateFormat();
+ await checkDateFormat(page);
// Verify no critical console errors (filter out expected warnings)
const criticalErrors = consoleErrors.filter(e =>
diff --git a/advanced-api/dynamic-remotes/e2e/utils/base-test.ts b/advanced-api/dynamic-remotes/e2e/utils/base-test.ts
index c1282ae9330..9bfbce676cf 100644
--- a/advanced-api/dynamic-remotes/e2e/utils/base-test.ts
+++ b/advanced-api/dynamic-remotes/e2e/utils/base-test.ts
@@ -1,4 +1,4 @@
-import { test as base, expect, Page } from '@playwright/test';
+import { Page } from '@playwright/test';
export class BasePage {
constructor(public page: Page) {}
@@ -87,11 +87,5 @@ export class BasePage {
}
}
-export const test = base.extend<{ basePage: BasePage }>({
- basePage: async ({ page }, use) => {
- const basePage = new BasePage(page);
- await use(basePage);
- },
-});
export { expect } from '@playwright/test';
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/package.json b/advanced-api/dynamic-remotes/package.json
index 59b9ca20adf..ee8a8e2ccbc 100644
--- a/advanced-api/dynamic-remotes/package.json
+++ b/advanced-api/dynamic-remotes/package.json
@@ -17,8 +17,8 @@
"test:e2e": "npx playwright test",
"test:e2e:ui": "npx playwright test --ui",
"test:e2e:debug": "npx playwright test --debug",
- "e2e:ci": "pnpm start & sleep 5 && wait-on tcp:3001 tcp:3002 tcp:3003 && npx playwright test --reporter=list; kill $(jobs -p) 2>/dev/null || true",
- "legacy:e2e:ci": "pnpm legacy:start & sleep 5 && wait-on tcp:3001 tcp:3002 tcp:3003 && LEGACY_MODE=true npx playwright test --reporter=list; kill $(jobs -p) 2>/dev/null || true"
+ "e2e:ci": "npx playwright test --reporter=list",
+ "legacy:e2e:ci": "npx playwright test --reporter=list"
},
"devDependencies": {
"@playwright/test": "^1.54.2",
diff --git a/advanced-api/dynamic-remotes/playwright.config.ts b/advanced-api/dynamic-remotes/playwright.config.ts
index 26445e39243..a8fd326e740 100644
--- a/advanced-api/dynamic-remotes/playwright.config.ts
+++ b/advanced-api/dynamic-remotes/playwright.config.ts
@@ -29,6 +29,24 @@ export default defineConfig({
},
],
- // webServer configuration removed - servers are started manually in package.json scripts
- // This ensures better compatibility with CI environments and matches the original Cypress approach
+ webServer: [
+ {
+ command: 'pnpm --filter dynamic-remotes_app1 start',
+ port: 3001,
+ reuseExistingServer: !process.env.CI,
+ timeout: 120000,
+ },
+ {
+ command: 'pnpm --filter dynamic-remotes_app2 start',
+ port: 3002,
+ reuseExistingServer: !process.env.CI,
+ timeout: 120000,
+ },
+ {
+ command: 'pnpm --filter dynamic-remotes_app3 start',
+ port: 3003,
+ reuseExistingServer: !process.env.CI,
+ timeout: 120000,
+ },
+ ],
});
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/runtime-plugins.js b/advanced-api/dynamic-remotes/runtime-plugins.js
new file mode 100644
index 00000000000..0d7a5618774
--- /dev/null
+++ b/advanced-api/dynamic-remotes/runtime-plugins.js
@@ -0,0 +1,279 @@
+/**
+ * Module Federation Runtime Plugins
+ *
+ * These plugins provide enhanced error handling, retry mechanisms,
+ * and performance monitoring for dynamic remote loading.
+ */
+
+/**
+ * Retry Plugin for failed remote loads
+ * Implements exponential backoff retry strategy
+ */
+class RetryPlugin {
+ constructor(options = {}) {
+ this.maxRetries = options.maxRetries || 3;
+ this.baseDelay = options.baseDelay || 1000;
+ this.maxDelay = options.maxDelay || 5000;
+ this.onRetry = options.onRetry || (() => {});
+ this.onFailure = options.onFailure || (() => {});
+ }
+
+ name = 'retry-plugin';
+
+ async loadRemote(args, next) {
+ let lastError;
+
+ for (let attempt = 0; attempt < this.maxRetries; attempt++) {
+ try {
+ return await next(args);
+ } catch (error) {
+ lastError = error;
+
+ if (attempt === this.maxRetries - 1) {
+ console.error(`Failed to load remote after ${this.maxRetries} attempts:`, error);
+ this.onFailure(error, args);
+ throw error;
+ }
+
+ const delay = Math.min(
+ this.baseDelay * Math.pow(2, attempt),
+ this.maxDelay
+ );
+
+ console.warn(`Retry attempt ${attempt + 1}/${this.maxRetries} for remote ${args.id} in ${delay}ms`, error);
+ this.onRetry(attempt + 1, error, args);
+
+ await new Promise(resolve => setTimeout(resolve, delay));
+ }
+ }
+
+ throw lastError;
+ }
+}
+
+/**
+ * Performance Monitoring Plugin
+ * Tracks remote loading performance and network issues
+ */
+class PerformancePlugin {
+ constructor(options = {}) {
+ this.enableLogging = options.enableLogging !== false;
+ this.slowThreshold = options.slowThreshold || 3000;
+ this.onSlowLoad = options.onSlowLoad || (() => {});
+ this.onLoadSuccess = options.onLoadSuccess || (() => {});
+ }
+
+ name = 'performance-plugin';
+
+ async loadRemote(args, next) {
+ const startTime = performance.now();
+
+ try {
+ const result = await next(args);
+ const loadTime = performance.now() - startTime;
+
+ if (this.enableLogging) {
+ console.log(`Successfully loaded remote ${args.id} in ${loadTime.toFixed(2)}ms`);
+ }
+
+ if (loadTime > this.slowThreshold) {
+ this.onSlowLoad(loadTime, args);
+ }
+
+ this.onLoadSuccess(loadTime, args);
+ return result;
+ } catch (error) {
+ const loadTime = performance.now() - startTime;
+ console.error(`Failed to load remote ${args.id} after ${loadTime.toFixed(2)}ms:`, error);
+ throw error;
+ }
+ }
+}
+
+/**
+ * Health Check Plugin
+ * Validates remote availability before attempting to load
+ */
+class HealthCheckPlugin {
+ constructor(options = {}) {
+ this.timeout = options.timeout || 5000;
+ this.enableCheck = options.enableCheck !== false;
+ this.onHealthCheckFail = options.onHealthCheckFail || (() => {});
+ }
+
+ name = 'health-check-plugin';
+
+ async loadRemote(args, next) {
+ if (!this.enableCheck) {
+ return next(args);
+ }
+
+ try {
+ // Basic health check by trying to fetch the remote entry
+ const controller = new AbortController();
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
+
+ const response = await fetch(args.url, {
+ method: 'HEAD',
+ signal: controller.signal,
+ cache: 'no-cache',
+ });
+
+ clearTimeout(timeoutId);
+
+ if (!response.ok) {
+ throw new Error(`Health check failed: ${response.status} ${response.statusText}`);
+ }
+
+ return await next(args);
+ } catch (error) {
+ console.warn(`Health check failed for remote ${args.id}:`, error.message);
+ this.onHealthCheckFail(error, args);
+
+ // Still attempt to load, as the health check might fail due to CORS
+ // but the actual module loading might work
+ return await next(args);
+ }
+ }
+}
+
+/**
+ * Error Boundary Plugin
+ * Provides comprehensive error tracking and reporting
+ */
+class ErrorBoundaryPlugin {
+ constructor(options = {}) {
+ this.onError = options.onError || (() => {});
+ this.errorReporting = options.errorReporting !== false;
+ this.maxErrorReports = options.maxErrorReports || 10;
+ this.errorCounts = new Map();
+ }
+
+ name = 'error-boundary-plugin';
+
+ async loadRemote(args, next) {
+ try {
+ return await next(args);
+ } catch (error) {
+ const errorKey = `${args.id}-${error.name}`;
+ const errorCount = (this.errorCounts.get(errorKey) || 0) + 1;
+ this.errorCounts.set(errorKey, errorCount);
+
+ const errorInfo = {
+ remoteId: args.id,
+ url: args.url,
+ error: error.message,
+ stack: error.stack,
+ timestamp: new Date().toISOString(),
+ count: errorCount,
+ userAgent: navigator.userAgent,
+ };
+
+ if (this.errorReporting && errorCount <= this.maxErrorReports) {
+ console.error('Module Federation Error:', errorInfo);
+ this.onError(errorInfo);
+ }
+
+ throw error;
+ }
+ }
+}
+
+/**
+ * Cache Plugin
+ * Implements intelligent caching for remote modules
+ */
+class CachePlugin {
+ constructor(options = {}) {
+ this.cacheTTL = options.cacheTTL || 5 * 60 * 1000; // 5 minutes
+ this.maxCacheSize = options.maxCacheSize || 50;
+ this.cache = new Map();
+ this.cacheTimestamps = new Map();
+ }
+
+ name = 'cache-plugin';
+
+ async loadRemote(args, next) {
+ const cacheKey = `${args.id}-${args.url}`;
+ const now = Date.now();
+
+ // Check if we have a valid cached version
+ if (this.cache.has(cacheKey)) {
+ const cacheTime = this.cacheTimestamps.get(cacheKey);
+ if (now - cacheTime < this.cacheTTL) {
+ console.log(`Loading remote ${args.id} from cache`);
+ return this.cache.get(cacheKey);
+ } else {
+ // Cache expired
+ this.cache.delete(cacheKey);
+ this.cacheTimestamps.delete(cacheKey);
+ }
+ }
+
+ // Load fresh and cache
+ const result = await next(args);
+
+ // Implement LRU cache size limit
+ if (this.cache.size >= this.maxCacheSize) {
+ const oldestKey = this.cache.keys().next().value;
+ this.cache.delete(oldestKey);
+ this.cacheTimestamps.delete(oldestKey);
+ }
+
+ this.cache.set(cacheKey, result);
+ this.cacheTimestamps.set(cacheKey, now);
+
+ return result;
+ }
+}
+
+/**
+ * Create default runtime plugins with sensible defaults
+ */
+function createDefaultPlugins(customOptions = {}) {
+ const options = {
+ retry: {
+ maxRetries: 3,
+ baseDelay: 1000,
+ maxDelay: 5000,
+ ...customOptions.retry,
+ },
+ performance: {
+ enableLogging: process.env.NODE_ENV === 'development',
+ slowThreshold: 3000,
+ ...customOptions.performance,
+ },
+ healthCheck: {
+ timeout: 5000,
+ enableCheck: process.env.NODE_ENV === 'development',
+ ...customOptions.healthCheck,
+ },
+ errorBoundary: {
+ errorReporting: true,
+ maxErrorReports: 10,
+ ...customOptions.errorBoundary,
+ },
+ cache: {
+ cacheTTL: 5 * 60 * 1000,
+ maxCacheSize: 50,
+ ...customOptions.cache,
+ },
+ };
+
+ return [
+ new CachePlugin(options.cache),
+ new HealthCheckPlugin(options.healthCheck),
+ new PerformancePlugin(options.performance),
+ new RetryPlugin(options.retry),
+ new ErrorBoundaryPlugin(options.errorBoundary),
+ ];
+}
+
+module.exports = {
+ RetryPlugin,
+ PerformancePlugin,
+ HealthCheckPlugin,
+ ErrorBoundaryPlugin,
+ CachePlugin,
+ createDefaultPlugins,
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/shared-config.js b/advanced-api/dynamic-remotes/shared-config.js
new file mode 100644
index 00000000000..2a05c0ffd08
--- /dev/null
+++ b/advanced-api/dynamic-remotes/shared-config.js
@@ -0,0 +1,158 @@
+/**
+ * Shared Module Federation Configuration
+ *
+ * This file provides standardized shared dependency configurations
+ * across all applications in the dynamic remotes example.
+ */
+
+const deps = {
+ react: '^18.3.1',
+ 'react-dom': '^18.3.1',
+ moment: '^2.29.4',
+ 'react-redux': '^9.1.2',
+ redux: '^5.0.1',
+};
+
+/**
+ * Standard shared configuration for Module Federation
+ * @param {Object} additionalShared - Additional shared dependencies specific to the app
+ * @returns {Object} Complete shared configuration
+ */
+function createSharedConfig(additionalShared = {}) {
+ const baseShared = {
+ react: {
+ singleton: true,
+ requiredVersion: deps.react,
+ strictVersion: true,
+ eager: false,
+ import: 'react',
+ shareKey: 'react',
+ shareScope: 'default',
+ },
+ 'react-dom': {
+ singleton: true,
+ requiredVersion: deps['react-dom'],
+ strictVersion: true,
+ eager: false,
+ },
+ 'react/jsx-runtime': {
+ singleton: true,
+ eager: false,
+ },
+ 'react/jsx-dev-runtime': {
+ singleton: true,
+ eager: false,
+ },
+ };
+
+ return {
+ ...baseShared,
+ ...additionalShared,
+ };
+}
+
+/**
+ * Environment-aware remote URL generation
+ * @param {number} port - Port number for the remote
+ * @param {string} appName - Name of the application
+ * @returns {string} Complete remote entry URL
+ */
+function getRemoteEntry(port, appName = '') {
+ const isDevelopment = process.env.NODE_ENV !== 'production';
+ const baseUrl = isDevelopment
+ ? (process.env.REMOTE_BASE_URL || 'http://localhost')
+ : (process.env.REMOTE_BASE_URL || window?.location?.origin || 'http://localhost');
+
+ return `${baseUrl}:${port}/remoteEntry.js`;
+}
+
+/**
+ * Standard webpack devServer configuration
+ * @param {number} port - Port number for the dev server
+ * @returns {Object} DevServer configuration
+ */
+function createDevServerConfig(port) {
+ return {
+ static: {
+ directory: require('path').join(process.cwd(), 'dist'),
+ },
+ headers: {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
+ 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
+ },
+ port,
+ hot: true,
+ liveReload: false,
+ allowedHosts: 'all',
+ client: {
+ overlay: {
+ errors: true,
+ warnings: false,
+ },
+ },
+ };
+}
+
+/**
+ * Standard babel configuration for React with TypeScript
+ */
+const babelConfig = {
+ presets: [
+ ['@babel/preset-env', { targets: 'defaults' }],
+ ['@babel/preset-react', { runtime: 'automatic' }],
+ ['@babel/preset-typescript', {
+ allowDeclareFields: true,
+ allowNamespaces: true
+ }],
+ ],
+ plugins: [
+ ['@babel/plugin-proposal-class-properties'],
+ ],
+};
+
+/**
+ * Standard SWC configuration for Rspack with TypeScript support
+ */
+const swcConfig = {
+ jsc: {
+ parser: {
+ syntax: 'ecmascript',
+ jsx: true,
+ },
+ transform: {
+ react: {
+ runtime: 'automatic',
+ },
+ },
+ target: 'es2020',
+ },
+};
+
+/**
+ * TypeScript-specific SWC configuration
+ */
+const swcConfigTS = {
+ jsc: {
+ parser: {
+ syntax: 'typescript',
+ tsx: true,
+ },
+ transform: {
+ react: {
+ runtime: 'automatic',
+ },
+ },
+ target: 'es2020',
+ },
+};
+
+module.exports = {
+ createSharedConfig,
+ getRemoteEntry,
+ createDevServerConfig,
+ babelConfig,
+ swcConfig,
+ swcConfigTS,
+ deps,
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/types/module-federation.d.ts b/advanced-api/dynamic-remotes/types/module-federation.d.ts
new file mode 100644
index 00000000000..8baf3c344bf
--- /dev/null
+++ b/advanced-api/dynamic-remotes/types/module-federation.d.ts
@@ -0,0 +1,181 @@
+/**
+ * Module Federation Type Definitions
+ *
+ * Provides type safety for remote modules and federation APIs
+ */
+
+declare module '@module-federation/runtime' {
+ export interface FederationRuntimePlugin {
+ name: string;
+ init?(args: InitOptions): void | Promise;
+ loadRemote?(args: LoadRemoteArgs, next: (args: LoadRemoteArgs) => Promise): Promise;
+ }
+
+ export interface InitOptions {
+ name: string;
+ remotes?: RemoteConfig[];
+ plugins?: FederationRuntimePlugin[];
+ shared?: SharedConfig;
+ }
+
+ export interface RemoteConfig {
+ name: string;
+ entry: string;
+ alias?: string;
+ }
+
+ export interface LoadRemoteArgs {
+ id: string;
+ url: string;
+ from?: string;
+ remoteName?: string;
+ }
+
+ export interface SharedConfig {
+ [key: string]: SharedDependency;
+ }
+
+ export interface SharedDependency {
+ singleton?: boolean;
+ requiredVersion?: string;
+ strictVersion?: boolean;
+ eager?: boolean;
+ import?: string;
+ shareKey?: string;
+ shareScope?: string;
+ }
+
+ export function init(options: InitOptions): Promise;
+ export function loadRemote(id: string): Promise<{ default: T }>;
+ export function registerRemotes(remotes: RemoteConfig[]): void;
+ export function getRemotes(): RemoteConfig[];
+}
+
+declare module '@module-federation/enhanced' {
+ export interface ModuleFederationPluginOptions {
+ name: string;
+ filename?: string;
+ exposes?: Record;
+ remotes?: Record;
+ shared?: SharedConfig;
+ library?: {
+ type: string;
+ name?: string;
+ };
+ dts?: {
+ generateTypes?: boolean;
+ generateAPITypes?: boolean;
+ consumeAPITypes?: boolean;
+ typesFolder?: string;
+ };
+ manifest?: {
+ fileName?: string;
+ getPublicPath?: () => string;
+ };
+ runtime?: boolean;
+ experiments?: {
+ federationRuntime?: string;
+ };
+ }
+
+ export class ModuleFederationPlugin {
+ constructor(options: ModuleFederationPluginOptions);
+ }
+
+ export interface SharedConfig {
+ [key: string]: SharedDependency;
+ }
+
+ export interface SharedDependency {
+ singleton?: boolean;
+ requiredVersion?: string;
+ strictVersion?: boolean;
+ eager?: boolean;
+ import?: string;
+ shareKey?: string;
+ shareScope?: string;
+ }
+}
+
+declare module '@module-federation/enhanced/rspack' {
+ export * from '@module-federation/enhanced';
+}
+
+// Global type declarations for remote modules
+declare global {
+ interface Window {
+ __FEDERATION__: {
+ remotes: Record;
+ shared: Record;
+ };
+ }
+}
+
+// Remote module declarations
+declare module 'app2/Widget' {
+ import { ComponentType } from 'react';
+ const Widget: ComponentType;
+ export default Widget;
+}
+
+declare module 'app3/Widget' {
+ import { ComponentType } from 'react';
+ const Widget: ComponentType;
+ export default Widget;
+}
+
+// Type utilities for dynamic remote loading
+export interface RemoteComponentProps {
+ module: string;
+ scope: string;
+}
+
+export interface DynamicImportHook {
+ component: React.ComponentType | null;
+ loading: boolean;
+ error: Error | null;
+ retryCount: number;
+ retry: () => void;
+}
+
+export interface RuntimePluginOptions {
+ retry?: {
+ maxRetries?: number;
+ baseDelay?: number;
+ maxDelay?: number;
+ onRetry?: (attempt: number, error: Error, args: LoadRemoteArgs) => void;
+ onFailure?: (error: Error, args: LoadRemoteArgs) => void;
+ };
+ performance?: {
+ enableLogging?: boolean;
+ slowThreshold?: number;
+ onSlowLoad?: (loadTime: number, args: LoadRemoteArgs) => void;
+ onLoadSuccess?: (loadTime: number, args: LoadRemoteArgs) => void;
+ };
+ healthCheck?: {
+ timeout?: number;
+ enableCheck?: boolean;
+ onHealthCheckFail?: (error: Error, args: LoadRemoteArgs) => void;
+ };
+ errorBoundary?: {
+ errorReporting?: boolean;
+ maxErrorReports?: number;
+ onError?: (errorInfo: ErrorInfo) => void;
+ };
+ cache?: {
+ cacheTTL?: number;
+ maxCacheSize?: number;
+ };
+}
+
+export interface ErrorInfo {
+ remoteId: string;
+ url: string;
+ error: string;
+ stack?: string;
+ timestamp: string;
+ count: number;
+ userAgent: string;
+}
+
+export {};
\ No newline at end of file
diff --git a/esm/rspack/webpack.config.mjs b/esm/rspack/webpack.config.mjs
deleted file mode 100644
index 37175549762..00000000000
--- a/esm/rspack/webpack.config.mjs
+++ /dev/null
@@ -1,120 +0,0 @@
-import { dirname } from 'node:path';
-import { fileURLToPath } from 'node:url';
-import HtmlWebpackPlugin from 'html-webpack-plugin';
-import enhancedFederation from '@module-federation/enhanced';
-const { ModuleFederationPlugin } = enhancedFederation;
-import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-
-// Target browsers, see: https://github.com/browserslist/browserslist
-const targets = ['chrome >= 87', 'edge >= 88', 'firefox >= 78', 'safari >= 14'];
-
-export default {
- context: __dirname,
- entry: {
- main: './src/main.js',
- app: './src/other.jsx',
- apeep: './src/App.jsx',
- },
- mode: 'development',
- resolve: {
- extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
- },
- devServer: {
- devMiddleware: {
- writeToDisk: true
- },
- hot: true,
- port: 8080,
- },
- module: {
- rules: [
- {
- test: /\.svg$/,
- type: 'asset',
- },
- {
- test: /\.(jsx?|tsx?)$/,
- exclude: /node_modules/,
- use: [
- {
- loader: 'swc-loader',
- options: {
- jsc: {
- parser: {
- syntax: 'typescript',
- tsx: true,
- },
- transform: {
- react: {
- runtime: 'automatic',
- development: true,
- refresh: true,
- },
- },
- },
- env: { targets },
- },
- },
- ],
- },
- {
- test: /\.css$/,
- use: [
- 'style-loader',
- 'css-loader',
- ],
- },
- ],
- },
- optimization:{
- runtimeChunk: 'single'
- },
- plugins: [
- new ModuleFederationPlugin({
- name: 'rspack',
- runtime: false,
- filename: 'remoteEntry.js',
- exposes: {
- './tjing': './src/App.jsx'
- },
- shared: {
- react: {
- singleton: true,
- },
- "react/jsx-dev-runtime": {
- singleton: true,
- },
- "react/jsx-runtime": {
- singleton: true,
- },
- "react-dom": {
- singleton: true,
- }
- },
- }),
- new HtmlWebpackPlugin({
- template: './index.html',
- scriptLoading: 'module',
- excludeChunks: ['rspack','app']
- }),
- new ReactRefreshWebpackPlugin(),
- ],
- devtool: false,
- experiments: {
- outputModule: true,
- },
- externalsType: 'module',
- output: {
- publicPath: 'auto',
- chunkFormat: 'module',
- chunkLoading: 'import',
- workerChunkLoading: 'import',
- wasmLoading: 'fetch',
- library: { type: 'module' },
- module: true,
- filename: '[name].js',
- chunkFilename: '[name].js',
- },
-};
diff --git a/package.json b/package.json
index d455ea669a3..061785f6be7 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
}
},
"devDependencies": {
+ "@playwright/test": "^1.54.2",
"@shelex/cypress-allure-plugin": "2.40.2",
"@types/node": "20.9.0",
"abbrev": "2.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a6780c60d88..81a65d36405 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13,6 +13,9 @@ importers:
.:
devDependencies:
+ '@playwright/test':
+ specifier: ^1.54.2
+ version: 1.54.2
'@shelex/cypress-allure-plugin':
specifier: 2.40.2
version: 2.40.2
@@ -85,6 +88,9 @@ importers:
advanced-api/automatic-vendor-sharing:
devDependencies:
+ '@playwright/test':
+ specifier: ^1.54.2
+ version: 1.54.2
wait-on:
specifier: 7.2.0
version: 7.2.0
@@ -92,11 +98,11 @@ importers:
advanced-api/automatic-vendor-sharing/app1:
dependencies:
react:
- specifier: ^16.13.0
- version: 16.14.0
+ specifier: ^18.3.1
+ version: 18.3.1
react-dom:
- specifier: ^16.13.0
- version: 16.14.0(react@16.14.0)
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
devDependencies:
'@babel/core':
specifier: 7.24.7
@@ -104,9 +110,12 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
- specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ specifier: ^0.17.1
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
'@rspack/cli':
specifier: 1.4.11
version: 1.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
@@ -116,6 +125,12 @@ importers:
'@rspack/dev-server':
specifier: 1.1.3
version: 1.1.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -125,6 +140,9 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ typescript:
+ specifier: ^5.5.4
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -138,11 +156,11 @@ importers:
advanced-api/automatic-vendor-sharing/app2:
dependencies:
react:
- specifier: ^16.13.0
- version: 16.14.0
+ specifier: ^18.3.1
+ version: 18.3.1
react-dom:
- specifier: ^16.13.0
- version: 16.14.0(react@16.14.0)
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
devDependencies:
'@babel/core':
specifier: 7.24.7
@@ -150,9 +168,12 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
- specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ specifier: ^0.17.1
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
'@rspack/cli':
specifier: 1.4.11
version: 1.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
@@ -162,6 +183,12 @@ importers:
'@rspack/dev-server':
specifier: 1.1.3
version: 1.1.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -171,6 +198,9 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ typescript:
+ specifier: ^5.5.4
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -195,6 +225,9 @@ importers:
advanced-api/dynamic-remotes-runtime-environment-variables:
devDependencies:
+ '@playwright/test':
+ specifier: ^1.54.2
+ version: 1.54.2
wait-on:
specifier: 7.2.0
version: 7.2.0
@@ -202,14 +235,14 @@ importers:
advanced-api/dynamic-remotes-runtime-environment-variables/host:
dependencies:
moment:
- specifier: ^2.29.4
+ specifier: ^2.30.1
version: 2.30.1
react:
- specifier: ^16.13.0
- version: 16.14.0
+ specifier: ^18.3.1
+ version: 18.3.1
react-dom:
- specifier: ^16.13.0
- version: 16.14.0(react@16.14.0)
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
devDependencies:
'@babel/core':
specifier: 7.24.7
@@ -219,7 +252,10 @@ importers:
version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ '@module-federation/retry-plugin':
+ specifier: 0.17.1
+ version: 0.17.1
'@module-federation/runtime':
specifier: 0.17.1
version: 0.17.1
@@ -253,6 +289,9 @@ importers:
webpack-dev-server:
specifier: 5.0.4
version: 5.0.4(webpack-cli@5.1.4)(webpack@5.101.0)
+ webpack-merge:
+ specifier: 6.0.1
+ version: 6.0.1
advanced-api/dynamic-remotes-runtime-environment-variables/remote:
dependencies:
@@ -260,14 +299,14 @@ importers:
specifier: 12.0.2
version: 12.0.2(webpack@5.101.0)
moment:
- specifier: ^2.29.4
+ specifier: ^2.30.1
version: 2.30.1
react:
- specifier: ^16.13.0
- version: 16.14.0
+ specifier: ^18.3.1
+ version: 18.3.1
react-dom:
- specifier: ^16.13.0
- version: 16.14.0(react@16.14.0)
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
devDependencies:
'@babel/core':
specifier: 7.24.7
@@ -277,7 +316,10 @@ importers:
version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ '@module-federation/retry-plugin':
+ specifier: 0.17.1
+ version: 0.17.1
'@rspack/cli':
specifier: 1.4.11
version: 1.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
@@ -305,9 +347,15 @@ importers:
webpack-dev-server:
specifier: 5.0.4
version: 5.0.4(webpack-cli@5.1.4)(webpack@5.101.0)
+ webpack-merge:
+ specifier: 6.0.1
+ version: 6.0.1
advanced-api/dynamic-remotes-synchronous-imports:
devDependencies:
+ '@playwright/test':
+ specifier: ^1.54.2
+ version: 1.54.2
wait-on:
specifier: 7.2.0
version: 7.2.0
@@ -318,11 +366,11 @@ importers:
specifier: ^2.29.4
version: 2.30.1
react:
- specifier: ^16.13.0
- version: 16.14.0
+ specifier: ^18.3.1
+ version: 18.3.1
react-dom:
- specifier: ^16.13.0
- version: 16.14.0(react@16.14.0)
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
devDependencies:
'@babel/core':
specifier: 7.24.7
@@ -330,9 +378,18 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -342,6 +399,9 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ typescript:
+ specifier: ^5.5.3
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -358,14 +418,14 @@ importers:
specifier: ^2.29.4
version: 2.30.1
react:
- specifier: ^16.13.0
- version: 16.14.0
+ specifier: ^18.3.1
+ version: 18.3.1
react-dom:
- specifier: ^16.13.0
- version: 16.14.0(react@16.14.0)
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
react-redux:
specifier: ^7.2.0
- version: 7.2.9(react-dom@16.14.0(react@16.14.0))(react@16.14.0)
+ version: 7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
redux:
specifier: ^4.2.1
version: 4.2.1
@@ -376,9 +436,18 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -388,6 +457,9 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ typescript:
+ specifier: ^5.5.3
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -413,9 +485,12 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
'@module-federation/runtime':
specifier: 0.17.1
version: 0.17.1
@@ -428,6 +503,12 @@ importers:
'@rspack/dev-server':
specifier: 1.1.3
version: 1.1.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -437,6 +518,12 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ ts-loader:
+ specifier: ^9.5.1
+ version: 9.5.1(typescript@5.6.2)(webpack@5.101.0)
+ typescript:
+ specifier: ^5.5.4
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -465,9 +552,12 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
'@rspack/cli':
specifier: 1.4.11
version: 1.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
@@ -477,6 +567,12 @@ importers:
'@rspack/dev-server':
specifier: 1.1.3
version: 1.1.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -486,6 +582,12 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ ts-loader:
+ specifier: ^9.5.1
+ version: 9.5.1(typescript@5.6.2)(webpack@5.101.0)
+ typescript:
+ specifier: ^5.5.4
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -520,9 +622,12 @@ importers:
'@babel/preset-react':
specifier: 7.24.7
version: 7.24.7(@babel/core@7.24.7)
+ '@babel/preset-typescript':
+ specifier: ^7.24.7
+ version: 7.24.7(@babel/core@7.24.7)
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0)
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)
'@rspack/cli':
specifier: 1.4.11
version: 1.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
@@ -532,6 +637,12 @@ importers:
'@rspack/dev-server':
specifier: 1.1.3
version: 1.1.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.101.0)
+ '@types/react':
+ specifier: 18.3.10
+ version: 18.3.10
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
babel-loader:
specifier: 9.1.3
version: 9.1.3(@babel/core@7.24.7)(webpack@5.101.0)
@@ -541,6 +652,12 @@ importers:
serve:
specifier: 14.2.3
version: 14.2.3
+ ts-loader:
+ specifier: ^9.5.1
+ version: 9.5.1(typescript@5.6.2)(webpack@5.101.0)
+ typescript:
+ specifier: ^5.5.4
+ version: 5.6.2
webpack:
specifier: 5.101.0
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
@@ -874,7 +991,7 @@ importers:
version: 2.68.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@module-federation/modern-js':
specifier: 0.17.1
- version: 0.17.1(@rsbuild/core@1.4.11)(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
react:
specifier: ~18.3.0
version: 18.3.1
@@ -887,10 +1004,10 @@ importers:
version: 2.59.0(typescript@5.9.2)
'@modern-js/app-tools':
specifier: 2.68.6
- version: 2.68.6(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5))(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@5.9.2)(webpack-dev-server@5.2.2(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)))(webpack-hot-middleware@2.26.1)
+ version: 2.68.6(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.3.1(react@18.3.1))(react-is@19.1.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@5.9.2)(webpack-dev-server@5.2.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)
'@modern-js/builder-rspack-provider':
specifier: 2.46.1
- version: 2.46.1(@babel/traverse@7.28.0)(@rsbuild/core@1.4.11)(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/express@4.17.21)(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(typescript@5.9.2)
+ version: 2.46.1(@babel/traverse@7.28.0)(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/express@4.17.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(typescript@5.9.2)
'@modern-js/eslint-config':
specifier: 2.59.0
version: 2.59.0(typescript@5.9.2)
@@ -899,7 +1016,7 @@ importers:
version: 2.68.6
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
husky:
specifier: 9.0.11
version: 9.0.11
@@ -920,7 +1037,7 @@ importers:
version: 2.68.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@module-federation/modern-js':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ version: 0.17.1(@rsbuild/core@1.4.11)(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
react:
specifier: ~18.3.0
version: 18.3.1
@@ -933,10 +1050,10 @@ importers:
version: 2.59.0(typescript@5.9.2)
'@modern-js/app-tools':
specifier: 2.68.6
- version: 2.68.6(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.3.1(react@18.3.1))(react-is@19.1.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@5.9.2)(webpack-dev-server@5.2.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)
+ version: 2.68.6(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5))(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@5.9.2)(webpack-dev-server@5.2.2(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)))(webpack-hot-middleware@2.26.1)
'@modern-js/builder-rspack-provider':
specifier: 2.46.1
- version: 2.46.1(@babel/traverse@7.28.0)(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/express@4.17.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(typescript@5.9.2)
+ version: 2.46.1(@babel/traverse@7.28.0)(@rsbuild/core@1.4.11)(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/express@4.17.21)(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@22.17.0)(typescript@5.9.2))(tsconfig-paths@4.2.0)(typescript@5.9.2)
'@modern-js/eslint-config':
specifier: 2.59.0
version: 2.59.0(typescript@5.9.2)
@@ -945,7 +1062,7 @@ importers:
version: 2.68.6
'@module-federation/enhanced':
specifier: 0.17.1
- version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ version: 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
husky:
specifier: 9.0.11
version: 9.0.11
@@ -5758,7 +5875,7 @@ importers:
version: 2.57.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@module-federation/modern-js':
specifier: 0.17.1
- version: 0.17.1(@rsbuild/core@1.4.12)(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@4.9.5)(vue-tsc@1.8.27(typescript@4.9.5))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ version: 0.17.1(@rsbuild/core@1.0.1-beta.3)(@rspack/core@1.4.11(@swc/helpers@0.5.11))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@4.9.5)(vue-tsc@1.8.27(typescript@4.9.5))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))
react:
specifier: ~18.3.0
version: 18.3.1
@@ -5771,7 +5888,7 @@ importers:
version: 2.57.0(typescript@4.9.5)
'@modern-js/app-tools':
specifier: 2.57.0
- version: 2.57.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.6.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.3.1(react@18.3.1))(react-is@19.1.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@16.18.101)(typescript@4.9.5))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)
+ version: 2.57.0(@rspack/core@1.4.11(@swc/helpers@0.5.11))(@swc/core@1.13.3(@swc/helpers@0.5.11))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))(encoding@0.1.13)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.24.7)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.11))(@swc/wasm@1.13.3)(@types/node@16.18.101)(typescript@4.9.5))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19)))(webpack-hot-middleware@2.26.1)
'@modern-js/eslint-config':
specifier: 2.57.0
version: 2.57.0(typescript@4.9.5)
@@ -5813,7 +5930,7 @@ importers:
version: 2.57.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@module-federation/modern-js':
specifier: 0.17.1
- version: 0.17.1(@rsbuild/core@1.0.1-beta.3)(@rspack/core@1.4.11(@swc/helpers@0.5.11))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@4.9.5)(vue-tsc@1.8.27(typescript@4.9.5))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))
+ version: 0.17.1(@rsbuild/core@1.4.12)(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@4.9.5)(vue-tsc@1.8.27(typescript@4.9.5))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
react:
specifier: ^18.2.0
version: 18.3.1
@@ -5826,7 +5943,7 @@ importers:
version: 2.57.0(typescript@4.9.5)
'@modern-js/app-tools':
specifier: 2.57.0
- version: 2.57.0(@rspack/core@1.4.11(@swc/helpers@0.5.11))(@swc/core@1.13.3(@swc/helpers@0.5.11))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))(encoding@0.1.13)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.24.7)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.11))(@swc/wasm@1.13.3)(@types/node@16.18.101)(typescript@4.9.5))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19)))(webpack-hot-middleware@2.26.1)
+ version: 2.57.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.6.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.3.1(react@18.3.1))(react-is@19.1.1)(react@18.3.1))(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@16.18.101)(typescript@4.9.5))(tsconfig-paths@4.2.0)(type-fest@2.19.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)
'@modern-js/eslint-config':
specifier: 2.57.0
version: 2.57.0(typescript@4.9.5)
@@ -6767,7 +6884,7 @@ importers:
devDependencies:
lerna:
specifier: 8.1.6
- version: 8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)
+ version: 8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)
wait-on:
specifier: 7.2.0
version: 7.2.0
@@ -12328,6 +12445,9 @@ packages:
react-dom:
optional: true
+ '@module-federation/retry-plugin@0.17.1':
+ resolution: {integrity: sha512-lI/y0C5PbABiD31I0LYHTN3CkHDXj9uba/wgZ2IiiKi6wY0VWLpZ/A+xn79hGS0ac8ANp2MHofpgIWSRxBl/XA==}
+
'@module-federation/rsbuild-plugin@0.17.1':
resolution: {integrity: sha512-+Wd6X34A7cMDPNj59EdQyFnx9tdbjSJL3+a1oIqq8WGA52+1uACNCkEzXxQW/Q1eoFbtZfk/jduDmz97rx3c2A==}
engines: {node: '>=16.0.0'}
@@ -28085,7 +28205,7 @@ snapshots:
eslint-visitor-keys: 2.1.0
semver: 6.3.1
- '@babel/eslint-plugin@7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.28.0)(eslint@8.57.1))(eslint@8.57.1)':
+ '@babel/eslint-plugin@7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.24.7)(eslint@8.57.1))(eslint@8.57.1)':
dependencies:
'@babel/eslint-parser': 7.24.7(@babel/core@7.24.7)(eslint@8.57.1)
eslint: 8.57.1
@@ -30126,7 +30246,7 @@ snapshots:
'@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.22.17)
'@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.22.17)
'@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.22.17)
- '@babel/plugin-transform-modules-commonjs': 7.22.15(@babel/core@7.22.17)
+ '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.22.17)
'@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.22.17)
'@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.22.17)
'@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.22.17)
@@ -32684,12 +32804,12 @@ snapshots:
'@leichtgewicht/ip-codec@2.0.5': {}
- '@lerna/create@8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.9.2)':
+ '@lerna/create@8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.6.2)':
dependencies:
'@npmcli/arborist': 7.5.3
'@npmcli/package-json': 5.2.0
'@npmcli/run-script': 8.1.0
- '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
'@octokit/plugin-enterprise-rest': 6.0.1
'@octokit/rest': 19.0.11(encoding@0.1.13)
aproba: 2.0.0
@@ -32702,7 +32822,89 @@ snapshots:
console-control-strings: 1.1.0
conventional-changelog-core: 5.0.1
conventional-recommended-bump: 7.0.1
- cosmiconfig: 8.3.6(typescript@5.9.2)
+ cosmiconfig: 8.3.6(typescript@5.6.2)
+ dedent: 1.5.3(babel-plugin-macros@3.1.0)
+ execa: 5.0.0
+ fs-extra: 11.3.0
+ get-stream: 6.0.0
+ git-url-parse: 14.0.0
+ glob-parent: 6.0.2
+ globby: 11.1.0
+ graceful-fs: 4.2.11
+ has-unicode: 2.0.1
+ ini: 1.3.8
+ init-package-json: 6.0.3
+ inquirer: 8.2.6
+ is-ci: 3.0.1
+ is-stream: 2.0.0
+ js-yaml: 4.1.0
+ libnpmpublish: 9.0.9
+ load-json-file: 6.2.0
+ lodash: 4.17.21
+ make-dir: 4.0.0
+ minimatch: 3.0.5
+ multimatch: 5.0.0
+ node-fetch: 2.6.7(encoding@0.1.13)
+ npm-package-arg: 11.0.2
+ npm-packlist: 8.0.2
+ npm-registry-fetch: 17.1.0
+ nx: 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
+ p-map: 4.0.0
+ p-map-series: 2.1.0
+ p-queue: 6.6.2
+ p-reduce: 2.1.0
+ pacote: 18.0.6
+ pify: 5.0.0
+ read-cmd-shim: 4.0.0
+ resolve-from: 5.0.0
+ rimraf: 4.4.1
+ semver: 7.6.3
+ set-blocking: 2.0.0
+ signal-exit: 3.0.7
+ slash: 3.0.0
+ ssri: 10.0.6
+ string-width: 4.2.3
+ strong-log-transformer: 2.1.0
+ tar: 6.2.1
+ temp-dir: 1.0.0
+ upath: 2.0.1
+ uuid: 10.0.0
+ validate-npm-package-license: 3.0.4
+ validate-npm-package-name: 5.0.1
+ wide-align: 1.1.5
+ write-file-atomic: 5.0.1
+ write-pkg: 4.0.0
+ yargs: 17.7.2
+ yargs-parser: 21.1.1
+ transitivePeerDependencies:
+ - '@swc-node/register'
+ - '@swc/core'
+ - babel-plugin-macros
+ - bluebird
+ - debug
+ - encoding
+ - supports-color
+ - typescript
+
+ '@lerna/create@8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.6.2)':
+ dependencies:
+ '@npmcli/arborist': 7.5.3
+ '@npmcli/package-json': 5.2.0
+ '@npmcli/run-script': 8.1.0
+ '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@octokit/plugin-enterprise-rest': 6.0.1
+ '@octokit/rest': 19.0.11(encoding@0.1.13)
+ aproba: 2.0.0
+ byte-size: 8.1.1
+ chalk: 4.1.0
+ clone-deep: 4.0.1
+ cmd-shim: 6.0.3
+ color-support: 1.1.3
+ columnify: 1.6.0
+ console-control-strings: 1.1.0
+ conventional-changelog-core: 5.0.1
+ conventional-recommended-bump: 7.0.1
+ cosmiconfig: 8.3.6(typescript@5.6.2)
dedent: 1.5.3(babel-plugin-macros@3.1.0)
execa: 5.0.0
fs-extra: 11.3.0
@@ -32766,7 +32968,7 @@ snapshots:
- supports-color
- typescript
- '@lerna/create@8.1.8(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.9.2)':
+ '@lerna/create@8.1.8(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.6.2)':
dependencies:
'@npmcli/arborist': 7.5.4
'@npmcli/package-json': 5.2.0
@@ -32784,7 +32986,7 @@ snapshots:
console-control-strings: 1.1.0
conventional-changelog-core: 5.0.1
conventional-recommended-bump: 7.0.1
- cosmiconfig: 8.3.6(typescript@5.9.2)
+ cosmiconfig: 8.3.6(typescript@5.6.2)
dedent: 1.5.3(babel-plugin-macros@3.1.0)
execa: 5.0.0
fs-extra: 11.3.0
@@ -33100,7 +33302,7 @@ snapshots:
dependencies:
'@babel/core': 7.24.7
'@babel/eslint-parser': 7.24.7(@babel/core@7.24.7)(eslint@8.57.1)
- '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.28.0)(eslint@8.57.1))(eslint@8.57.1)
+ '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.24.7)(eslint@8.57.1))(eslint@8.57.1)
'@rsbuild/babel-preset': 0.7.10(@rsbuild/core@0.7.10)(@swc/helpers@0.5.17)
'@rsbuild/core': 0.7.10
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3)
@@ -33127,7 +33329,7 @@ snapshots:
dependencies:
'@babel/core': 7.24.7
'@babel/eslint-parser': 7.24.7(@babel/core@7.24.7)(eslint@8.57.1)
- '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.28.0)(eslint@8.57.1))(eslint@8.57.1)
+ '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.24.7)(eslint@8.57.1))(eslint@8.57.1)
'@rsbuild/babel-preset': 0.7.10(@rsbuild/core@0.7.10)(@swc/helpers@0.5.17)
'@rsbuild/core': 0.7.10
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
@@ -33154,7 +33356,7 @@ snapshots:
dependencies:
'@babel/core': 7.24.7
'@babel/eslint-parser': 7.24.7(@babel/core@7.24.7)(eslint@8.57.1)
- '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.28.0)(eslint@8.57.1))(eslint@8.57.1)
+ '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.24.7)(eslint@8.57.1))(eslint@8.57.1)
'@rsbuild/babel-preset': 0.7.10(@rsbuild/core@0.7.10)(@swc/helpers@0.5.3)
'@rsbuild/core': 0.7.10
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
@@ -33181,7 +33383,7 @@ snapshots:
dependencies:
'@babel/core': 7.24.7
'@babel/eslint-parser': 7.24.7(@babel/core@7.24.7)(eslint@8.57.1)
- '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.28.0)(eslint@8.57.1))(eslint@8.57.1)
+ '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.24.7)(eslint@8.57.1))(eslint@8.57.1)
'@modern-js/babel-preset': 2.57.0(@rsbuild/core@1.0.1-beta.3)
'@rsbuild/core': 1.0.1-beta.3
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)
@@ -33207,7 +33409,7 @@ snapshots:
dependencies:
'@babel/core': 7.24.7
'@babel/eslint-parser': 7.24.7(@babel/core@7.24.7)(eslint@8.57.1)
- '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.28.0)(eslint@8.57.1))(eslint@8.57.1)
+ '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.24.7(@babel/core@7.24.7)(eslint@8.57.1))(eslint@8.57.1)
'@modern-js/babel-preset': 2.59.0(@rsbuild/core@1.0.1-rc.4)
'@rsbuild/core': 1.0.1-rc.4
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
@@ -33881,7 +34083,7 @@ snapshots:
react-refresh: 0.14.2
rspack-manifest-plugin: 5.0.0-alpha0(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
style-loader: 3.3.3(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
transitivePeerDependencies:
- '@babel/traverse'
- '@parcel/css'
@@ -34101,7 +34303,7 @@ snapshots:
line-diff: 2.1.1
postcss: 8.4.31
source-map: 0.7.4
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
webpack-sources: 3.2.3
zod: 3.25.76
zod-validation-error: 1.2.0(zod@3.25.76)
@@ -34597,7 +34799,7 @@ snapshots:
dependencies:
'@swc/helpers': 0.5.17
esbuild: 0.25.5
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
transitivePeerDependencies:
- '@swc/core'
- uglify-js
@@ -35091,7 +35293,7 @@ snapshots:
'@babel/register': 7.27.1(@babel/core@7.24.7)
'@modern-js/prod-server': 2.46.1(@types/express@4.17.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@modern-js/runtime-utils': 2.46.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@modern-js/server-utils': 2.46.1(@babel/traverse@7.28.0)(@rsbuild/core@1.4.12)
+ '@modern-js/server-utils': 2.46.1(@babel/traverse@7.28.0)(@rsbuild/core@1.4.11)
'@modern-js/types': 2.46.1
'@modern-js/utils': 2.46.1
'@swc/helpers': 0.5.3
@@ -35754,7 +35956,7 @@ snapshots:
terser-webpack-plugin: 5.3.14(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
ts-deepmerge: 7.0.2
ts-loader: 9.4.4(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
transitivePeerDependencies:
- '@parcel/css'
@@ -35833,7 +36035,7 @@ snapshots:
terser-webpack-plugin: 5.3.14(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
ts-deepmerge: 7.0.2
ts-loader: 9.4.4(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
transitivePeerDependencies:
- '@parcel/css'
@@ -36410,6 +36612,35 @@ snapshots:
- supports-color
- utf-8-validate
+ '@module-federation/enhanced@0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))(webpack@5.101.0)':
+ dependencies:
+ '@module-federation/bridge-react-webpack-plugin': 0.17.1
+ '@module-federation/cli': 0.17.1(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))
+ '@module-federation/data-prefetch': 0.17.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@module-federation/dts-plugin': 0.17.1(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))
+ '@module-federation/error-codes': 0.17.1
+ '@module-federation/inject-external-runtime-core-plugin': 0.17.1(@module-federation/runtime-tools@0.17.1)
+ '@module-federation/managers': 0.17.1
+ '@module-federation/manifest': 0.17.1(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))
+ '@module-federation/rspack': 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(typescript@5.6.2)(vue-tsc@1.8.27(typescript@5.6.2))
+ '@module-federation/runtime-tools': 0.17.1
+ '@module-federation/sdk': 0.17.1
+ btoa: 1.2.1
+ schema-utils: 4.3.2
+ upath: 2.0.1
+ optionalDependencies:
+ typescript: 5.6.2
+ vue-tsc: 1.8.27(typescript@5.6.2)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
+ transitivePeerDependencies:
+ - '@rspack/core'
+ - bufferutil
+ - debug
+ - react
+ - react-dom
+ - supports-color
+ - utf-8-validate
+
'@module-federation/enhanced@0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)(vue-tsc@1.8.27(typescript@5.9.2))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))':
dependencies:
'@module-federation/bridge-react-webpack-plugin': 0.17.1
@@ -36429,7 +36660,7 @@ snapshots:
optionalDependencies:
typescript: 5.9.2
vue-tsc: 1.8.27(typescript@5.9.2)
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
transitivePeerDependencies:
- '@rspack/core'
- bufferutil
@@ -37098,7 +37329,7 @@ snapshots:
btoa: 1.2.1
encoding: 0.1.13
node-fetch: 2.7.0(encoding@0.1.13)
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
optionalDependencies:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
@@ -37240,6 +37471,10 @@ snapshots:
- utf-8-validate
- vue-tsc
+ '@module-federation/retry-plugin@0.17.1':
+ dependencies:
+ '@module-federation/sdk': 0.17.1
+
'@module-federation/rsbuild-plugin@0.17.1(@rsbuild/core@1.0.1-beta.3)(@rspack/core@1.4.11(@swc/helpers@0.5.11))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@4.9.5)(vue-tsc@1.8.27(typescript@4.9.5))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))':
dependencies:
'@module-federation/enhanced': 0.17.1(@rspack/core@1.4.11(@swc/helpers@0.5.11))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@4.9.5)(vue-tsc@1.8.27(typescript@4.9.5))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))
@@ -38019,9 +38254,9 @@ snapshots:
transitivePeerDependencies:
- nx
- '@nrwl/devkit@19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))':
+ '@nrwl/devkit@19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))':
dependencies:
- '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
transitivePeerDependencies:
- nx
@@ -38184,6 +38419,15 @@ snapshots:
- '@swc/core'
- debug
+ '@nrwl/tao@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))':
+ dependencies:
+ nx: 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - '@swc-node/register'
+ - '@swc/core'
+ - debug
+
'@nrwl/tao@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))':
dependencies:
nx: 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
@@ -38332,14 +38576,14 @@ snapshots:
tslib: 2.8.1
yargs-parser: 21.1.1
- '@nx/devkit@19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))':
+ '@nx/devkit@19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))':
dependencies:
- '@nrwl/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@nrwl/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
ejs: 3.1.10
enquirer: 2.3.6
ignore: 5.3.2
minimatch: 9.0.3
- nx: 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
+ nx: 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
semver: 7.6.3
tmp: 0.2.3
tslib: 2.8.1
@@ -39179,7 +39423,7 @@ snapshots:
react-refresh: 0.14.2
schema-utils: 4.3.2
source-map: 0.7.6
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
optionalDependencies:
'@types/webpack': 5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
type-fest: 2.19.0
@@ -40422,7 +40666,7 @@ snapshots:
picocolors: 1.1.1
reduce-configs: 1.1.0
tsconfig-paths-webpack-plugin: 4.2.0
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
transitivePeerDependencies:
- '@rspack/core'
- '@swc/core'
@@ -41801,6 +42045,22 @@ snapshots:
- supports-color
optional: true
+ '@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2)':
+ dependencies:
+ '@swc-node/core': 1.13.3(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)
+ '@swc-node/sourcemap-support': 0.5.1
+ '@swc/core': 1.13.3(@swc/helpers@0.5.17)
+ colorette: 2.0.20
+ debug: 4.4.1(supports-color@8.1.1)
+ oxc-resolver: 1.12.0
+ pirates: 4.0.7
+ tslib: 2.8.1
+ typescript: 5.6.2
+ transitivePeerDependencies:
+ - '@swc/types'
+ - supports-color
+ optional: true
+
'@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2)':
dependencies:
'@swc-node/core': 1.13.3(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)
@@ -42461,7 +42721,7 @@ snapshots:
dependencies:
'@types/node': 18.19.39
tapable: 2.2.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
transitivePeerDependencies:
- '@swc/core'
- esbuild
@@ -44862,7 +45122,7 @@ snapshots:
'@babel/core': 7.28.0
find-cache-dir: 4.0.0
schema-utils: 4.3.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
babel-loader@9.2.1(@babel/core@7.28.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))):
dependencies:
@@ -46269,7 +46529,7 @@ snapshots:
normalize-path: 3.0.0
schema-utils: 4.3.2
serialize-javascript: 6.0.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
copy-webpack-plugin@11.0.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19)):
dependencies:
@@ -46395,6 +46655,15 @@ snapshots:
optionalDependencies:
typescript: 5.5.3
+ cosmiconfig@8.3.6(typescript@5.6.2):
+ dependencies:
+ import-fresh: 3.3.1
+ js-yaml: 4.1.0
+ parse-json: 5.2.0
+ path-type: 4.0.0
+ optionalDependencies:
+ typescript: 5.6.2
+
cosmiconfig@8.3.6(typescript@5.9.2):
dependencies:
import-fresh: 3.3.1
@@ -46758,7 +47027,7 @@ snapshots:
postcss: 8.4.47
schema-utils: 4.3.2
serialize-javascript: 6.0.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
optionalDependencies:
esbuild: 0.25.5
@@ -49701,7 +49970,7 @@ snapshots:
semver: 7.6.3
tapable: 2.2.2
typescript: 5.9.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
fork-ts-checker-webpack-plugin@8.0.0(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)):
dependencies:
@@ -50525,7 +50794,7 @@ snapshots:
tapable: 2.2.2
optionalDependencies:
'@rspack/core': 1.4.11(@swc/helpers@0.5.17)
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)):
dependencies:
@@ -52537,13 +52806,104 @@ snapshots:
lazy@1.0.11: {}
+ lerna@8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13):
+ dependencies:
+ '@lerna/create': 8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.6.2)
+ '@npmcli/arborist': 7.5.3
+ '@npmcli/package-json': 5.2.0
+ '@npmcli/run-script': 8.1.0
+ '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@octokit/plugin-enterprise-rest': 6.0.1
+ '@octokit/rest': 19.0.11(encoding@0.1.13)
+ aproba: 2.0.0
+ byte-size: 8.1.1
+ chalk: 4.1.0
+ clone-deep: 4.0.1
+ cmd-shim: 6.0.3
+ color-support: 1.1.3
+ columnify: 1.6.0
+ console-control-strings: 1.1.0
+ conventional-changelog-angular: 7.0.0
+ conventional-changelog-core: 5.0.1
+ conventional-recommended-bump: 7.0.1
+ cosmiconfig: 8.3.6(typescript@5.6.2)
+ dedent: 1.5.3(babel-plugin-macros@3.1.0)
+ envinfo: 7.13.0
+ execa: 5.0.0
+ fs-extra: 11.3.0
+ get-port: 5.1.1
+ get-stream: 6.0.0
+ git-url-parse: 14.0.0
+ glob-parent: 6.0.2
+ globby: 11.1.0
+ graceful-fs: 4.2.11
+ has-unicode: 2.0.1
+ import-local: 3.1.0
+ ini: 1.3.8
+ init-package-json: 6.0.3
+ inquirer: 8.2.6
+ is-ci: 3.0.1
+ is-stream: 2.0.0
+ jest-diff: 29.7.0
+ js-yaml: 4.1.0
+ libnpmaccess: 8.0.6
+ libnpmpublish: 9.0.9
+ load-json-file: 6.2.0
+ lodash: 4.17.21
+ make-dir: 4.0.0
+ minimatch: 3.0.5
+ multimatch: 5.0.0
+ node-fetch: 2.6.7(encoding@0.1.13)
+ npm-package-arg: 11.0.2
+ npm-packlist: 8.0.2
+ npm-registry-fetch: 17.1.0
+ nx: 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
+ p-map: 4.0.0
+ p-map-series: 2.1.0
+ p-pipe: 3.1.0
+ p-queue: 6.6.2
+ p-reduce: 2.1.0
+ p-waterfall: 2.1.1
+ pacote: 18.0.6
+ pify: 5.0.0
+ read-cmd-shim: 4.0.0
+ resolve-from: 5.0.0
+ rimraf: 4.4.1
+ semver: 7.6.3
+ set-blocking: 2.0.0
+ signal-exit: 3.0.7
+ slash: 3.0.0
+ ssri: 10.0.6
+ string-width: 4.2.3
+ strong-log-transformer: 2.1.0
+ tar: 6.2.1
+ temp-dir: 1.0.0
+ typescript: 5.6.2
+ upath: 2.0.1
+ uuid: 10.0.0
+ validate-npm-package-license: 3.0.4
+ validate-npm-package-name: 5.0.1
+ wide-align: 1.1.5
+ write-file-atomic: 5.0.1
+ write-pkg: 4.0.0
+ yargs: 17.7.2
+ yargs-parser: 21.1.1
+ transitivePeerDependencies:
+ - '@swc-node/register'
+ - '@swc/core'
+ - babel-plugin-macros
+ - bluebird
+ - debug
+ - encoding
+ - supports-color
+
lerna@8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13):
dependencies:
- '@lerna/create': 8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.9.2)
+ '@lerna/create': 8.1.6(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.6.2)
'@npmcli/arborist': 7.5.3
'@npmcli/package-json': 5.2.0
'@npmcli/run-script': 8.1.0
- '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@nx/devkit': 19.8.14(nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17)))
'@octokit/plugin-enterprise-rest': 6.0.1
'@octokit/rest': 19.0.11(encoding@0.1.13)
aproba: 2.0.0
@@ -52557,7 +52917,7 @@ snapshots:
conventional-changelog-angular: 7.0.0
conventional-changelog-core: 5.0.1
conventional-recommended-bump: 7.0.1
- cosmiconfig: 8.3.6(typescript@5.9.2)
+ cosmiconfig: 8.3.6(typescript@5.6.2)
dedent: 1.5.3(babel-plugin-macros@3.1.0)
envinfo: 7.13.0
execa: 5.0.0
@@ -52609,7 +52969,7 @@ snapshots:
strong-log-transformer: 2.1.0
tar: 6.2.1
temp-dir: 1.0.0
- typescript: 5.9.2
+ typescript: 5.6.2
upath: 2.0.1
uuid: 10.0.0
validate-npm-package-license: 3.0.4
@@ -52630,7 +52990,7 @@ snapshots:
lerna@8.1.8(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13):
dependencies:
- '@lerna/create': 8.1.8(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.9.2)
+ '@lerna/create': 8.1.8(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.5.3))(@swc/core@1.13.3(@swc/helpers@0.5.17))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.6.2)
'@npmcli/arborist': 7.5.4
'@npmcli/package-json': 5.2.0
'@npmcli/run-script': 8.1.0
@@ -52648,7 +53008,7 @@ snapshots:
conventional-changelog-angular: 7.0.0
conventional-changelog-core: 5.0.1
conventional-recommended-bump: 7.0.1
- cosmiconfig: 8.3.6(typescript@5.9.2)
+ cosmiconfig: 8.3.6(typescript@5.6.2)
dedent: 1.5.3(babel-plugin-macros@3.1.0)
envinfo: 7.13.0
execa: 5.0.0
@@ -52701,7 +53061,7 @@ snapshots:
strong-log-transformer: 2.1.0
tar: 6.2.1
temp-dir: 1.0.0
- typescript: 5.9.2
+ typescript: 5.6.2
upath: 2.0.1
uuid: 10.0.0
validate-npm-package-license: 3.0.4
@@ -53641,7 +54001,7 @@ snapshots:
dependencies:
schema-utils: 4.3.2
tapable: 2.2.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
mini-css-extract-plugin@2.9.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)):
dependencies:
@@ -54239,6 +54599,58 @@ snapshots:
transitivePeerDependencies:
- debug
+ nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)):
+ dependencies:
+ '@nrwl/tao': 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
+ '@yarnpkg/lockfile': 1.1.0
+ '@yarnpkg/parsers': 3.0.0-rc.46
+ '@zkochan/js-yaml': 0.0.6
+ axios: 1.7.7
+ chalk: 4.1.2
+ cli-cursor: 3.1.0
+ cli-spinners: 2.6.1
+ cliui: 8.0.1
+ dotenv: 16.3.2
+ dotenv-expand: 10.0.0
+ enquirer: 2.3.6
+ figures: 3.2.0
+ flat: 5.0.2
+ fs-extra: 11.3.0
+ ignore: 5.3.2
+ jest-diff: 29.7.0
+ js-yaml: 4.1.0
+ jsonc-parser: 3.2.0
+ lines-and-columns: 2.0.4
+ minimatch: 9.0.3
+ node-machine-id: 1.1.12
+ npm-run-path: 4.0.1
+ open: 8.4.2
+ ora: 5.3.0
+ semver: 7.6.3
+ string-width: 4.2.3
+ strong-log-transformer: 2.1.0
+ tar-stream: 2.2.0
+ tmp: 0.2.3
+ tsconfig-paths: 4.2.0
+ tslib: 2.8.1
+ yargs: 17.7.2
+ yargs-parser: 21.1.1
+ optionalDependencies:
+ '@nx/nx-darwin-arm64': 17.3.2
+ '@nx/nx-darwin-x64': 17.3.2
+ '@nx/nx-freebsd-x64': 17.3.2
+ '@nx/nx-linux-arm-gnueabihf': 17.3.2
+ '@nx/nx-linux-arm64-gnu': 17.3.2
+ '@nx/nx-linux-arm64-musl': 17.3.2
+ '@nx/nx-linux-x64-gnu': 17.3.2
+ '@nx/nx-linux-x64-musl': 17.3.2
+ '@nx/nx-win32-arm64-msvc': 17.3.2
+ '@nx/nx-win32-x64-msvc': 17.3.2
+ '@swc-node/register': 1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.6.2)
+ '@swc/core': 1.13.3(@swc/helpers@0.5.17)
+ transitivePeerDependencies:
+ - debug
+
nx@17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17)):
dependencies:
'@nrwl/tao': 17.3.2(@swc-node/register@1.10.9(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.2))(@swc/core@1.13.3(@swc/helpers@0.5.17))
@@ -57244,6 +57656,18 @@ snapshots:
optionalDependencies:
react-dom: 16.14.0(react@16.14.0)
+ react-redux@7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ dependencies:
+ '@babel/runtime': 7.28.2
+ '@types/react-redux': 7.1.34
+ hoist-non-react-statics: 3.3.2
+ loose-envify: 1.4.0
+ prop-types: 15.8.1
+ react: 18.3.1
+ react-is: 17.0.2
+ optionalDependencies:
+ react-dom: 18.3.1(react@18.3.1)
+
react-redux@9.2.0(@types/react@18.3.10)(react@18.3.1)(redux@5.0.1):
dependencies:
'@types/use-sync-external-store': 0.0.6
@@ -58114,7 +58538,7 @@ snapshots:
rspack-manifest-plugin@5.0.0-alpha0(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)):
dependencies:
tapable: 2.2.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
webpack-sources: 2.3.1
rspack-manifest-plugin@5.0.0-alpha0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))):
@@ -59119,7 +59543,7 @@ snapshots:
style-loader@3.3.3(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)):
dependencies:
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
style-loader@3.3.3(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))):
dependencies:
@@ -59635,7 +60059,7 @@ snapshots:
schema-utils: 4.3.2
serialize-javascript: 6.0.2
terser: 5.43.1
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
optionalDependencies:
'@swc/core': 1.11.31(@swc/helpers@0.5.17)
esbuild: 0.25.5
@@ -60038,7 +60462,7 @@ snapshots:
micromatch: 4.0.8
semver: 7.6.3
typescript: 5.9.2
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
ts-loader@9.4.4(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))):
dependencies:
@@ -61652,7 +62076,7 @@ snapshots:
range-parser: 1.2.1
schema-utils: 4.3.2
optionalDependencies:
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
optional: true
webpack-dev-middleware@7.4.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))):
@@ -61991,7 +62415,7 @@ snapshots:
webpack-dev-middleware: 7.4.2(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
ws: 8.18.3
optionalDependencies:
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
transitivePeerDependencies:
- bufferutil
- debug
@@ -62126,7 +62550,7 @@ snapshots:
webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)):
dependencies:
typed-assert: 1.0.9
- webpack: 5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5)
optionalDependencies:
html-webpack-plugin: 5.6.3(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
@@ -62148,7 +62572,7 @@ snapshots:
webpack-virtual-modules@0.6.2: {}
- webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5):
+ webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.8
@@ -62172,7 +62596,7 @@ snapshots:
neo-async: 2.6.2
schema-utils: 4.3.2
tapable: 2.2.2
- terser-webpack-plugin: 5.3.14(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
+ terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))
watchpack: 2.4.4
webpack-sources: 3.3.3
transitivePeerDependencies:
@@ -62180,7 +62604,7 @@ snapshots:
- esbuild
- uglify-js
- webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19):
+ webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.17.19):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.8
@@ -62204,7 +62628,7 @@ snapshots:
neo-async: 2.6.2
schema-utils: 4.3.2
tapable: 2.2.2
- terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.11))(esbuild@0.17.19))
+ terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.17.19)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
watchpack: 2.4.4
webpack-sources: 3.3.3
transitivePeerDependencies:
@@ -62212,7 +62636,7 @@ snapshots:
- esbuild
- uglify-js
- webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.17.19):
+ webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.8
@@ -62236,7 +62660,7 @@ snapshots:
neo-async: 2.6.2
schema-utils: 4.3.2
tapable: 2.2.2
- terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.17.19)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
watchpack: 2.4.4
webpack-sources: 3.3.3
transitivePeerDependencies:
@@ -62244,7 +62668,7 @@ snapshots:
- esbuild
- uglify-js
- webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0):
+ webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)(webpack-cli@5.1.4):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.8
@@ -62268,15 +62692,17 @@ snapshots:
neo-async: 2.6.2
schema-utils: 4.3.2
tapable: 2.2.2
- terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)(webpack@5.101.0)
watchpack: 2.4.4
webpack-sources: 3.3.3
+ optionalDependencies:
+ webpack-cli: 5.1.4(webpack@5.101.0)
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
- webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)(webpack-cli@5.1.4):
+ webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.25.5):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.8
@@ -62300,11 +62726,9 @@ snapshots:
neo-async: 2.6.2
schema-utils: 4.3.2
tapable: 2.2.2
- terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)(webpack@5.101.0)
+ terser-webpack-plugin: 5.3.14(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack@5.101.0(@swc/core@1.11.31(@swc/helpers@0.5.17))(esbuild@0.25.5))
watchpack: 2.4.4
webpack-sources: 3.3.3
- optionalDependencies:
- webpack-cli: 5.1.4(webpack@5.101.0)
transitivePeerDependencies:
- '@swc/core'
- esbuild