Dynamic Loading of MFE exposing multiple entries doesn't work
yoniabitbolkryon opened this issue · 2 comments
Versions
- vite-plugin-federation: v1.3.5
- vite: v4.5.3
- react: v18.3.1
- react-dom: v18.3.1
Reproduction
MFE vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import federation from "@originjs/vite-plugin-federation";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
federation({
name: "pokemonList",
filename: "remoteEntry.js",
exposes: {
"./PokemonList": "./src/components/PokemonList",
"./PokemonList2": "./src/components/PokemonList2"
},
shared: ["react", "react-dom", "jotai"],
}),
],
build: {
modulePreload: false,
target: "esnext",
minify: false,
cssCodeSplit: false,
},
});
Host vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import federation from "@originjs/vite-plugin-federation";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
federation({
name: "pokemonHome",
remotes: {
dummy: "dummy",
},
shared: ["react", "react-dom"],
}),
],
build: {
modulePreload: false,
target: "esnext",
minify: false,
cssCodeSplit: false,
},
});
Host App.jsx:
import {lazy, useEffect, useState} from "react";
import {__federation_method_getRemote, __federation_method_setRemote} from "__federation__";
import "./App.css";
const loadComponent = (scope, module, remoteUrl) => {
return async () => {
console.log('loadComponent', scope, module, remoteUrl);
try {
__federation_method_setRemote(scope, {
url: (typeof remoteUrl === 'string') ? () => Promise.resolve(remoteUrl) : remoteUrl,
format: "esm",
from: "vite",
});
return __federation_method_getRemote(scope, module);
} catch (err) {
console.error('loadComponent loading remote component', err);
}
};
};
const componentCache = new Map();
export const useFederatedComponent =(
remoteUrl,
scope,
module
) => {
const key = `${scope}-${module}`;
const [Component, setComponent] = useState(null);
useEffect(() => {
if (Component) setComponent(null);
// eslint-disable-next-line react-hooks/exhaustive-deps -- Only recalculate when key changes
}, [key]);
useEffect(() => {
if (!Component) {
const Comp = lazy(loadComponent(scope, module, remoteUrl));
componentCache.set(key, Comp);
setComponent(Comp);
}
// eslint-disable-next-line react-hooks/exhaustive-deps -- key includes all dependencies (scope/module)
}, [Component, key]);
return {Component};
};
function App() {
const {Component: PokemonList} =
useFederatedComponent("http://localhost:5174/assets/remoteEntry.js", "pokemonList", "./PokemonList");
const {Component: PokemonList2} =
useFederatedComponent("http://localhost:5174/assets/remoteEntry.js", "pokemonList2", "./PokemonList2");
return (
<>
<h3 style={{color: "#1e3a8a", fontSize: "20px"}}>
Created using Vite + vite-plugin-federation
</h3>
{PokemonList ? <PokemonList/> : <></>}
{PokemonList2 ? <PokemonList2/> : <></>}
</>
);
}
export default App;
Steps to reproduce
Project reproduction: vite.zip
What is Expected?
The Host should display 2 component showing list of Pokémon.
What is actually happening?
page is empty and Console has multiple errors:
Warning: lazy: Expected the result of a dynamic import() call. Instead received: () => {
const [, addPokemons] = useAtom(addAllPokemons);
const [pokemons$1] = useAtom(pokemons);
const [, setSelectPokemon] = useSelectPokemon();
const fetchPokemons = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/kevinuehara/microfrontends/main/mocks/pokemonList.json"
);
const jsonData = await response.json();
addPokemons(jsonData);
};
useEffect(() => {
fetchPokemons();
}, []);
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.container, children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("h1", { children: "Pokémon List Micro Frontend" }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 29,
columnNumber: 7
}, globalThis),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.pokemonCardContainer, children: pokemons$1.map((pokemon) => {
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"div",
{
className: style.pokemonCard,
onClick: () => setSelectPokemon(pokemon),
children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"img",
{
src: pokemon.sprite,
"aria-label": `Image of pokemon ${pokemon.name}`
},
void 0,
false,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 38,
columnNumber: 15
},
globalThis
),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("label", { children: pokemon.name }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 42,
columnNumber: 15
}, globalThis)
]
},
pokemon.id,
true,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 33,
columnNumber: 13
},
globalThis
);
}) }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 30,
columnNumber: 7
}, globalThis)
] }, void 0, true, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 28,
columnNumber: 5
}, globalThis);
}
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))
at App (http://localhost:5173/src/App.jsx?t=1720595273552:57:38)
printWarning @ chunk-3ON3CNAS.js?v=b0864ebc:137
error @ chunk-3ON3CNAS.js?v=b0864ebc:121
lazyInitializer @ chunk-3ON3CNAS.js?v=b0864ebc:899
resolveLazy @ chunk-FMOPAGIP.js?v=b0864ebc:9965
updateElement @ chunk-FMOPAGIP.js?v=b0864ebc:10058
updateSlot @ chunk-FMOPAGIP.js?v=b0864ebc:10147
reconcileChildrenArray @ chunk-FMOPAGIP.js?v=b0864ebc:10267
reconcileChildFibers2 @ chunk-FMOPAGIP.js?v=b0864ebc:10575
reconcileChildren @ chunk-FMOPAGIP.js?v=b0864ebc:14310
updateFunctionComponent @ chunk-FMOPAGIP.js?v=b0864ebc:14624
beginWork @ chunk-FMOPAGIP.js?v=b0864ebc:15942
beginWork$1 @ chunk-FMOPAGIP.js?v=b0864ebc:19779
performUnitOfWork @ chunk-FMOPAGIP.js?v=b0864ebc:19224
workLoopSync @ chunk-FMOPAGIP.js?v=b0864ebc:19163
renderRootSync @ chunk-FMOPAGIP.js?v=b0864ebc:19142
performConcurrentWorkOnRoot @ chunk-FMOPAGIP.js?v=b0864ebc:18704
workLoop @ chunk-FMOPAGIP.js?v=b0864ebc:195
flushWork @ chunk-FMOPAGIP.js?v=b0864ebc:174
performWorkUntilDeadline @ chunk-FMOPAGIP.js?v=b0864ebc:382
Show 19 more frames
Show lessUnderstand this error
App.jsx:7 loadComponent pokemonList2 ./PokemonList2 http://localhost:5174/assets/remoteEntry.js
chunk-3ON3CNAS.js?v=b0864ebc:137 Warning: lazy: Expected the result of a dynamic import() call. Instead received: () => {
const [, addPokemons] = useAtom(addAllPokemons);
const [pokemons$1] = useAtom(pokemons);
const [, setSelectPokemon] = useSelectPokemon();
const fetchPokemons = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/kevinuehara/microfrontends/main/mocks/pokemonList.json"
);
const jsonData = await response.json();
addPokemons(jsonData);
};
useEffect(() => {
fetchPokemons();
}, []);
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.container, children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("h1", { children: "Pokémon List Micro Frontend" }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 29,
columnNumber: 7
}, globalThis),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.pokemonCardContainer, children: pokemons$1.map((pokemon) => {
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"div",
{
className: style.pokemonCard,
onClick: () => setSelectPokemon(pokemon),
children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"img",
{
src: pokemon.sprite,
"aria-label": `Image of pokemon ${pokemon.name}`
},
void 0,
false,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 38,
columnNumber: 15
},
globalThis
),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("label", { children: pokemon.name }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 42,
columnNumber: 15
}, globalThis)
]
},
pokemon.id,
true,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 33,
columnNumber: 13
},
globalThis
);
}) }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 30,
columnNumber: 7
}, globalThis)
] }, void 0, true, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 28,
columnNumber: 5
}, globalThis);
}
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))
at App (http://localhost:5173/src/App.jsx?t=1720595273552:57:38)
printWarning @ chunk-3ON3CNAS.js?v=b0864ebc:137
error @ chunk-3ON3CNAS.js?v=b0864ebc:121
lazyInitializer @ chunk-3ON3CNAS.js?v=b0864ebc:899
resolveLazy @ chunk-FMOPAGIP.js?v=b0864ebc:9965
updateElement @ chunk-FMOPAGIP.js?v=b0864ebc:10058
updateSlot @ chunk-FMOPAGIP.js?v=b0864ebc:10147
reconcileChildrenArray @ chunk-FMOPAGIP.js?v=b0864ebc:10267
reconcileChildFibers2 @ chunk-FMOPAGIP.js?v=b0864ebc:10575
reconcileChildren @ chunk-FMOPAGIP.js?v=b0864ebc:14310
updateFunctionComponent @ chunk-FMOPAGIP.js?v=b0864ebc:14624
beginWork @ chunk-FMOPAGIP.js?v=b0864ebc:15942
beginWork$1 @ chunk-FMOPAGIP.js?v=b0864ebc:19779
performUnitOfWork @ chunk-FMOPAGIP.js?v=b0864ebc:19224
workLoopSync @ chunk-FMOPAGIP.js?v=b0864ebc:19163
renderRootSync @ chunk-FMOPAGIP.js?v=b0864ebc:19142
performConcurrentWorkOnRoot @ chunk-FMOPAGIP.js?v=b0864ebc:18704
workLoop @ chunk-FMOPAGIP.js?v=b0864ebc:195
flushWork @ chunk-FMOPAGIP.js?v=b0864ebc:174
performWorkUntilDeadline @ chunk-FMOPAGIP.js?v=b0864ebc:382
Show 19 more frames
Show lessUnderstand this error
chunk-3ON3CNAS.js?v=b0864ebc:137 Warning: lazy: Expected the result of a dynamic import() call. Instead received: () => {
const [, addPokemons] = useAtom(addAllPokemons);
const [pokemons$1] = useAtom(pokemons);
const [, setSelectPokemon] = useSelectPokemon();
const fetchPokemons = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/kevinuehara/microfrontends/main/mocks/pokemonList.json"
);
const jsonData = await response.json();
addPokemons(jsonData);
};
useEffect(() => {
fetchPokemons();
}, []);
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.container, children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("h1", { children: "Pokémon List Micro Frontend" }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList2/index.tsx",
lineNumber: 29,
columnNumber: 7
}, globalThis),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.pokemonCardContainer, children: pokemons$1.map((pokemon) => {
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"div",
{
className: style.pokemonCard,
onClick: () => setSelectPokemon(pokemon),
children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"img",
{
src: pokemon.sprite,
"aria-label": `Image of pokemon ${pokemon.name}`
},
void 0,
false,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList2/index.tsx",
lineNumber: 38,
columnNumber: 15
},
globalThis
),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("label", { children: pokemon.name }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList2/index.tsx",
lineNumber: 42,
columnNumber: 15
}, globalThis)
]
},
pokemon.id,
true,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList2/index.tsx",
lineNumber: 33,
columnNumber: 13
},
globalThis
);
}) }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList2/index.tsx",
lineNumber: 30,
columnNumber: 7
}, globalThis)
] }, void 0, true, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList2/index.tsx",
lineNumber: 28,
columnNumber: 5
}, globalThis);
}
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))
at App (http://localhost:5173/src/App.jsx?t=1720595273552:57:38)
printWarning @ chunk-3ON3CNAS.js?v=b0864ebc:137
error @ chunk-3ON3CNAS.js?v=b0864ebc:121
lazyInitializer @ chunk-3ON3CNAS.js?v=b0864ebc:899
resolveLazy @ chunk-FMOPAGIP.js?v=b0864ebc:9965
updateElement @ chunk-FMOPAGIP.js?v=b0864ebc:10058
updateSlot @ chunk-FMOPAGIP.js?v=b0864ebc:10147
reconcileChildrenArray @ chunk-FMOPAGIP.js?v=b0864ebc:10267
reconcileChildFibers2 @ chunk-FMOPAGIP.js?v=b0864ebc:10575
reconcileChildren @ chunk-FMOPAGIP.js?v=b0864ebc:14310
updateFunctionComponent @ chunk-FMOPAGIP.js?v=b0864ebc:14624
beginWork @ chunk-FMOPAGIP.js?v=b0864ebc:15942
beginWork$1 @ chunk-FMOPAGIP.js?v=b0864ebc:19779
performUnitOfWork @ chunk-FMOPAGIP.js?v=b0864ebc:19224
workLoopSync @ chunk-FMOPAGIP.js?v=b0864ebc:19163
renderRootSync @ chunk-FMOPAGIP.js?v=b0864ebc:19142
performConcurrentWorkOnRoot @ chunk-FMOPAGIP.js?v=b0864ebc:18704
workLoop @ chunk-FMOPAGIP.js?v=b0864ebc:195
flushWork @ chunk-FMOPAGIP.js?v=b0864ebc:174
performWorkUntilDeadline @ chunk-FMOPAGIP.js?v=b0864ebc:382
Show 19 more frames
Show lessUnderstand this error
chunk-3ON3CNAS.js?v=b0864ebc:137 Warning: lazy: Expected the result of a dynamic import() call. Instead received: () => {
const [, addPokemons] = useAtom(addAllPokemons);
const [pokemons$1] = useAtom(pokemons);
const [, setSelectPokemon] = useSelectPokemon();
const fetchPokemons = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/kevinuehara/microfrontends/main/mocks/pokemonList.json"
);
const jsonData = await response.json();
addPokemons(jsonData);
};
useEffect(() => {
fetchPokemons();
}, []);
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.container, children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("h1", { children: "Pokémon List Micro Frontend" }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 29,
columnNumber: 7
}, globalThis),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.pokemonCardContainer, children: pokemons$1.map((pokemon) => {
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"div",
{
className: style.pokemonCard,
onClick: () => setSelectPokemon(pokemon),
children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"img",
{
src: pokemon.sprite,
"aria-label": `Image of pokemon ${pokemon.name}`
},
void 0,
false,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 38,
columnNumber: 15
},
globalThis
),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("label", { children: pokemon.name }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 42,
columnNumber: 15
}, globalThis)
]
},
pokemon.id,
true,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 33,
columnNumber: 13
},
globalThis
);
}) }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 30,
columnNumber: 7
}, globalThis)
] }, void 0, true, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 28,
columnNumber: 5
}, globalThis);
}
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))
at Lazy
at App (http://localhost:5173/src/App.jsx?t=1720595273552:57:38)
printWarning @ chunk-3ON3CNAS.js?v=b0864ebc:137
error @ chunk-3ON3CNAS.js?v=b0864ebc:121
lazyInitializer @ chunk-3ON3CNAS.js?v=b0864ebc:899
mountLazyComponent @ chunk-FMOPAGIP.js?v=b0864ebc:14840
beginWork @ chunk-FMOPAGIP.js?v=b0864ebc:15936
beginWork$1 @ chunk-FMOPAGIP.js?v=b0864ebc:19779
performUnitOfWork @ chunk-FMOPAGIP.js?v=b0864ebc:19224
workLoopSync @ chunk-FMOPAGIP.js?v=b0864ebc:19163
renderRootSync @ chunk-FMOPAGIP.js?v=b0864ebc:19142
performConcurrentWorkOnRoot @ chunk-FMOPAGIP.js?v=b0864ebc:18704
workLoop @ chunk-FMOPAGIP.js?v=b0864ebc:195
flushWork @ chunk-FMOPAGIP.js?v=b0864ebc:174
performWorkUntilDeadline @ chunk-FMOPAGIP.js?v=b0864ebc:382
Show 13 more frames
Show lessUnderstand this error
chunk-3ON3CNAS.js?v=b0864ebc:137 Warning: lazy: Expected the result of a dynamic import() call. Instead received: () => {
const [, addPokemons] = useAtom(addAllPokemons);
const [pokemons$1] = useAtom(pokemons);
const [, setSelectPokemon] = useSelectPokemon();
const fetchPokemons = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/kevinuehara/microfrontends/main/mocks/pokemonList.json"
);
const jsonData = await response.json();
addPokemons(jsonData);
};
useEffect(() => {
fetchPokemons();
}, []);
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.container, children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("h1", { children: "Pokémon List Micro Frontend" }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 29,
columnNumber: 7
}, globalThis),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: style.pokemonCardContainer, children: pokemons$1.map((pokemon) => {
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"div",
{
className: style.pokemonCard,
onClick: () => setSelectPokemon(pokemon),
children: [
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
"img",
{
src: pokemon.sprite,
"aria-label": `Image of pokemon ${pokemon.name}`
},
void 0,
false,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 38,
columnNumber: 15
},
globalThis
),
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("label", { children: pokemon.name }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 42,
columnNumber: 15
}, globalThis)
]
},
pokemon.id,
true,
{
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 33,
columnNumber: 13
},
globalThis
);
}) }, void 0, false, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 30,
columnNumber: 7
}, globalThis)
] }, void 0, true, {
fileName: "C:/Users/AbitboY/Downloads/microfrontends-module-federation-main/vite/pokemons-list/src/components/PokemonList/index.tsx",
lineNumber: 28,
columnNumber: 5
}, globalThis);
}
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))
at Lazy
at App (http://localhost:5173/src/App.jsx?t=1720595273552:57:38)
printWarning @ chunk-3ON3CNAS.js?v=b0864ebc:137
error @ chunk-3ON3CNAS.js?v=b0864ebc:121
lazyInitializer @ chunk-3ON3CNAS.js?v=b0864ebc:899
mountLazyComponent @ chunk-FMOPAGIP.js?v=b0864ebc:14840
beginWork @ chunk-FMOPAGIP.js?v=b0864ebc:15936
callCallback2 @ chunk-FMOPAGIP.js?v=b0864ebc:3672
invokeGuardedCallbackDev @ chunk-FMOPAGIP.js?v=b0864ebc:3697
invokeGuardedCallback @ chunk-FMOPAGIP.js?v=b0864ebc:3731
beginWork$1 @ chunk-FMOPAGIP.js?v=b0864ebc:19791
performUnitOfWork @ chunk-FMOPAGIP.js?v=b0864ebc:19224
workLoopSync @ chunk-FMOPAGIP.js?v=b0864ebc:19163
renderRootSync @ chunk-FMOPAGIP.js?v=b0864ebc:19142
performConcurrentWorkOnRoot @ chunk-FMOPAGIP.js?v=b0864ebc:18704
workLoop @ chunk-FMOPAGIP.js?v=b0864ebc:195
flushWork @ chunk-FMOPAGIP.js?v=b0864ebc:174
performWorkUntilDeadline @ chunk-FMOPAGIP.js?v=b0864ebc:382
Show 16 more frames
Show lessUnderstand this error
chunk-FMOPAGIP.js?v=b0864ebc:14900 Uncaught Error: Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function.
at mountLazyComponent (chunk-FMOPAGIP.js?v=b0864ebc:14900:17)
at beginWork (chunk-FMOPAGIP.js?v=b0864ebc:15936:22)
at HTMLUnknownElement.callCallback2 (chunk-FMOPAGIP.js?v=b0864ebc:3672:22)
at Object.invokeGuardedCallbackDev (chunk-FMOPAGIP.js?v=b0864ebc:3697:24)
at invokeGuardedCallback (chunk-FMOPAGIP.js?v=b0864ebc:3731:39)
at beginWork$1 (chunk-FMOPAGIP.js?v=b0864ebc:19791:15)
at performUnitOfWork (chunk-FMOPAGIP.js?v=b0864ebc:19224:20)
at workLoopSync (chunk-FMOPAGIP.js?v=b0864ebc:19163:13)
at renderRootSync (chunk-FMOPAGIP.js?v=b0864ebc:19142:15)
at performConcurrentWorkOnRoot (chunk-FMOPAGIP.js?v=b0864ebc:18704:83)
Hey!
I had a similar issue. When you have multiple exposes in MFE the module federation plugin automatically changes the export in the federation entry point and then you don't have a default export.
In my case, the below fixes the issue, and modules were loaded correctly when there was a single or multiple exposes.
const remote = await federation.__federation_method_getRemote(moduleName, exposeName);
return "default" in remote ? remote : { default: remote };
Hey!
I had a similar issue. When you have multiple exposes in MFE the module federation plugin automatically changes the export in the federation entry point and then you don't have a default export.
In my case, the below fixes the issue, and modules were loaded correctly when there was a single or multiple exposes.
const remote = await federation.__federation_method_getRemote(moduleName, exposeName); return "default" in remote ? remote : { default: remote };
thank you, it worked! :)