diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml
index 9169f17f715..20fd30315f4 100644
--- a/.github/workflows/on-pull-request.yml
+++ b/.github/workflows/on-pull-request.yml
@@ -264,22 +264,23 @@ jobs:
npx cypress verify || true
fi
- - name: Install Playwright for projects that need it
+ - name: Install Playwright browsers for projects that use it
run: |
- if [ "${{ matrix.container }}" = "bi-directional" ]; then
- echo "Setting up Playwright for bi-directional example..."
- cd ${{ matrix.container }}
-
- # Check if we need to install Playwright browsers
- if [ ! -d "$HOME/.cache/ms-playwright" ] || [ -z "$(ls -A $HOME/.cache/ms-playwright 2>/dev/null)" ]; then
- echo "Installing Playwright browsers and dependencies..."
- npx playwright install --with-deps chromium
- else
- echo "Playwright browsers already cached, installing system dependencies only..."
- npx playwright install-deps chromium
- fi
-
- cd ..
+ echo "Installing Playwright browsers for projects that use it..."
+
+ # Install Playwright package first if not already available
+ if ! command -v playwright &> /dev/null; then
+ echo "Installing Playwright package..."
+ npm install -g playwright@^1.54.2
+ fi
+
+ # Check if we need to install Playwright browsers
+ if [ ! -d "$HOME/.cache/ms-playwright" ] || [ -z "$(ls -A $HOME/.cache/ms-playwright 2>/dev/null)" ]; then
+ echo "Installing Playwright browsers and dependencies..."
+ npx playwright install --with-deps chromium
+ else
+ echo "Playwright browsers already cached, installing system dependencies only..."
+ npx playwright install-deps chromium
fi
- name: Run sample webpack e2e tests
@@ -298,11 +299,14 @@ jobs:
pnpm --filter "${{ matrix.container }}" e2e:ci
(lsof -i tcp:3000-3999 -i tcp:4000-4999 -i tcp:8080-8100 | awk 'NR!=1 {print $2}' | xargs -r kill) 2> /dev/null
- - name: Create artifacts for Allure report
- id: create-artifacts-allure-report
+ - name: Create artifacts for test reports
+ id: create-artifacts-test-reports
uses: actions/upload-artifact@v4
if: always()
with:
- name: allure-results
- path: 'cypress/results/allure-results'
+ name: test-results-${{ matrix.container }}
+ path: |
+ ${{ matrix.container }}/cypress/results/allure-results
+ ${{ matrix.container }}/playwright-report
+ ${{ matrix.container }}/test-results
retention-days: 7
diff --git a/advanced-api/dynamic-remotes/README.md b/advanced-api/dynamic-remotes/README.md
index a1c03aea2d7..236cb8a4d7f 100644
--- a/advanced-api/dynamic-remotes/README.md
+++ b/advanced-api/dynamic-remotes/README.md
@@ -1,26 +1,427 @@
# Dynamic Remote Vendor Sharing Example
-This example demos a basic host application loading remote component and sharing vendor code dynamically between unknown remotes
+This example demonstrates advanced Module Federation capabilities for **dynamic remote loading** and **vendor code sharing** between unknown remotes at runtime. It showcases how a host application can load remote components on-demand without compile-time knowledge of their locations, while efficiently sharing dependencies.
-- `app1` is the host application.
-- `app2` standalone application which exposes `Widget` component.
-- `app3` standalone application which exposes `Widget` component that requires
- `momentjs`.
+> **⚠️ Important Note**: True dynamic remotes (where you don't know what you're importing at build time) are **very rare** in practice. For most use cases where you need dynamic remote URLs but know the component interfaces, consider using **runtime plugins** instead:
+>
+> - **[Remote Control Example](../../runtime-plugins/remote-control)** - Dynamic remote URL configuration with runtime plugins
+> - **[Remote Router Example](../../runtime-plugins/remote-router)** - Dynamic routing with runtime remote management
+>
+> These approaches provide better type safety, performance, and maintainability while still allowing runtime URL configuration.
-# Running Demo
+## Project Overview
-Run `pnpm start`. This will build and serve both `app1`, `app2`, and `app3` on
-ports `3001`, `3002`, and `3003` respectively.
+This example illustrates the power of Module Federation's runtime API for creating truly dynamic micro-frontend architectures. The host application (`app1`) can dynamically load and render components from remote applications (`app2` and `app3`) at runtime, demonstrating vendor sharing optimization where dependencies like React and Moment.js are shared efficiently between applications.
-- [localhost:3001](http://localhost:3001/) (HOST)
-- [localhost:3002](http://localhost:3002/) (STANDALONE REMOTE)
-- [localhost:3003](http://localhost:3003/) (STANDALONE REMOTE)
-
+**Key Learning Objectives:**
+- Runtime remote registration and loading
+- Dynamic component rendering with error handling
+- Vendor dependency sharing optimization
+- Cross-application state and dependency management
-# Running Cypress E2E Tests
+## Architecture
-To run tests in interactive mode, run `npm run cypress:debug` from the root directory of the project. It will open Cypress Test Runner and allow to run tests in interactive mode. [More info about "How to run tests"](../../cypress-e2e/README.md#how-to-run-tests)
+### Applications Structure
-To build app and run test in headless mode, run `pnpm e2e:ci`. It will build app and run tests for this workspace in headless mode. If tets failed cypress will create `cypress` directory in sample root folder with screenshots and videos.
+- **`app1`** - Host Application (Port 3001)
+ - Serves as the container application
+ - Dynamically loads remotes using `@module-federation/runtime`
+ - Manages shared dependencies (React, ReactDOM)
+ - Provides UI for remote component selection
-["Best Practices, Rules amd more interesting information here](../../cypress-e2e/README.md)
+- **`app2`** - Remote Application (Port 3002)
+ - Exposes a `Widget` component
+ - Uses Moment.js for date formatting
+ - Demonstrates vendor sharing with external dependencies
+
+- **`app3`** - Remote Application (Port 3003)
+ - Exposes a `Widget` component with React hooks
+ - Uses Moment.js and Redux for state management
+ - Shows advanced dependency sharing scenarios
+
+### Dynamic Loading Flow
+
+```
+1. Host app initializes Module Federation runtime
+2. Runtime registers remote entry points
+3. User triggers component load via UI
+4. Host dynamically imports remote component
+5. Shared dependencies are resolved efficiently
+6. Component renders with fallback handling
+```
+
+## Current Implementation
+
+### Host Application Dynamic Loading
+
+The host uses the Module Federation runtime API to initialize and load remotes:
+
+```javascript
+// Runtime initialization with remote registration
+init({
+ name: 'app1',
+ remotes: [
+ { name: 'app2', entry: 'http://localhost:3002/remoteEntry.js' },
+ { name: 'app3', entry: 'http://localhost:3003/remoteEntry.js' }
+ ]
+});
+
+// Dynamic component loading hook
+function useDynamicImport({ module, scope }) {
+ const [component, setComponent] = useState(null);
+
+ useEffect(() => {
+ const loadComponent = async () => {
+ try {
+ const { default: Component } = await loadRemote(`${scope}/${module}`);
+ setComponent(() => Component);
+ } catch (error) {
+ console.error(`Error loading remote module ${scope}/${module}:`, error);
+ }
+ };
+
+ loadComponent();
+ }, [module, scope]);
+
+ return component;
+}
+```
+
+### Vendor Sharing Configuration
+
+Each application configures shared dependencies to optimize bundle sizes:
+
+```javascript
+// Host configuration (app1)
+shared: {
+ react: {
+ singleton: true,
+ shareScope: 'default'
+ },
+ 'react-dom': {
+ singleton: true
+ }
+}
+
+// Remote configuration (app2/app3)
+shared: {
+ react: {
+ requiredVersion: deps.react,
+ singleton: true
+ },
+ 'react-dom': {
+ requiredVersion: deps['react-dom'],
+ singleton: true
+ },
+ moment: deps.moment // Shared between remotes
+}
+```
+
+## Setup Instructions
+
+### Prerequisites
+
+- Node.js 16+ and pnpm
+- Modern browser with ES2020 support
+- Network access for cross-origin requests
+
+### Installation & Running
+
+1. **Install dependencies for all applications:**
+ ```bash
+ pnpm install
+ ```
+
+2. **Start all applications simultaneously:**
+ ```bash
+ pnpm start
+ ```
+ This starts:
+ - Host app on [http://localhost:3001](http://localhost:3001)
+ - Remote app2 on [http://localhost:3002](http://localhost:3002)
+ - Remote app3 on [http://localhost:3003](http://localhost:3003)
+
+3. **Alternative: Legacy Webpack mode:**
+ ```bash
+ pnpm legacy:start
+ ```
+
+4. **Production build:**
+ ```bash
+ pnpm build
+ pnpm serve
+ ```
+
+### Usage Instructions
+
+1. Open the host application at [http://localhost:3001](http://localhost:3001)
+2. Click "Load App 2 Widget" to dynamically load the red widget from app2
+3. Click "Load App 3 Widget" to dynamically load the purple widget from app3
+4. Observe shared dependency optimization in browser DevTools Network tab
+5. Check browser console for loading logs and shared module information
+
+## Key Concepts Demonstrated
+
+### 1. Runtime Remote Registration
+- Remotes are registered at runtime, not build time
+- Entry points can be discovered dynamically
+- No compile-time coupling between host and remotes
+
+### 2. Dynamic Import with Error Handling
+- Graceful fallback when remotes are unavailable
+- Loading states and error boundaries
+- Component lazy loading with Suspense
+
+### 3. Vendor Code Sharing
+- React/ReactDOM shared as singletons across applications
+- Moment.js shared between app2 and app3
+- Automatic version resolution and deduplication
+
+### 4. Cross-Application Dependency Management
+- Shared scope management for dependency isolation
+- Version compatibility handling
+- Singleton enforcement for framework libraries
+
+## Configuration Explained
+
+### Module Federation Plugin Configuration
+
+**Host Configuration:**
+```javascript
+new ModuleFederationPlugin({
+ name: 'app1',
+ shared: {
+ react: { singleton: true },
+ 'react-dom': { singleton: true }
+ }
+})
+```
+
+**Remote Configuration:**
+```javascript
+new ModuleFederationPlugin({
+ name: 'app2',
+ filename: 'remoteEntry.js',
+ exposes: {
+ './Widget': './src/Widget'
+ },
+ shared: {
+ react: { requiredVersion: deps.react, singleton: true },
+ 'react-dom': { requiredVersion: deps['react-dom'], singleton: true },
+ moment: deps.moment
+ }
+})
+```
+
+### Rspack vs Webpack Support
+
+The example supports both Rspack (default) and Webpack bundlers:
+- **Rspack**: Faster builds with `rspack serve`
+- **Webpack**: Legacy support with `webpack-cli serve`
+- Both configurations maintain feature parity
+
+## Known Issues & Limitations
+
+### Critical Issues Requiring Attention
+
+1. **Severely Outdated React Version (16.13.0)**
+ - Missing modern features (Concurrent Mode, Suspense improvements)
+ - Security vulnerabilities in older versions
+ - Limited hooks and performance optimizations
+
+2. **Hardcoded Remote URLs**
+ - `http://localhost:3002/3003` URLs limit portability
+ - No environment-based configuration
+ - Deployment challenges across environments
+
+3. **Missing Error Boundaries**
+ - Remote loading failures can crash the host
+ - No graceful degradation strategies
+ - Limited user feedback for loading states
+
+4. **No Type Safety**
+ - Missing TypeScript definitions for remote contracts
+ - Runtime errors for interface mismatches
+ - No compile-time validation of remote APIs
+
+5. **Suboptimal Shared Configuration**
+ - Inconsistent version requirements across remotes
+ - Missing eager loading for critical dependencies
+ - No shared scope isolation strategies
+
+## Modernization Roadmap
+
+### Immediate Improvements (High Priority)
+
+1. **Upgrade to React 18+**
+ ```bash
+ pnpm update react react-dom --workspace-root
+ ```
+
+2. **Environment-based Configuration**
+ ```javascript
+ const REMOTE_BASE_URL = process.env.REMOTE_BASE_URL || 'http://localhost';
+ ```
+
+3. **Enhanced Error Handling**
+ ```javascript
+ const ErrorBoundary = ({ children, fallback }) => {
+ // Implement comprehensive error boundary
+ };
+ ```
+
+### Medium-term Enhancements
+
+1. **TypeScript Migration**
+ - Add type definitions for remote contracts
+ - Implement shared type packages
+ - Enable compile-time validation
+
+2. **Advanced Shared Dependencies**
+ ```javascript
+ shared: {
+ react: {
+ singleton: true,
+ eager: true,
+ requiredVersion: '^18.0.0'
+ }
+ }
+ ```
+
+3. **Runtime Remote Discovery**
+ - Service registry integration
+ - Dynamic remote manifest loading
+ - Health checking for remote availability
+
+### Advanced Features
+
+1. **Micro-frontend Orchestration**
+ - Centralized routing and navigation
+ - Inter-application communication patterns
+ - Shared state management strategies
+
+2. **Performance Optimization**
+ - Bundle analysis and optimization
+ - Lazy loading strategies
+ - Caching and prefetching policies
+
+## Best Practices Demonstrated
+
+### 1. Separation of Concerns
+- Clear boundaries between host and remote responsibilities
+- Independent deployment capabilities
+- Isolated development workflows
+
+### 2. Dependency Management
+- Singleton enforcement for framework libraries
+- Version compatibility strategies
+- Shared scope optimization
+
+### 3. Runtime Flexibility
+- Dynamic component discovery and loading
+- Graceful degradation patterns
+- Environment-agnostic configuration
+
+### 4. Development Experience
+- Hot module replacement support
+- Independent development servers
+- Comprehensive testing strategies
+
+## Troubleshooting
+
+### Common Issues and Solutions
+
+**1. CORS Errors During Development**
+```javascript
+// Add to webpack.config.js devServer
+headers: {
+ 'Access-Control-Allow-Origin': '*'
+}
+```
+
+**2. Shared Dependency Version Conflicts**
+```javascript
+// Use strict version matching
+shared: {
+ react: {
+ requiredVersion: '^18.0.0',
+ singleton: true,
+ strictVersion: true
+ }
+}
+```
+
+**3. Remote Loading Failures**
+```javascript
+// Implement retry logic
+const loadWithRetry = async (remoteName, retries = 3) => {
+ for (let i = 0; i < retries; i++) {
+ try {
+ return await loadRemote(remoteName);
+ } catch (error) {
+ if (i === retries - 1) throw error;
+ await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
+ }
+ }
+};
+```
+
+**4. Development Server Port Conflicts**
+```bash
+# Check and gracefully terminate processes using ports
+lsof -ti:3001,3002,3003 | xargs kill -15
+# If any processes remain, force kill as a last resort:
+lsof -ti:3001,3002,3003 | xargs kill -9
+```
+
+**5. Build Failures with Rspack**
+```javascript
+// Add to rspack.config.js for compatibility
+resolve: {
+ alias: {
+ '@module-federation/runtime$': require.resolve('@module-federation/runtime')
+ }
+}
+```
+
+## Testing
+
+### Running E2E Tests
+
+**Interactive Mode:**
+```bash
+npm run cypress:debug
+```
+
+**Headless CI Mode:**
+```bash
+pnpm e2e:ci
+```
+
+**Legacy Webpack Testing:**
+```bash
+pnpm legacy:e2e:ci
+```
+
+The E2E tests verify:
+- Dynamic component loading functionality
+- Shared dependency optimization
+- Cross-application UI interactions
+- Error handling and fallback scenarios
+
+### Test Coverage
+
+- Component rendering verification
+- Dynamic loading state management
+- Vendor sharing optimization validation
+- Cross-browser compatibility checks
+
+For comprehensive testing guidelines, see [Cypress E2E Documentation](../../cypress-e2e/README.md).
+
+## Next Steps
+
+1. **Immediate**: Address critical issues (React upgrade, environment config)
+2. **Short-term**: Implement TypeScript and enhanced error handling
+3. **Long-term**: Explore advanced micro-frontend patterns and tooling
+
+This example serves as a foundation for understanding Module Federation's dynamic capabilities while highlighting areas for production-ready improvements.
diff --git a/advanced-api/dynamic-remotes/app1/package.json b/advanced-api/dynamic-remotes/app1/package.json
index 272b987efb9..bb660262f4c 100644
--- a/advanced-api/dynamic-remotes/app1/package.json
+++ b/advanced-api/dynamic-remotes/app1/package.json
@@ -25,7 +25,7 @@
"clean": "rm -rf dist"
},
"dependencies": {
- "react": "^16.13.0",
- "react-dom": "^16.13.0"
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1"
}
}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app1/rspack.config.js b/advanced-api/dynamic-remotes/app1/rspack.config.js
index 5bb7877c70a..cb91134113b 100644
--- a/advanced-api/dynamic-remotes/app1/rspack.config.js
+++ b/advanced-api/dynamic-remotes/app1/rspack.config.js
@@ -56,14 +56,23 @@ module.exports = {
// so it will always use the higher version found
shared: {
react: {
- import: 'react', // the "react" package will be used a provided and fallback module
- shareKey: 'react', // under this name the shared module will be placed in the share scope
- shareScope: 'default', // share scope with this name will be used
- singleton: true, // only a single version of the shared module is allowed
+ 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/jsx-dev-runtime': {},
'react-dom': {
- singleton: true, // only a single version of the shared module is allowed
+ singleton: true,
+ requiredVersion: '^18.3.1',
+ strictVersion: true,
},
},
}),
diff --git a/advanced-api/dynamic-remotes/app1/src/App.js b/advanced-api/dynamic-remotes/app1/src/App.js
index 2c10c1298c4..fdb7fc71ce2 100644
--- a/advanced-api/dynamic-remotes/app1/src/App.js
+++ b/advanced-api/dynamic-remotes/app1/src/App.js
@@ -1,39 +1,115 @@
import React, { useState, useEffect, Suspense } from 'react';
import { init, loadRemote } from '@module-federation/runtime';
+class ErrorBoundary extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = { hasError: false, error: null };
+ }
+
+ static getDerivedStateFromError(error) {
+ return { hasError: true, error };
+ }
+
+ componentDidCatch(error, errorInfo) {
+ console.error('Remote component error:', error, errorInfo);
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return (
+
+
⚠️ Component Failed to Load
+
Unable to load the remote component. Please try again or check the remote application.
+
+ Error Details
+
+ {this.state.error?.toString()}
+
+
+
+
+ );
+ }
+
+ return this.props.children;
+ }
+}
+
+const getRemoteEntry = (port) => {
+ const baseUrl = process.env.NODE_ENV === 'production'
+ ? (process.env.REACT_APP_REMOTE_BASE_URL || window.location.origin)
+ : 'http://localhost';
+ return `${baseUrl}:${port}/remoteEntry.js`;
+};
+
init({
name: 'app1',
remotes: [
{
name: 'app2',
- entry: 'http://localhost:3002/remoteEntry.js',
+ entry: getRemoteEntry(3002),
},
{
name: 'app3',
- entry: 'http://localhost:3003/remoteEntry.js',
+ entry: getRemoteEntry(3003),
},
],
});
function useDynamicImport({ module, scope }) {
const [component, setComponent] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
useEffect(() => {
- if (!module || !scope) return;
+ if (!module || !scope) {
+ setComponent(null);
+ setError(null);
+ 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;
+ return { component, loading, error };
}
function App() {
@@ -53,7 +129,54 @@ function App() {
});
};
- const Component = useDynamicImport({ module, scope });
+ const { component: Component, loading, error } = useDynamicImport({ module, scope });
+
+ const renderRemoteComponent = () => {
+ if (loading) {
+ return (
+
+
🔄 Loading {scope}/{module}...
+
+ );
+ }
+
+ if (error) {
+ return (
+
+
⚠️ Failed to Load Remote Component
+
Could not load {scope}/{module}
+
+ Error Details
+
+ {error.toString()}
+
+
+
+ );
+ }
+
+ if (Component) {
+ return (
+
+
+
+ );
+ }
+
+ return null;
+ };
return (
remotes and{' '}
exposes. It will not load components that have already been loaded.
-
-
+
+
+
+
- {Component ? : null}
+
+ 🔄 Initializing component...
+
+ }>
+ {renderRemoteComponent()}
+
);
diff --git a/advanced-api/dynamic-remotes/app1/src/bootstrap.js b/advanced-api/dynamic-remotes/app1/src/bootstrap.js
index a8680f71cdf..129ffb0c0f9 100644
--- a/advanced-api/dynamic-remotes/app1/src/bootstrap.js
+++ b/advanced-api/dynamic-remotes/app1/src/bootstrap.js
@@ -1,5 +1,7 @@
import App from './App';
import React from 'react';
-import ReactDOM from 'react-dom';
+import { createRoot } from 'react-dom/client';
-ReactDOM.render(, document.getElementById('root'));
+const container = document.getElementById('root');
+const root = createRoot(container);
+root.render();
diff --git a/advanced-api/dynamic-remotes/app1/webpack.config.js b/advanced-api/dynamic-remotes/app1/webpack.config.js
index 1fa58ff6e58..1e9c4b2810f 100644
--- a/advanced-api/dynamic-remotes/app1/webpack.config.js
+++ b/advanced-api/dynamic-remotes/app1/webpack.config.js
@@ -41,13 +41,20 @@ module.exports = {
// so it will always use the higher version found
shared: {
react: {
- import: 'react', // the "react" package will be used a provided and fallback module
- shareKey: 'react', // under this name the shared module will be placed in the share scope
- shareScope: 'default', // share scope with this name will be used
- singleton: true, // only a single version of the shared module is allowed
+ import: 'react',
+ shareKey: 'react',
+ shareScope: 'default',
+ singleton: true,
+ requiredVersion: '^18.3.1',
+ strictVersion: true,
},
'react-dom': {
- singleton: true, // only a single version of the shared module is allowed
+ singleton: true,
+ requiredVersion: '^18.3.1',
+ strictVersion: true,
+ },
+ 'react/jsx-runtime': {
+ singleton: true,
},
},
}),
diff --git a/advanced-api/dynamic-remotes/app2/package.json b/advanced-api/dynamic-remotes/app2/package.json
index 59b1abb1e5a..5a8fe394821 100644
--- a/advanced-api/dynamic-remotes/app2/package.json
+++ b/advanced-api/dynamic-remotes/app2/package.json
@@ -25,7 +25,7 @@
},
"dependencies": {
"moment": "^2.29.4",
- "react": "^16.13.0",
- "react-dom": "^16.13.0"
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1"
}
}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app2/rspack.config.js b/advanced-api/dynamic-remotes/app2/rspack.config.js
index b9cbd3af6d5..8b08b700066 100644
--- a/advanced-api/dynamic-remotes/app2/rspack.config.js
+++ b/advanced-api/dynamic-remotes/app2/rspack.config.js
@@ -58,18 +58,28 @@ module.exports = {
'./Widget': './src/Widget',
},
shared: {
- moment: deps.moment,
- 'react/jsx-dev-runtime': {},
+ moment: {
+ requiredVersion: deps.moment,
+ singleton: false,
+ },
+ 'react/jsx-runtime': {
+ singleton: true,
+ },
+ 'react/jsx-dev-runtime': {
+ singleton: true,
+ },
react: {
- requiredVersion: deps.react,
- import: 'react', // the "react" package will be used a provided and fallback module
- shareKey: 'react', // under this name the shared module will be placed in the share scope
- shareScope: 'default', // share scope with this name will be used
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ import: 'react',
+ shareKey: 'react',
+ shareScope: 'default',
+ singleton: true,
+ strictVersion: true,
},
'react-dom': {
- requiredVersion: deps['react-dom'],
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ singleton: true,
+ strictVersion: true,
},
},
}),
diff --git a/advanced-api/dynamic-remotes/app2/src/bootstrap.js b/advanced-api/dynamic-remotes/app2/src/bootstrap.js
index a8680f71cdf..129ffb0c0f9 100644
--- a/advanced-api/dynamic-remotes/app2/src/bootstrap.js
+++ b/advanced-api/dynamic-remotes/app2/src/bootstrap.js
@@ -1,5 +1,7 @@
import App from './App';
import React from 'react';
-import ReactDOM from 'react-dom';
+import { createRoot } from 'react-dom/client';
-ReactDOM.render(, document.getElementById('root'));
+const container = document.getElementById('root');
+const root = createRoot(container);
+root.render();
diff --git a/advanced-api/dynamic-remotes/app2/webpack.config.js b/advanced-api/dynamic-remotes/app2/webpack.config.js
index be5b9e7d496..7351c6ebbbd 100644
--- a/advanced-api/dynamic-remotes/app2/webpack.config.js
+++ b/advanced-api/dynamic-remotes/app2/webpack.config.js
@@ -41,17 +41,25 @@ module.exports = {
'./Widget': './src/Widget',
},
shared: {
- moment: deps.moment,
+ moment: {
+ requiredVersion: deps.moment,
+ singleton: false,
+ },
react: {
- requiredVersion: deps.react,
- import: 'react', // the "react" package will be used a provided and fallback module
- shareKey: 'react', // under this name the shared module will be placed in the share scope
- shareScope: 'default', // share scope with this name will be used
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ import: 'react',
+ shareKey: 'react',
+ shareScope: 'default',
+ singleton: true,
+ strictVersion: true,
},
'react-dom': {
- requiredVersion: deps['react-dom'],
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ singleton: true,
+ strictVersion: true,
+ },
+ 'react/jsx-runtime': {
+ singleton: true,
},
},
}),
diff --git a/advanced-api/dynamic-remotes/app3/package.json b/advanced-api/dynamic-remotes/app3/package.json
index 7cb78abf367..c71dc2776e1 100644
--- a/advanced-api/dynamic-remotes/app3/package.json
+++ b/advanced-api/dynamic-remotes/app3/package.json
@@ -25,9 +25,9 @@
},
"dependencies": {
"moment": "^2.29.4",
- "react": "^16.13.0",
- "react-dom": "^16.13.0",
- "react-redux": "^7.2.0",
- "redux": "^4.2.1"
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-redux": "^9.1.2",
+ "redux": "^5.0.1"
}
}
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/app3/rspack.config.js b/advanced-api/dynamic-remotes/app3/rspack.config.js
index fe7222d6bd1..bb5f0970a09 100644
--- a/advanced-api/dynamic-remotes/app3/rspack.config.js
+++ b/advanced-api/dynamic-remotes/app3/rspack.config.js
@@ -50,31 +50,42 @@ module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'app3',
- library: { type: 'var', name: 'app3' },
filename: 'remoteEntry.js',
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,
- import: 'react', // the "react" package will be used a provided and fallback module
- shareKey: 'react', // under this name the shared module will be placed in the share scope
- shareScope: 'default', // share scope with this name will be used
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ import: 'react',
+ shareKey: 'react',
+ shareScope: 'default',
+ singleton: true,
+ strictVersion: true,
},
'react-dom': {
- requiredVersion: deps['react-dom'],
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ singleton: true,
+ strictVersion: true,
+ },
+ 'react/jsx-runtime': {
+ singleton: true,
+ },
+ 'react/jsx-dev-runtime': {
+ singleton: true,
+ },
+ moment: {
+ requiredVersion: deps.moment,
+ singleton: false,
+ },
+ 'react-redux': {
+ requiredVersion: deps['react-redux'],
+ singleton: true,
+ },
+ redux: {
+ requiredVersion: deps.redux,
+ singleton: true,
},
- // adds moment as shared module
- // version is inferred from package.json
- // it will use the highest moment version that is >= 2.24 and < 3
- moment: deps.moment,
},
}),
new HtmlRspackPlugin({
diff --git a/advanced-api/dynamic-remotes/app3/src/bootstrap.js b/advanced-api/dynamic-remotes/app3/src/bootstrap.js
index a8680f71cdf..129ffb0c0f9 100644
--- a/advanced-api/dynamic-remotes/app3/src/bootstrap.js
+++ b/advanced-api/dynamic-remotes/app3/src/bootstrap.js
@@ -1,5 +1,7 @@
import App from './App';
import React from 'react';
-import ReactDOM from 'react-dom';
+import { createRoot } from 'react-dom/client';
-ReactDOM.render(, document.getElementById('root'));
+const container = document.getElementById('root');
+const root = createRoot(container);
+root.render();
diff --git a/advanced-api/dynamic-remotes/app3/webpack.config.js b/advanced-api/dynamic-remotes/app3/webpack.config.js
index 6c4e51352c3..46c78cb785c 100644
--- a/advanced-api/dynamic-remotes/app3/webpack.config.js
+++ b/advanced-api/dynamic-remotes/app3/webpack.config.js
@@ -35,31 +35,39 @@ module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'app3',
- library: { type: 'var', name: 'app3' },
filename: 'remoteEntry.js',
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,
- import: 'react', // the "react" package will be used a provided and fallback module
- shareKey: 'react', // under this name the shared module will be placed in the share scope
- shareScope: 'default', // share scope with this name will be used
- singleton: true, // only a single version of the shared module is allowed
+ import: 'react',
+ shareKey: 'react',
+ shareScope: 'default',
+ singleton: true,
+ strictVersion: true,
},
'react-dom': {
- requiredVersion: deps['react-dom'],
- singleton: true, // only a single version of the shared module is allowed
+ requiredVersion: '^18.3.1',
+ singleton: true,
+ strictVersion: true,
+ },
+ 'react/jsx-runtime': {
+ singleton: true,
+ },
+ moment: {
+ requiredVersion: deps.moment,
+ singleton: false,
+ },
+ 'react-redux': {
+ requiredVersion: deps['react-redux'],
+ singleton: true,
+ },
+ redux: {
+ requiredVersion: deps.redux,
+ singleton: true,
},
- // adds moment as shared module
- // version is inferred from package.json
- // it will use the highest moment version that is >= 2.24 and < 3
- moment: deps.moment,
},
}),
new HtmlWebpackPlugin({
diff --git a/advanced-api/dynamic-remotes/cypress.env.json b/advanced-api/dynamic-remotes/cypress.env.json
deleted file mode 100644
index e63233bb67d..00000000000
--- a/advanced-api/dynamic-remotes/cypress.env.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "allure": true,
- "allureResultsPath": "../../cypress-e2e/results/allure-results"
-}
diff --git a/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.cy.ts b/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.cy.ts
deleted file mode 100644
index 3e2403e38c6..00000000000
--- a/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.cy.ts
+++ /dev/null
@@ -1,177 +0,0 @@
-import { baseSelectors, commonSelectors } from '../../../cypress-e2e/common/selectors';
-import { BaseMethods } from '../../../cypress-e2e/common/base';
-import { Constants } from '../../../cypress-e2e/fixtures/constants';
-import { getDateWithFormat } from '../../../cypress-e2e/helpers/base-helper';
-import { CssAttr } from '../../../cypress-e2e/types/cssAttr';
-import { returnCommonDynamicAppsData } from '../../../cypress-e2e/fixtures/commonTestData';
-
-const basePage: BaseMethods = new BaseMethods();
-
-const appsData = returnCommonDynamicAppsData(
- Constants.commonPhrases.dynamicRemotesApp.widgetParagraphText,
-);
-
-appsData.forEach(
- (property: {
- headerSelector: string;
- subHeaderSelector: string;
- isButtonExist: boolean;
- buttonSelector: string;
- headerText: string;
- appNameText: string;
- widgetQuantity?: number;
- widgetName: string[];
- widgetParagraph: string[];
- widgetColor: string[];
- paragraph: boolean;
- host: number;
- }) => {
- const appName =
- property.host === 3001
- ? appsData[0].appNameText
- : property.host === 3002
- ? appsData[1].appNameText
- : appsData[2].appNameText;
- const host =
- property.host === 3001
- ? appsData[0].host
- : property.host === 3002
- ? appsData[1].host
- : appsData[2].host;
- const widget: number =
- property.host === 3002
- ? Number(appsData[1].widgetQuantity)
- : Number(appsData[2].widgetQuantity);
-
- describe('Dynamic Remotes', () => {
- context(`Check ${appName}`, () => {
- beforeEach(() => {
- basePage.openLocalhost({
- number: host,
- });
- });
-
- it(`Check ${appName} elements exist on the page`, () => {
- basePage.checkElementWithTextPresence({
- selector: property.headerSelector,
- text: property.headerText,
- });
- basePage.checkElementWithTextPresence({
- selector: property.subHeaderSelector,
- text: appName,
- });
- if (property.paragraph) {
- basePage.checkElementWithTextPresence({
- selector: baseSelectors.tags.paragraph,
- text: Constants.commonPhrases.dynamicRemotesApp.paragraphText,
- });
-
- return;
- }
- basePage.checkElementWithTextPresence({
- selector: baseSelectors.tags.paragraph,
- text: Constants.commonPhrases.dynamicRemotesApp.paragraphText,
- isVisible: false,
- });
- });
-
- it(`Check buttons in ${appName} exist`, () => {
- basePage.openLocalhost({
- number: host,
- });
- if (property.isButtonExist) {
- Constants.elementsText.dynamicRemotesApp.buttonsText.forEach(button => {
- basePage.checkElementWithTextPresence({
- selector: property.buttonSelector,
- text: button,
- });
- });
-
- return;
- }
-
- basePage.checkElementVisibility({
- selector: property.buttonSelector,
- isVisible: property.isButtonExist,
- });
- });
-
- it(`Check elements functionality in ${appName}`, () => {
- if (property.isButtonExist) {
- Constants.elementsText.dynamicRemotesApp.buttonsText.forEach(button => {
- basePage.clickElementWithText({
- selector: property.buttonSelector,
- text: button,
- });
- basePage.checkElementVisibility({
- selector: commonSelectors.commonWidget.replace(
- '{appQuantity}',
- (
- Constants.elementsText.dynamicRemotesApp.buttonsText.indexOf(button) + 2
- ).toString(),
- ),
- });
- basePage.checkElementHaveProperty({
- selector: commonSelectors.commonWidget.replace(
- '{appQuantity}',
- (
- Constants.elementsText.dynamicRemotesApp.buttonsText.indexOf(button) + 2
- ).toString(),
- ),
- prop: CssAttr.backgroundColor,
- value:
- property.widgetColor[
- Constants.elementsText.dynamicRemotesApp.buttonsText.indexOf(button)
- ],
- });
- basePage.checkElementWithTextPresence({
- selector: property.subHeaderSelector,
- text: property.widgetName[
- Constants.elementsText.dynamicRemotesApp.buttonsText.indexOf(button)
- ],
- });
- basePage.checkElementWithTextPresence({
- selector: baseSelectors.tags.paragraph,
- text: property.widgetParagraph[
- Constants.elementsText.dynamicRemotesApp.buttonsText.indexOf(button)
- ],
- });
- basePage.checkElementWithTextPresence({
- selector: baseSelectors.tags.paragraph,
- text: getDateWithFormat('current', 'MMMM Do YYYY, h:mm'),
- });
- });
-
- return;
- }
- basePage.checkElementVisibility({
- selector: commonSelectors.commonWidget.replace(
- '{appQuantity}',
- (widget + 2).toString(),
- ),
- });
- basePage.checkElementHaveProperty({
- selector: commonSelectors.commonWidget.replace(
- '{appQuantity}',
- (widget + 2).toString(),
- ),
- prop: CssAttr.backgroundColor,
- value: property.widgetColor[widget],
- });
- basePage.checkElementWithTextPresence({
- selector: property.subHeaderSelector,
- text: property.widgetName[widget],
- });
- basePage.checkElementWithTextPresence({
- selector: baseSelectors.tags.paragraph,
- text: property.widgetParagraph[widget],
- });
- basePage.checkElementWithTextPresence({
- selector: baseSelectors.tags.paragraph,
- text: getDateWithFormat('current', 'MMMM Do YYYY, h:mm'),
- });
- });
- });
- });
- },
-);
diff --git a/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts b/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts
new file mode 100644
index 00000000000..1289765ab6f
--- /dev/null
+++ b/advanced-api/dynamic-remotes/e2e/checkDynamicRemotesApps.spec.ts
@@ -0,0 +1,318 @@
+import { test, expect } from './utils/base-test';
+import { selectors } from './utils/selectors';
+import { Constants } from './utils/constants';
+
+test.describe('Dynamic Remotes E2E Tests', () => {
+
+ test.describe('Host Application (App 1)', () => {
+ test('should display host application elements correctly', async ({ basePage }) => {
+ const consoleErrors: string[] = [];
+ basePage.page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await basePage.openLocalhost(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');
+
+ // Check both buttons exist
+ await basePage.checkElementWithTextPresence('button', 'Load App 2 Widget');
+ await basePage.checkElementWithTextPresence('button', 'Load App 3 Widget');
+
+ // Verify no critical console errors
+ const criticalErrors = consoleErrors.filter(error =>
+ error.includes('Failed to fetch') ||
+ error.includes('ChunkLoadError') ||
+ error.includes('Module not found')
+ );
+ expect(criticalErrors).toHaveLength(0);
+ });
+
+ test('should dynamically load App 2 widget successfully', async ({ basePage }) => {
+ const consoleErrors: string[] = [];
+ basePage.page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await basePage.openLocalhost(3001);
+
+ // Click to load App 2 widget
+ await basePage.clickElementWithText('button', 'Load App 2 Widget');
+ await basePage.waitForDynamicImport();
+
+ // 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)');
+
+ // Check for moment.js date formatting
+ await basePage.checkDateFormat();
+
+ // Verify no module federation errors
+ const moduleErrors = consoleErrors.filter(error =>
+ error.includes('Loading remote module') ||
+ error.includes('Module Federation')
+ );
+ expect(moduleErrors).toHaveLength(0);
+ });
+
+ test('should dynamically load App 3 widget successfully', async ({ basePage }) => {
+ const consoleErrors: string[] = [];
+ basePage.page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await basePage.openLocalhost(3001);
+
+ // Click to load App 3 widget
+ await basePage.clickElementWithText('button', 'Load App 3 Widget');
+ await basePage.waitForDynamicImport();
+
+ // 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)');
+
+ // Check for moment.js date formatting
+ await basePage.checkDateFormat();
+
+ // Verify no module federation errors
+ const moduleErrors = consoleErrors.filter(error =>
+ error.includes('Loading remote module') ||
+ error.includes('Module Federation')
+ );
+ expect(moduleErrors).toHaveLength(0);
+ });
+
+ test('should handle sequential loading of both widgets', async ({ basePage }) => {
+ await basePage.openLocalhost(3001);
+
+ // Load App 2 widget first
+ await basePage.clickElementWithText('button', 'Load App 2 Widget');
+ await basePage.waitForDynamicImport();
+
+ // Verify App 2 widget is loaded and get its content
+ await basePage.checkElementVisibility(selectors.dataTestIds.app2Widget);
+ await basePage.checkElementWithTextPresence('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();
+
+ // Verify App 3 widget is loaded
+ await basePage.checkElementVisibility(selectors.dataTestIds.app3Widget);
+ await basePage.checkElementWithTextPresence('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);
+
+ // Check that buttons are initially enabled
+ const app2Button = basePage.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="⚠️"');
+ await expect(errorMessages).toHaveCount(0);
+ });
+ });
+
+ test.describe('Remote Application - App 2', () => {
+ test('should display App 2 standalone correctly', async ({ basePage }) => {
+ const consoleErrors: string[] = [];
+ basePage.page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await basePage.openLocalhost(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)');
+
+ // Check moment.js functionality
+ await basePage.checkElementWithTextPresence('p', "Moment shouldn't download twice");
+ await basePage.checkDateFormat();
+
+ // Verify no critical console errors (filter out expected warnings)
+ const criticalErrors = consoleErrors.filter(e =>
+ !e.includes('webpack-dev-server') &&
+ !e.includes('ReactDOM.render is no longer supported') &&
+ !e.includes('DevTools') &&
+ !e.includes('Warning:')
+ );
+ expect(criticalErrors).toHaveLength(0);
+ });
+ });
+
+ test.describe('Remote Application - App 3', () => {
+ test('should display App 3 standalone correctly', async ({ basePage }) => {
+ const consoleErrors: string[] = [];
+ basePage.page.on('console', (msg) => {
+ if (msg.type() === 'error') {
+ consoleErrors.push(msg.text());
+ }
+ });
+
+ await basePage.openLocalhost(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)');
+
+ // Check for moment.js date formatting
+ await basePage.checkDateFormat();
+
+ // Verify no critical console errors (filter out expected warnings)
+ const criticalErrors = consoleErrors.filter(e =>
+ !e.includes('webpack-dev-server') &&
+ !e.includes('ReactDOM.render is no longer supported') &&
+ !e.includes('DevTools') &&
+ !e.includes('Warning:')
+ );
+ expect(criticalErrors).toHaveLength(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
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Load both remotes
+ await page.click('button:has-text("Load App 2 Widget")');
+ await page.waitForTimeout(3000);
+
+ await page.click('button:has-text("Load App 3 Widget")');
+ await page.waitForTimeout(3000);
+
+ // Verify React is shared efficiently (should not be loaded multiple times)
+ const reactRequests = networkRequests.filter(url =>
+ url.includes('react') && !url.includes('react-dom') && !url.includes('react-redux')
+ );
+ expect(reactRequests.length).toBeLessThan(5);
+
+ // Verify moment.js is shared between remotes
+ const momentRequests = networkRequests.filter(url => url.includes('moment'));
+ expect(momentRequests.length).toBeLessThan(4);
+ });
+
+ test('should handle cross-origin requests correctly', async ({ page }) => {
+ // Monitor for CORS errors
+ 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');
+
+ // Load remotes
+ await page.click('button:has-text("Load App 2 Widget")');
+ await page.waitForTimeout(2000);
+
+ // Should have no CORS errors
+ expect(corsErrors).toHaveLength(0);
+ });
+
+ test('should maintain proper error boundaries during failures', 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');
+
+ // Try to load widgets normally
+ await page.click('button:has-text("Load App 2 Widget")');
+ await page.waitForTimeout(2000);
+
+ // Check for React error boundaries working
+
+ // Should handle any errors gracefully (either no errors or proper error boundaries)
+ const criticalErrors = consoleErrors.filter(error =>
+ error.includes('Uncaught') &&
+ !error.includes('webpack-dev-server') &&
+ !error.includes('DevTools')
+ );
+ expect(criticalErrors).toHaveLength(0);
+ });
+ });
+
+ test.describe('Environment Configuration', () => {
+ test('should use environment-based remote URLs', async ({ page }) => {
+ const networkRequests: string[] = [];
+
+ page.on('request', (request) => {
+ networkRequests.push(request.url());
+ });
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ // Trigger dynamic loading to generate remote requests
+ await page.click('button:has-text("Load App 2 Widget")');
+ await page.waitForTimeout(2000);
+
+ // Verify requests are going to the correct localhost ports
+ const remoteRequests = networkRequests.filter(url =>
+ url.includes('localhost:3002') || url.includes('localhost:3003')
+ );
+
+ expect(remoteRequests.length).toBeGreaterThan(0);
+ });
+ });
+
+ test.describe('Performance and Loading', () => {
+ test('should load all applications within reasonable time', async ({ page }) => {
+ const startTime = Date.now();
+
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ const loadTime = Date.now() - startTime;
+ expect(loadTime).toBeLessThan(10000); // Should load within 10 seconds
+ });
+
+ test('should handle dynamic imports efficiently', async ({ page }) => {
+ await page.goto('http://localhost:3001');
+ await page.waitForLoadState('networkidle');
+
+ const startTime = Date.now();
+
+ await page.click('button:has-text("Load App 2 Widget")');
+ await page.waitForSelector('[data-e2e="APP_2__WIDGET"]', { timeout: 10000 });
+
+ const dynamicLoadTime = Date.now() - startTime;
+ expect(dynamicLoadTime).toBeLessThan(8000); // Dynamic loading should be fast
+ });
+ });
+});
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/e2e/utils/base-test.ts b/advanced-api/dynamic-remotes/e2e/utils/base-test.ts
new file mode 100644
index 00000000000..c1282ae9330
--- /dev/null
+++ b/advanced-api/dynamic-remotes/e2e/utils/base-test.ts
@@ -0,0 +1,97 @@
+import { test as base, expect, 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');
+
+ // Wait for module federation to load (give it extra time for federated components)
+ await this.page.waitForTimeout(2000);
+
+ // Wait for React to render
+ await this.page.waitForFunction(() => {
+ const elements = document.querySelectorAll('h1, h2, button, p');
+ return elements.length > 0;
+ }, { timeout: 30000 });
+ }
+
+ async checkElementWithTextPresence(selector: string, text: string, shouldBeVisible = true) {
+ const element = this.page.locator(selector).filter({ hasText: text });
+ if (shouldBeVisible) {
+ await expect(element).toBeVisible();
+ } else {
+ await expect(element).not.toBeVisible();
+ }
+ }
+
+ async checkElementVisibility(selector: string, shouldBeVisible = true) {
+ const element = this.page.locator(selector);
+ if (shouldBeVisible) {
+ await expect(element).toBeVisible();
+ } else {
+ await expect(element).not.toBeVisible();
+ }
+ }
+
+ async clickElementWithText(selector: string, text: string) {
+ const element = this.page.locator(selector).filter({ hasText: text });
+
+ // Wait for element to be ready
+ await element.waitFor({ state: 'visible', timeout: 10000 });
+
+ // Remove any overlays that might interfere
+ await this.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, force: true });
+ break;
+ } catch (error) {
+ attempts++;
+ if (attempts >= 3) throw error;
+ await this.page.waitForTimeout(1000);
+ }
+ }
+
+ // Wait for any dynamic loading to complete
+ await this.page.waitForTimeout(3000);
+ }
+
+ async checkElementBackgroundColor(selector: string, expectedColor: string) {
+ const element = this.page.locator(selector);
+ await expect(element).toHaveCSS('background-color', expectedColor);
+ }
+
+ async waitForDynamicImport() {
+ // Wait for dynamic import to complete - looking for loading states to disappear
+ await this.page.waitForTimeout(3000); // Give time for dynamic loading
+
+ // Wait for any network activity to settle
+ await this.page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => {
+ // Ignore timeout - loading might already be complete
+ });
+ }
+
+ async checkDateFormat() {
+ // Check for moment.js formatted date (format: "Month Day Year, time")
+ const dateRegex = /\w+ \d+\w+ \d{4}, \d+:\d+/;
+ const textContent = await this.page.textContent('body');
+ expect(textContent).toMatch(dateRegex);
+ }
+}
+
+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/e2e/utils/constants.ts b/advanced-api/dynamic-remotes/e2e/utils/constants.ts
new file mode 100644
index 00000000000..e68bdab80b4
--- /dev/null
+++ b/advanced-api/dynamic-remotes/e2e/utils/constants.ts
@@ -0,0 +1,24 @@
+export const Constants = {
+ commonPhrases: {
+ dynamicRemotesApp: {
+ hostTitle: 'Dynamic System Host',
+ app1Title: 'App 1',
+ app2WidgetTitle: 'App 2 Widget',
+ app3WidgetTitle: 'App 3 Widget',
+ paragraphText: 'The Dynamic System will take advantage of Module Federation remotes and exposes. It will not load components that have already been loaded.',
+ loadingText: 'Loading',
+ app2Button: 'Load App 2 Widget',
+ app3Button: 'Load App 3 Widget',
+ momentText: "Moment shouldn't download twice, the host has no moment.js",
+ },
+ },
+ elementsText: {
+ dynamicRemotesApp: {
+ buttonsText: ['Load App 2 Widget', 'Load App 3 Widget'],
+ },
+ },
+ colors: {
+ red: 'rgb(255, 0, 0)',
+ purple: 'rgb(128, 0, 128)',
+ },
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/e2e/utils/selectors.ts b/advanced-api/dynamic-remotes/e2e/utils/selectors.ts
new file mode 100644
index 00000000000..2c065f8676b
--- /dev/null
+++ b/advanced-api/dynamic-remotes/e2e/utils/selectors.ts
@@ -0,0 +1,20 @@
+export const selectors = {
+ tags: {
+ coreElements: {
+ button: 'button',
+ h1: 'h1',
+ h2: 'h2',
+ paragraph: 'p',
+ div: 'div',
+ },
+ },
+ classes: {
+ title: '.title',
+ name: '.name',
+ description: '.description',
+ },
+ dataTestIds: {
+ app2Widget: '[data-e2e="APP_2__WIDGET"]',
+ app3Widget: '[data-e2e="APP_3__WIDGET"]',
+ },
+};
\ No newline at end of file
diff --git a/advanced-api/dynamic-remotes/package.json b/advanced-api/dynamic-remotes/package.json
index caa57f06501..59b9ca20adf 100644
--- a/advanced-api/dynamic-remotes/package.json
+++ b/advanced-api/dynamic-remotes/package.json
@@ -14,10 +14,15 @@
"build": "pnpm --filter dynamic-remotes_app* --parallel build",
"serve": "pnpm --filter dynamic-remotes_app* --parallel serve",
"clean": "pnpm --filter dynamic-remotes_app* --parallel clean",
- "e2e:ci": "pnpm start & sleep 1 && wait-on tcp:3001 && wait-on tcp:3002 && wait-on tcp:3003 && npx cypress run --config-file ../../cypress-e2e/config/cypress.config.ts --config '{\"supportFile\": \"../../cypress-e2e/support/e2e.ts\"}' --spec \"./e2e/*.cy.ts\" --browser=chrome",
- "legacy:e2e:ci": "pnpm legacy:start & sleep 1 && wait-on tcp:3001 && wait-on tcp:3002 && wait-on tcp:3003 && npx cypress run --config-file ../../cypress-e2e/config/cypress.config.ts --config '{\"supportFile\": \"../../cypress-e2e/support/e2e.ts\"}' --spec \"./e2e/*.cy.ts\" --browser=chrome"
+ "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"
},
"devDependencies": {
+ "@playwright/test": "^1.54.2",
+ "playwright": "^1.54.2",
"wait-on": "7.2.0"
}
}
diff --git a/advanced-api/dynamic-remotes/playwright.config.ts b/advanced-api/dynamic-remotes/playwright.config.ts
new file mode 100644
index 00000000000..26445e39243
--- /dev/null
+++ b/advanced-api/dynamic-remotes/playwright.config.ts
@@ -0,0 +1,34 @@
+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 configuration removed - servers are started manually in package.json scripts
+ // This ensures better compatibility with CI environments and matches the original Cypress approach
+});
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3ebd22cc80f..5368a6fe916 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -185,6 +185,12 @@ importers:
advanced-api/dynamic-remotes:
devDependencies:
+ '@playwright/test':
+ specifier: ^1.54.2
+ version: 1.54.2
+ playwright:
+ specifier: ^1.54.2
+ version: 1.54.2
wait-on:
specifier: 7.2.0
version: 7.2.0
@@ -397,11 +403,11 @@ importers:
advanced-api/dynamic-remotes/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
@@ -411,7 +417,7 @@ 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/runtime':
specifier: 0.17.1
version: 0.17.1
@@ -449,11 +455,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
@@ -463,7 +469,7 @@ 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)
'@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)
@@ -498,17 +504,17 @@ 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)
+ specifier: ^9.1.2
+ version: 9.2.0(@types/react@18.3.10)(react@18.3.1)(redux@5.0.1)
redux:
- specifier: ^4.2.1
- version: 4.2.1
+ specifier: ^5.0.1
+ version: 5.0.1
devDependencies:
'@babel/core':
specifier: 7.24.7
@@ -518,7 +524,7 @@ 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)
'@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)
@@ -600,7 +606,7 @@ importers:
version: 15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@18.19.39)(typescript@5.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4)
'@angular/cli':
specifier: 15.2.10
- version: 15.2.10(chokidar@3.6.0)
+ version: 15.2.10(chokidar@3.5.3)
'@angular/compiler-cli':
specifier: 15.2.10
version: 15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3)
@@ -621,7 +627,7 @@ importers:
version: 4.0.2(webpack@5.101.0)
sass-loader:
specifier: 14.2.1
- version: 14.2.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass-embedded@1.89.2)(sass@1.77.6)(webpack@5.101.0)
+ version: 14.2.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass-embedded@1.89.2)(sass@1.58.1)(webpack@5.101.0)
ts-node:
specifier: 10.9.2
version: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@swc/wasm@1.13.3)(@types/node@18.19.39)(typescript@5.5.3)
@@ -636,7 +642,7 @@ importers:
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
webpack-cli:
specifier: 5.1.4
- version: 5.1.4(webpack@5.101.0)
+ version: 5.1.4(webpack-dev-server@4.11.1)(webpack@5.101.0)
angular-universal-ssr/host-app:
dependencies:
@@ -688,7 +694,7 @@ importers:
version: 15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(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.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4)
'@angular/cli':
specifier: 15.2.10
- version: 15.2.10(chokidar@3.5.3)
+ version: 15.2.10(chokidar@3.6.0)
'@angular/compiler-cli':
specifier: 15.2.10
version: 15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3)
@@ -697,7 +703,7 @@ importers:
version: 15.2.11(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(typescript@5.5.3)(webpack@5.101.0)
'@nguniversal/builders':
specifier: 16.2.0
- version: 16.2.0(@angular-devkit/build-angular@15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(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.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4))(@angular/common@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(rxjs@7.8.2))(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(@types/express@4.17.21)(chokidar@3.5.3)(typescript@5.5.3)
+ version: 16.2.0(@angular-devkit/build-angular@15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(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.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4))(@angular/common@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(rxjs@7.8.2))(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(@types/express@4.17.21)(chokidar@3.6.0)(typescript@5.5.3)
clean-webpack-plugin:
specifier: 4.0.0
version: 4.0.0(webpack@5.101.0)
@@ -709,7 +715,7 @@ importers:
version: 4.0.2(webpack@5.101.0)
sass-loader:
specifier: 14.2.1
- version: 14.2.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass-embedded@1.89.2)(sass@1.58.1)(webpack@5.101.0)
+ version: 14.2.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(sass-embedded@1.89.2)(sass@1.77.6)(webpack@5.101.0)
ts-node:
specifier: 10.9.2
version: 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.5.3)
@@ -724,7 +730,7 @@ importers:
version: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
webpack-cli:
specifier: 5.1.4
- version: 5.1.4(webpack-dev-server@4.11.1)(webpack@5.101.0)
+ version: 5.1.4(webpack@5.101.0)
apollo-client:
devDependencies:
@@ -9473,7 +9479,7 @@ importers:
version: 17.0.2(react@17.0.2)
react-scripts:
specifier: 5.0.1
- version: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1)
+ version: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1)
devDependencies:
'@chromatic-com/storybook':
specifier: ^1.6.1
@@ -9501,7 +9507,7 @@ importers:
version: 8.6.14(react-dom@17.0.2(react@17.0.2))(react@17.0.2)(storybook@8.6.14(prettier@3.3.3))
'@storybook/preset-create-react-app':
specifier: ^8.2.6
- version: 8.6.14(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.11.0)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1))(storybook@8.6.14(prettier@3.3.3))(type-fest@2.19.0)(typescript@5.9.2)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ version: 8.6.14(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.17.0)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1))(storybook@8.6.14(prettier@3.3.3))(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))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
'@storybook/react':
specifier: ^8.2.6
version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.3.3)))(react-dom@17.0.2(react@17.0.2))(react@17.0.2)(storybook@8.6.14(prettier@3.3.3))(typescript@5.9.2)
@@ -9543,7 +9549,7 @@ importers:
version: 17.0.2(react@17.0.2)
react-scripts:
specifier: 5.0.1
- version: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1)
+ version: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1)
react-webpack-host-vite-remote:
devDependencies:
@@ -22643,6 +22649,9 @@ packages:
'@types/unist@3.0.3':
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+ '@types/use-sync-external-store@0.0.6':
+ resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
+
'@types/uuid@9.0.8':
resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
@@ -33483,6 +33492,18 @@ packages:
react-native:
optional: true
+ react-redux@9.2.0:
+ resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
+ peerDependencies:
+ '@types/react': 18.3.10
+ react: ^18.0 || ^19
+ redux: ^5.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ redux:
+ optional: true
+
react-refresh@0.11.0:
resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==}
engines: {node: '>=0.10.0'}
@@ -33746,6 +33767,9 @@ packages:
redux@4.2.1:
resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
+ redux@5.0.1:
+ resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
+
reflect-metadata@0.1.14:
resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==}
@@ -37522,9 +37546,9 @@ snapshots:
transitivePeerDependencies:
- chokidar
- '@angular-devkit/architect@0.1602.16(chokidar@3.5.3)':
+ '@angular-devkit/architect@0.1602.16(chokidar@3.6.0)':
dependencies:
- '@angular-devkit/core': 16.2.16(chokidar@3.5.3)
+ '@angular-devkit/core': 16.2.16(chokidar@3.6.0)
rxjs: 7.8.1
transitivePeerDependencies:
- chokidar
@@ -37822,7 +37846,7 @@ snapshots:
optionalDependencies:
chokidar: 3.6.0
- '@angular-devkit/core@16.2.16(chokidar@3.5.3)':
+ '@angular-devkit/core@16.2.16(chokidar@3.6.0)':
dependencies:
ajv: 8.12.0
ajv-formats: 2.1.1(ajv@8.12.0)
@@ -37831,7 +37855,7 @@ snapshots:
rxjs: 7.8.1
source-map: 0.7.4
optionalDependencies:
- chokidar: 3.5.3
+ chokidar: 3.6.0
'@angular-devkit/core@18.2.20(chokidar@3.6.0)':
dependencies:
@@ -38371,7 +38395,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
@@ -44624,7 +44648,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)
@@ -44651,7 +44675,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)
@@ -44678,7 +44702,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)
@@ -44705,7 +44729,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)
@@ -44731,7 +44755,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)
@@ -50025,11 +50049,11 @@ snapshots:
typescript: 5.5.3
webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
- '@nguniversal/builders@16.2.0(@angular-devkit/build-angular@15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(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.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4))(@angular/common@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(rxjs@7.8.2))(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(@types/express@4.17.21)(chokidar@3.5.3)(typescript@5.5.3)':
+ '@nguniversal/builders@16.2.0(@angular-devkit/build-angular@15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(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.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4))(@angular/common@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(rxjs@7.8.2))(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(@types/express@4.17.21)(chokidar@3.6.0)(typescript@5.5.3)':
dependencies:
- '@angular-devkit/architect': 0.1602.16(chokidar@3.5.3)
+ '@angular-devkit/architect': 0.1602.16(chokidar@3.6.0)
'@angular-devkit/build-angular': 15.2.10(@angular/compiler-cli@15.2.10(@angular/compiler@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10)))(typescript@5.5.3))(@angular/platform-server@15.2.10(6676711f88f9c40c18b0e2629d70e5ad))(@swc/core@1.13.3(@swc/helpers@0.5.17))(html-webpack-plugin@5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0))(sass-embedded@1.89.2)(tailwindcss@3.4.13(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.5.3)))(typescript@5.5.3)(webpack-cli@5.1.4)
- '@angular-devkit/core': 16.2.16(chokidar@3.5.3)
+ '@angular-devkit/core': 16.2.16(chokidar@3.6.0)
'@nguniversal/common': 16.2.0(@angular/common@15.2.10(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))(rxjs@7.8.2))(@angular/core@15.2.10(rxjs@7.8.2)(zone.js@0.14.10))
browser-sync: 2.29.3
express: 4.19.2
@@ -52116,6 +52140,23 @@ snapshots:
webpack-dev-server: 4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
webpack-hot-middleware: 2.26.1
+ '@pmmmwh/react-refresh-webpack-plugin@0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.17.0)(type-fest@2.19.0)(webpack-dev-server@5.2.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))':
+ dependencies:
+ ansi-html: 0.0.9
+ core-js-pure: 3.44.0
+ error-stack-parser: 2.1.4
+ html-entities: 2.6.0
+ loader-utils: 2.0.4
+ react-refresh: 0.17.0
+ schema-utils: 4.3.2
+ source-map: 0.7.6
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)
+ optionalDependencies:
+ '@types/webpack': 5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)
+ type-fest: 2.19.0
+ webpack-dev-server: 5.2.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ webpack-hot-middleware: 2.26.1
+
'@pmmmwh/react-refresh-webpack-plugin@0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4))(react-refresh@0.14.2)(type-fest@2.19.0)(webpack-dev-server@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.101.0)':
dependencies:
ansi-html: 0.0.9
@@ -55081,13 +55122,13 @@ snapshots:
'@storybook/node-logger@7.6.20': {}
- ? '@storybook/preset-create-react-app@8.6.14(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.11.0)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1))(storybook@8.6.14(prettier@3.3.3))(type-fest@2.19.0)(typescript@5.9.2)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))'
+ ? '@storybook/preset-create-react-app@8.6.14(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.17.0)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1))(storybook@8.6.14(prettier@3.3.3))(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))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))'
: dependencies:
- '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.11.0)(type-fest@2.19.0)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.17.0)(type-fest@2.19.0)(webpack-dev-server@5.2.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
'@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.9.2)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
'@types/semver': 7.7.0
pnp-webpack-plugin: 1.7.0(typescript@5.9.2)
- react-scripts: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1)
+ react-scripts: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1)
semver: 7.6.3
storybook: 8.6.14(prettier@3.3.3)
transitivePeerDependencies:
@@ -56386,6 +56427,8 @@ snapshots:
'@types/unist@3.0.3': {}
+ '@types/use-sync-external-store@0.0.6': {}
+
'@types/uuid@9.0.8': {}
'@types/webpack-bundle-analyzer@4.7.0(@swc/core@1.13.3(@swc/helpers@0.5.17))':
@@ -61689,7 +61732,7 @@ snapshots:
semver: 7.6.3
optionalDependencies:
'@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-cli@5.1.4)
+ webpack: 5.101.0(@swc/core@1.6.13(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
css-minimizer-webpack-plugin@3.4.1(esbuild@0.23.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)):
dependencies:
@@ -69714,7 +69757,7 @@ snapshots:
dependencies:
schema-utils: 4.3.2
tapable: 2.2.2
- webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
+ webpack: 5.101.0(@swc/core@1.6.13(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
minimalistic-assert@1.0.1: {}
@@ -74257,6 +74300,15 @@ snapshots:
optionalDependencies:
react-dom: 16.14.0(react@16.14.0)
+ 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
+ react: 18.3.1
+ use-sync-external-store: 1.5.0(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.10
+ redux: 5.0.1
+
react-refresh@0.11.0: {}
react-refresh@0.14.0: {}
@@ -74417,56 +74469,56 @@ snapshots:
'@remix-run/router': 1.23.0
react: 18.3.1
- react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1):
+ react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1):
dependencies:
'@babel/core': 7.24.7
- '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.11.0)(type-fest@2.19.0)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(react-refresh@0.11.0)(type-fest@2.19.0)(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)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
'@svgr/webpack': 5.5.0
babel-jest: 27.5.1(@babel/core@7.24.7)
- babel-loader: 8.4.1(@babel/core@7.24.7)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ babel-loader: 8.4.1(@babel/core@7.24.7)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
babel-plugin-named-asset-import: 0.3.8(@babel/core@7.24.7)
babel-preset-react-app: 10.1.0
bfj: 7.1.0
browserslist: 4.25.1
camelcase: 6.3.0
case-sensitive-paths-webpack-plugin: 2.4.0
- css-loader: 6.11.0(@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))
- css-minimizer-webpack-plugin: 3.4.1(esbuild@0.23.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ css-loader: 6.11.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ css-minimizer-webpack-plugin: 3.4.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
dotenv: 10.0.0
dotenv-expand: 5.1.0
eslint: 9.6.0
eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.24.7))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.24.7))(eslint@9.6.0)(jest@27.5.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)))(typescript@5.9.2)
- eslint-webpack-plugin: 3.2.0(eslint@9.6.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
- file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ eslint-webpack-plugin: 3.2.0(eslint@9.6.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
fs-extra: 10.1.0
- html-webpack-plugin: 5.6.0(@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))
+ html-webpack-plugin: 5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
identity-obj-proxy: 3.0.0
jest: 27.5.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))
jest-resolve: 27.5.1
jest-watch-typeahead: 1.1.0(jest@27.5.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)))
- 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))
+ mini-css-extract-plugin: 2.9.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
postcss: 8.4.47
postcss-flexbugs-fixes: 5.0.2(postcss@8.4.47)
- postcss-loader: 6.2.1(postcss@8.4.47)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ postcss-loader: 6.2.1(postcss@8.4.47)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
postcss-normalize: 10.0.1(browserslist@4.25.1)(postcss@8.4.47)
postcss-preset-env: 7.8.3(postcss@8.4.47)
prompts: 2.4.2
react: 17.0.2
react-app-polyfill: 3.0.0
- react-dev-utils: 12.0.1(eslint@9.6.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ react-dev-utils: 12.0.1(eslint@9.6.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
react-refresh: 0.11.0
resolve: 1.22.10
resolve-url-loader: 4.0.0
- sass-loader: 12.6.0(sass-embedded@1.89.2)(sass@1.77.6)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ sass-loader: 12.6.0(sass-embedded@1.89.2)(sass@1.77.6)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
semver: 7.6.3
- source-map-loader: 3.0.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
- style-loader: 3.3.4(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ source-map-loader: 3.0.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ style-loader: 3.3.4(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
tailwindcss: 3.4.13(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))
- terser-webpack-plugin: 5.3.10(@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: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)
- webpack-dev-server: 4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
- webpack-manifest-plugin: 4.1.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
- workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ terser-webpack-plugin: 5.3.10(@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)))
+ webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.17.19)
+ webpack-dev-server: 4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ webpack-manifest-plugin: 4.1.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
optionalDependencies:
fsevents: 2.3.3
typescript: 5.9.2
@@ -74504,56 +74556,56 @@ snapshots:
- webpack-hot-middleware
- webpack-plugin-serve
- react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1):
+ react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(@rspack/core@1.4.11(@swc/helpers@0.5.17))(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(esbuild@0.23.0)(eslint@9.6.0)(react@17.0.2)(sass-embedded@1.89.2)(sass@1.77.6)(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))(type-fest@2.19.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack-hot-middleware@2.26.1):
dependencies:
'@babel/core': 7.24.7
- '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))(react-refresh@0.11.0)(type-fest@2.19.0)(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)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(@types/webpack@5.28.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))(react-refresh@0.11.0)(type-fest@2.19.0)(webpack-dev-server@4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)))(webpack-hot-middleware@2.26.1)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
'@svgr/webpack': 5.5.0
babel-jest: 27.5.1(@babel/core@7.24.7)
- babel-loader: 8.4.1(@babel/core@7.24.7)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ babel-loader: 8.4.1(@babel/core@7.24.7)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
babel-plugin-named-asset-import: 0.3.8(@babel/core@7.24.7)
babel-preset-react-app: 10.1.0
bfj: 7.1.0
browserslist: 4.25.1
camelcase: 6.3.0
case-sensitive-paths-webpack-plugin: 2.4.0
- css-loader: 6.11.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
- css-minimizer-webpack-plugin: 3.4.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ css-loader: 6.11.0(@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))
+ css-minimizer-webpack-plugin: 3.4.1(esbuild@0.23.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
dotenv: 10.0.0
dotenv-expand: 5.1.0
eslint: 9.6.0
eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0))(eslint@9.6.0)(jest@27.5.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)))(typescript@5.9.2)
- eslint-webpack-plugin: 3.2.0(eslint@9.6.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
- file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ eslint-webpack-plugin: 3.2.0(eslint@9.6.0)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ file-loader: 6.2.0(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
fs-extra: 10.1.0
- html-webpack-plugin: 5.6.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ html-webpack-plugin: 5.6.0(@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))
identity-obj-proxy: 3.0.0
jest: 27.5.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))
jest-resolve: 27.5.1
jest-watch-typeahead: 1.1.0(jest@27.5.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)))
- mini-css-extract-plugin: 2.9.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ 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))
postcss: 8.4.47
postcss-flexbugs-fixes: 5.0.2(postcss@8.4.47)
- postcss-loader: 6.2.1(postcss@8.4.47)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ postcss-loader: 6.2.1(postcss@8.4.47)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
postcss-normalize: 10.0.1(browserslist@4.25.1)(postcss@8.4.47)
postcss-preset-env: 7.8.3(postcss@8.4.47)
prompts: 2.4.2
react: 17.0.2
react-app-polyfill: 3.0.0
- react-dev-utils: 12.0.1(eslint@9.6.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ react-dev-utils: 12.0.1(eslint@9.6.0)(typescript@5.9.2)(vue-template-compiler@2.7.16)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
react-refresh: 0.11.0
resolve: 1.22.10
resolve-url-loader: 4.0.0
- sass-loader: 12.6.0(sass-embedded@1.89.2)(sass@1.77.6)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ sass-loader: 12.6.0(sass-embedded@1.89.2)(sass@1.77.6)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
semver: 7.6.3
- source-map-loader: 3.0.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
- style-loader: 3.3.4(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ source-map-loader: 3.0.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ style-loader: 3.3.4(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
tailwindcss: 3.4.13(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))
- terser-webpack-plugin: 5.3.10(@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)))
- webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.17.19)
- webpack-dev-server: 4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
- webpack-manifest-plugin: 4.1.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
- workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17)))
+ terser-webpack-plugin: 5.3.10(@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: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0)
+ webpack-dev-server: 4.15.2(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ webpack-manifest-plugin: 4.1.1(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
+ workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(esbuild@0.23.0))
optionalDependencies:
fsevents: 2.3.3
typescript: 5.9.2
@@ -74822,6 +74874,8 @@ snapshots:
dependencies:
'@babel/runtime': 7.28.2
+ redux@5.0.1: {}
+
reflect-metadata@0.1.14: {}
reflect-metadata@0.2.2: {}
@@ -76500,7 +76554,7 @@ snapshots:
style-loader@4.0.0(webpack@5.101.0):
dependencies:
- webpack: 5.101.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
+ webpack: 5.101.0(@swc/core@1.6.13(@swc/helpers@0.5.17))(webpack-cli@5.1.4)
style-resources-loader@1.5.0(webpack@5.88.2(@swc/core@1.13.3(@swc/helpers@0.5.17))):
dependencies:
@@ -81078,7 +81132,7 @@ snapshots:
watchpack: 2.4.4
webpack-sources: 3.3.3
optionalDependencies:
- webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.0.4)(webpack@5.101.0)
+ webpack-cli: 5.1.4(webpack@5.101.0)
transitivePeerDependencies:
- '@swc/core'
- esbuild