I recently made a federated module host that is federating the Header and the Footer of a site. Everything works as expected, but I am trying to build in some fallbacks if the request to the federated host fails.
new ModuleFederationPlugin({
name: 'app',
remotes: {
app2: 'app2@https:/example/remoteEntry.js',
},
shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true } },
}),
If I block the request to https:/example/remoteEntry.js I get a the webpack error below. Ideally I would like to load a basic fallback header or just no header than the page pletely dying
(error: .js1)
while loading "./Footer" from webpack/container/reference/app2
I recently made a federated module host that is federating the Header and the Footer of a site. Everything works as expected, but I am trying to build in some fallbacks if the request to the federated host fails.
new ModuleFederationPlugin({
name: 'app',
remotes: {
app2: 'app2@https:/example./remoteEntry.js',
},
shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true } },
}),
If I block the request to https:/example./remoteEntry.js I get a the webpack error below. Ideally I would like to load a basic fallback header or just no header than the page pletely dying
(error: https://example./remoteEntry.js1)
while loading "./Footer" from webpack/container/reference/app2
Share
Improve this question
asked Oct 28, 2020 at 22:46
user1320691user1320691
831 silver badge5 bronze badges
2
- Have you found any solution? – Muhammad Kamal Commented Jan 19, 2021 at 7:44
- 2 This tutorial by Jack Herrington talks about fallback to npm version of the same federated module. Probably what you need m.youtube./watch?v=K-yQB9YGmgE – PSWai Commented Mar 13, 2021 at 2:28
2 Answers
Reset to default 6I know it's a bit late, but I developed this solution, and possibly it can help someone else with Webpack@5 and Module Federation. It's also based on Dynamic Remotes.
https://webpack.js/concepts/module-federation/#promise-based-dynamic-remotes
new ModuleFederationPlugin({
name: "app",
remotes: {
app2: `promise new Promise(resolve => {
// This part depends on how you plan on hosting and versioning your federated modules
const remoteUrlWithVersion = 'https:/example./remoteEntry.js'
const script = document.createElement('script')
script.src = remoteUrlWithVersion
script.onload = () => {
// the injected script has loaded and is available on window
// we can now resolve this Promise
const proxy = {
get: (request) => {
// Note the name of the module
return window.app2.get(request);
},
init: (arg) => {
try {
// Note the name of the module
return window.app2.init(arg)
} catch(e) {
console.log('remote container already initialized')
}
}
}
resolve(proxy)
}
script.onerror = (error) => {
console.error('error loading remote container')
const proxy = {
get: (request) => {
// If the service is down it will render this content
return Promise.resolve(() => () => "I'm dead");
},
init: (arg) => {
return;
}
}
resolve(proxy)
}
// inject this script with the src set to the versioned remoteEntry.js
document.head.appendChild(script);
})
`
},
exposes: {},
shared: {
...deps,
react: {
singleton: true,
eager: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
eager: true,
requiredVersion: deps["react-dom"],
},
},
}),
I found a decision.
Checkout this article https://habr./ru/post/554682/ - the article is in Russian, but you can use a translator.
Pay attention to the hook - useDynamicScript and handlers onload and onerror
The point is to independently check whether it is available remoteEntry.js from remote host. If remoteEntry.js is not available, do not download the remote ponent, otherwise try to download. The probability that the ponent will load in this case is very high.
But if when loading remoteEntry.js an error will occur, we will process it, and the error will not be thrown to the console.