Skip to content

Commit 47e4d36

Browse files
YanPesyannik.peschke
andauthored
docs: add doc for error-catalog in "basic" (#2849)
Co-authored-by: yannik.peschke <[email protected]>
1 parent 8378a77 commit 47e4d36

File tree

2 files changed

+138
-1
lines changed

2 files changed

+138
-1
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
["runtime", "rspack", "webpack", "chrome-devtool", "type-prompt"]
1+
["runtime", "rspack", "webpack", "chrome-devtool", "type-prompt", "error-catalog"]
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Error Catalog
2+
3+
This section is a collection of common issues related to the implementation of `Module Federation` in general.
4+
The main goal is to provide additional context and solution paths for beginners not familiar with the fundamental ways of how `Module Federation` is working at its core.
5+
6+
## Unable to use `module-name`'s URL with `module-name`_provider's globalName to get remoteEntry exports
7+
#### Error Message
8+
:::danger Browser Error Message
9+
Uncaught (in promise)
10+
Error: [ Federation Runtime ]:
11+
Unable to use `module-name`'s URL with `module-name`_provider's globalName to get remoteEntry exports.
12+
Possible reasons could be:
13+
14+
`origin`/modules/`module-name`/static/js/`module-name`_provider.js' is not the correct URL, or the remoteEntry resource is incorrect.
15+
16+
`module-name`_provider' cannot be used to get remoteEntry exports in the window object.
17+
:::
18+
19+
#### Solution
20+
1. Create a shared-strategy in all hosts and remotes
21+
22+
```ts title="shared-strategy.ts"
23+
``import type { FederationRuntimePlugin } from '@module-federation/enhanced/runtime';
24+
25+
const sharedStrategy: () => FederationRuntimePlugin = () => ({
26+
name: 'shared-strategy-plugin',
27+
beforeInit(args) {
28+
const { userOptions } = args;
29+
const shared = userOptions.shared;
30+
if (shared) {
31+
Object.keys(shared).forEach((sharedKey) => {
32+
const sharedConfigs = shared[sharedKey];
33+
const arraySharedConfigs = Array.isArray(sharedConfigs)
34+
? sharedConfigs
35+
: [sharedConfigs];
36+
arraySharedConfigs.forEach((s) => {
37+
s.strategy = 'loaded-first';
38+
});
39+
});
40+
}
41+
return args;
42+
},
43+
});
44+
export default sharedStrategy;
45+
```
46+
47+
2. Add the shared-strategy to your config
48+
```ts title="modern.config.js"
49+
{
50+
...
51+
new ModuleFederationPlugin({
52+
...,
53+
runtimePlugins: ['path/to/shared-strategy.ts'],
54+
})
55+
}
56+
```
57+
58+
3. Optional: If you are running `module-federation` in a Docker environment, make sure to adapt the following fields in your configs of all `hosts` and `remotes`:
59+
```ts title="modern.config.js"
60+
{
61+
rspack: (config, {appendPlugins}) => {
62+
...
63+
config.publicPath = "auto";
64+
config.output.uniqueName = "module-name";
65+
delete config.optimization?.splitChunks;
66+
},
67+
appendPlugins([
68+
new ModuleFederationPlugin({
69+
...,
70+
runtime: false,
71+
})
72+
])
73+
}
74+
```
75+
76+
## Resolve error: Cant't resolve `module-namespace`/`module-component` in `implementation-path`
77+
#### Error Message
78+
:::danger Browser Error Message
79+
Resolve error: Cant't resolve `module-namespace`/`module-component` in `implementation-path`
80+
81+
var Component = /*#__PURE__*/ lazy(function() {}
82+
return import("`module-namespace`/`module-component`)});
83+
:::
84+
85+
#### Solution
86+
When checking your browser network traffic you might see that no `mf-manifest.json` file is being loaded. This is because the `module-namespace` is not being resolved correctly.
87+
Make sure the path to the actual exposed `module_provider.js` file in your remote is resolving with status code 200.
88+
89+
90+
## Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
91+
#### Error Message
92+
:::danger Browser Error Message
93+
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
94+
95+
You might have mismatching versions of React and the renderer (such as React DOM)
96+
97+
You might be breaking the Rules of Hooks
98+
99+
You might have more than one copy of React in the same app
100+
:::
101+
102+
:::danger Browser Error Message
103+
Uncaught TypeError: Cannot read properties on null (reading `useState`)
104+
:::
105+
106+
#### Solution
107+
This error occurs when you work a lot with `shared-dependencies`. After loading modules it is not clear which version of each shared-dependency should be used. To resolve this, switch to the shared notation of the option field `shared`
108+
The object notation allows for more control of the shared-dependencies.
109+
110+
For us, the option `singleton` is mandatory to consolidate all versions of shared-dependencies to the lowest matching version.
111+
112+
In addition, the option `eager` encapsulates all shared-dependencies into a dedicated output entry. This can be helpful to solve possible race-condition artifacts in the runtime. The drawback which this option is a slightly increased network traffic because of the additional output entry.
113+
114+
```ts title="modern.config.js"
115+
{
116+
...
117+
new ModuleFederationPlugin({
118+
...,
119+
// Default basic configuration
120+
// shared: [
121+
// 'react',
122+
// 'react-dom',
123+
// 'my-custom-module'
124+
// ]
125+
126+
// Configuration with more specificity
127+
shared: {
128+
react: { singleton: true, eager: true },
129+
'react-dom': { singleton: true, eager: true },
130+
'my-custom-module': { singleton: true, eager: true },
131+
...
132+
},
133+
})
134+
])
135+
}
136+
```
137+

0 commit comments

Comments
 (0)