-
Notifications
You must be signed in to change notification settings - Fork 71
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
Any change happen inside the MFEs or Shell won't be Appear until I do a reload for the page
// Shell/vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { federation } from '@module-federation/vite';
import { dependencies } from './package.json';
import path from "path"
import tailwindcss from "@tailwindcss/vite"
export default defineConfig({
plugins: [
react({reactRefreshHost:'http://localhost:4200'}),
tailwindcss(),
federation({
name: 'shell',
remotes: {
mfe1: {
type: 'module',
name: 'mfe1',
entry: 'http://localhost:4201/remoteEntry.js',
entryGlobalName: 'mfe1',
shareScope: 'default'
},
mfe2: {
type: 'module',
name: 'mfe2',
entry: 'http://localhost:4202/remoteEntry.js',
entryGlobalName: 'mfe2',
shareScope: 'default'
}
},
shared: {
react: {
singleton: true,
requiredVersion: dependencies.react,
strictVersion: false,
},
'react-dom': {
singleton: true,
requiredVersion: dependencies['react-dom'],
strictVersion: false,
},
'react-router-dom': {
singleton: true,
requiredVersion: dependencies['react-router-dom'],
strictVersion: false,
},
},
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
build: {
target: 'esnext',
minify: false,
cssCodeSplit: false,
rollupOptions: {
external: [],
}
},
server: {
port: 4200,
cors: true,
hmr: {
port: 4210,
host: 'localhost',
},
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
},
// Proxy configuration to handle MFE requests
proxy: {
'/mfe1': {
target: 'http://localhost:4201',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/mfe1/, ''),
},
'/mfe2': {
target: 'http://localhost:4202',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/mfe2/, ''),
},
},
watch: {
usePolling: true,
interval: 100,
}
},
});
// MFE1/vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { federation } from '@module-federation/vite';
import { dependencies } from './package.json';
import path from "path"
import tailwindcss from "@tailwindcss/vite"
export default defineConfig({
plugins: [
react(),
tailwindcss(),
federation({
name: 'mfe1',
filename: 'remoteEntry.js',
exposes: {
'./App': './src/App.tsx',
'./routes': './src/routes.tsx',
'./Button': './src/components/Button.tsx',
},
shared: {
react: {
singleton: true,
requiredVersion: dependencies.react,
strictVersion: false,
},
'react-dom': {
singleton: true,
requiredVersion: dependencies['react-dom'],
strictVersion: false,
},
'react-router-dom': {
singleton: true,
requiredVersion: dependencies['react-router-dom'],
strictVersion: false,
},
},
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
build: {
target: 'esnext',
minify: false,
cssCodeSplit: false,
rollupOptions: {
external: [],
}
},
server: {
port: 4201,
cors: true,
// Enhanced HMR configuration
hmr: {
port: 4211, // Different HMR port to avoid conflicts
host: 'localhost',
},
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
},
// Watch options for better file detection
watch: {
usePolling: true,
interval: 100,
}
},
});
// MFE2/vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { federation } from '@module-federation/vite';
import { dependencies } from './package.json';
export default defineConfig({
plugins: [
react(),
federation({
name: 'mfe2',
filename: 'remoteEntry.js',
exposes: {
'./App': './src/App.tsx',
'./routes': './src/routes.tsx',
},
shared: {
react: {
singleton: true,
requiredVersion: dependencies.react,
strictVersion: false,
},
'react-dom': {
singleton: true,
requiredVersion: dependencies['react-dom'],
strictVersion: false,
},
'react-router-dom': {
singleton: true,
requiredVersion: dependencies['react-router-dom'],
strictVersion: false,
},
},
}),
],
build: {
target: 'esnext',
minify: false,
cssCodeSplit: false,
rollupOptions: {
external: [],
}
},
server: {
port: 4202,
cors: true,
hmr: {
port: 4212, // Different HMR port
host: 'localhost',
},
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
},
watch: {
usePolling: true,
interval: 100,
}
},
});
// Shell/App.tsx
import { Suspense, lazy, } from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import './App.css';
const Mfe1App = lazy(() =>
import('mfe1/App').catch(err => {
console.error('Failed to load MFE1:', err);
return { default: () => <div>Error loading MFE1. Please ensure it's running on port 5001.</div> };
})
);
const Mfe2App = lazy(() =>
import('mfe2/App').catch(err => {
console.error('Failed to load MFE2:', err);
return { default: () => <div>Error loading MFE2. Please ensure it's running on port 5002.</div> };
})
);
function App() {
return (
<BrowserRouter>
<div className="shell-container">
<header className="shell-header">
<h1>React Shell Application</h1>
<nav>
<Link to="/">Home</Link> | <Link to="/mfe1">MFE1</Link> | <Link to="/mfe2">MFE2</Link>
</nav>
</header>
<main className="shell-content">
<Suspense fallback={<div>Loading MFE...</div>}>
<Routes>
<Route path="/" element={<h2>Welcome to the Shell!</h2>} />
<Route path="/mfe1/*" element={<Mfe1App />} />
<Route path="/mfe2/*" element={<Mfe2App />} />
<Route path="/shared-button" element={
<div>
<h3>Local Button Component:</h3>
<button style={{ padding: '10px 20px', backgroundColor: 'lightblue' }}>
Local Button
</button>
</div>
} />
<Route path="*" element={<h2>404 - Not Found</h2>} />
</Routes>
</Suspense>
</main>
</div>
</BrowserRouter>
);
}
export default App;
Version
"@module-federation/vite": "^1.4.1",
"vite": "^6.3.5"
"react": "^19.1.0",
Reproduction
HMR-MFEs-React
Relevant log output
Validations
- Read the docs.
- Read the common issues list.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- The provided reproduction is a minimal reproducible example of the bug.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working