Skip to content

Commit 433fe07

Browse files
danpeenzhoushaw
andauthored
feat: add @module-federation/retry-plugin for resource retry when resource loading went wrong (#2899)
Co-authored-by: Zhou xiao <[email protected]>
1 parent df76031 commit 433fe07

File tree

36 files changed

+1397
-158
lines changed

36 files changed

+1397
-158
lines changed

.changeset/brave-wasps-flash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/retry-plugin': patch
3+
---
4+
5+
feat: add @module-federation/retry-plugin for resource retry when resource loading went wrong

.changeset/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"@module-federation/bridge-vue3",
2020
"@module-federation/bridge-shared",
2121
"@module-federation/bridge-react-webpack-plugin",
22-
"@module-federation/modern-js"
22+
"@module-federation/modern-js",
23+
"@module-federation/retry-plugin"
2324
]
2425
],
2526
"ignorePatterns": ["^alpha|^beta"],

apps/router-demo/router-host-2000/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"@ant-design/icons": "^5.3.6",
1212
"@module-federation/bridge-react": "workspace:*",
1313
"@module-federation/enhanced": "workspace:*",
14-
"react-router-dom": "^6.24.1"
14+
"react-router-dom": "^6.24.1",
15+
"@module-federation/retry-plugin": "workspace:*"
1516
},
1617
"devDependencies": {
1718
"@rsbuild/core": "^0.6.15",

apps/router-demo/router-host-2000/rsbuild.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export default defineConfig({
3131
shared: ['react', 'react-dom', 'antd'],
3232
runtimePlugins: [
3333
path.join(__dirname, './src/runtime-plugin/shared-strategy.ts'),
34+
// path.join(__dirname, './src/runtime-plugin/retry.ts'),
3435
],
3536
}),
3637
]);

apps/router-demo/router-host-2000/src/App.tsx

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
11
import { useRef, useEffect, ForwardRefExoticComponent } from 'react';
22
import { Route, Routes, useLocation } from 'react-router-dom';
3-
import {
4-
init,
5-
loadRemote,
6-
RetryPlugin,
7-
} from '@module-federation/enhanced/runtime';
3+
import { init, loadRemote } from '@module-federation/enhanced/runtime';
4+
import { RetryPlugin } from '@module-federation/retry-plugin';
85
import { createRemoteComponent } from '@module-federation/bridge-react';
96
import Navigation from './navigation';
107
import Detail from './pages/Detail';
118
import Home from './pages/Home';
129
import styles from './index.module.less';
1310
import './App.css';
1411

15-
// init to register the RetryPlugin
1612
init({
1713
name: 'federation_consumer',
1814
remotes: [],
1915
plugins: [
2016
RetryPlugin({
21-
// fallbackUrl is optional
22-
fallbackUrl: 'http://localhost:2001/mf-manifest.json',
17+
fetch: {
18+
url: 'http://localhost:2008/not-exist-mf-manifest.json',
19+
fallback: () => 'http://localhost:2001/mf-manifest.json',
20+
},
21+
script: {
22+
url: 'http://localhost:2001/static/js/async/src_App_tsx.js',
23+
customCreateScript: (url: string, attrs: Record<string, string>) => {
24+
let script = document.createElement('script');
25+
script.src = `http://localhost:2011/static/js/async/src_App_tsx.js`;
26+
script.setAttribute('loader-hoos', 'isTrue');
27+
script.setAttribute('crossorigin', 'anonymous');
28+
script.onload = (event) => {
29+
console.log('--------custom script onload--------', event);
30+
};
31+
script.onerror = (event) => {
32+
console.log('--------custom script onerror--------', event);
33+
};
34+
return script;
35+
},
36+
},
2337
}),
2438
],
2539
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { RetryPlugin } from '@module-federation/retry-plugin';
2+
3+
const retryPlugin = () =>
4+
RetryPlugin({
5+
fetch: {
6+
url: 'http://localhost:2008/not-exist-mf-manifest.json',
7+
fallback: () => 'http://localhost:2001/mf-manifest.json',
8+
},
9+
script: {
10+
url: 'http://localhost:2001/static/js/async/src_App_tsx.js',
11+
customCreateScript: (url: string, attrs: Record<string, string>) => {
12+
let script = document.createElement('script');
13+
script.src = `http://localhost:2011/static/js/async/src_App_tsx.js`;
14+
script.setAttribute('loader-hoos', 'isTrue');
15+
script.setAttribute('crossorigin', 'anonymous');
16+
return script;
17+
},
18+
},
19+
});
20+
export default retryPlugin;

apps/router-demo/router-remote1-2001/src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ import styles from './App.module.css';
1212
const dataSource = [
1313
{
1414
key: '1',
15-
name: '胡彦斌',
15+
name: 'Zack',
1616
age: 32,
1717
address: '西湖区湖底公园1号',
1818
},
1919
{
2020
key: '2',
21-
name: '胡彦祖',
21+
name: 'Jack',
2222
age: 42,
2323
address: '西湖区湖底公园1号',
2424
},
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
["index"]
1+
["index", "retry-plugin"]
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import { PackageManagerTabs, Tabs, Tab } from '@theme';
2+
3+
# RetryPlugin
4+
5+
## Introduction
6+
7+
Resource retry plugin is used to retry resources when they fail to load, thereby increasing the success rate of resource loading. In Module Federation, we provide the retry plugin `RetryPlugin` to increase the retry mechanism, which can improve the stability of the application.
8+
9+
## Installation
10+
11+
This `RetryPlugin` is Provided by the `@module-federation/retry-plugin` package
12+
13+
<PackageManagerTabs
14+
command={{
15+
npm: 'npm add @module-federation/retry-plugin --save',
16+
yarn: 'yarn add @module-federation/retry-plugin --save',
17+
pnpm: 'pnpm add @module-federation/retry-plugin --save',
18+
bun: 'bun add @module-federation/retry-plugin --save',
19+
}}
20+
/>
21+
22+
## Usage
23+
24+
`RetryPlugin` is a runtime plugin, we can register this plugin through the `runtimePlugin` of the build plugin or register it at runtime and configure retry parameters and retry logic, etc.:
25+
26+
27+
:::note
28+
Note: Choose either of the two ways to register the build plugin and do not register it repeatedly
29+
30+
:::
31+
32+
33+
### Method1: Register in the build plugin
34+
35+
```ts
36+
// ./src/runtime-plugin/retry.ts
37+
import { RetryPlugin } from '@module-federation/retry-plugin';
38+
const retryPlugin = () => RetryPlugin({
39+
fetch: {
40+
url: 'http://localhost:2008/not-exist-mf-manifest.json',
41+
fallback: () => 'http://localhost:2001/mf-manifest.json',
42+
},
43+
script: {
44+
// url: 'http://localhost:2008/not-exist-mf-manifest.json',
45+
url: 'http://localhost:2001/static/js/async/src_App_tsx.js',
46+
customCreateScript: (url: string, attrs: Record<string, string>) => {
47+
let script = document.createElement('script');
48+
script.src = `http://localhost:2011/static/js/async/src_App_tsx.js`;
49+
script.setAttribute('loader-hoos', 'isTrue');
50+
script.setAttribute('crossorigin', 'anonymous');
51+
return script;
52+
},
53+
}
54+
})
55+
export default retryPlugin;
56+
```
57+
58+
### Method2: Register it at runtime
59+
60+
```ts
61+
import {
62+
init,
63+
loadRemote,
64+
RetryPlugin,
65+
} from '@module-federation/retry-plugin';
66+
67+
init({
68+
name: 'federation_consumer',
69+
remotes: [],
70+
plugins: [
71+
RetryPlugin({
72+
fetch: {
73+
// the retry resource url
74+
url: 'http://localhost:2008/not-exist-mf-manifest.json',
75+
// after all retried failed, set a fallback function to guarantee a fallback resource
76+
fallback: () => 'http://localhost:2001/mf-manifest.json',
77+
},
78+
script: {
79+
// the retry resource url
80+
url: 'http://localhost:2001/static/js/async/src_App_tsx.js',
81+
// if you need to custom create script element, pass `customCreateScript` and plugin will use customCreateScript to create script element
82+
customCreateScript: (url: string, attrs: Record<string, string>) => {
83+
let script = document.createElement('script');
84+
script.src = `http://localhost:2011/static/js/async/src_App_tsx.js`;
85+
script.setAttribute('loader-hoos', 'isTrue');
86+
script.setAttribute('crossorigin', 'anonymous');
87+
return script;
88+
},
89+
},
90+
}),
91+
],
92+
});
93+
```
94+
95+
the resource that needs to be retried is divided into two types: the `fetch` type and the `script` type, and we control the retry logic of these two resource types through the `fetch` parameter and the `script` parameter, respectively.
96+
97+
## Type
98+
99+
```ts
100+
const RetryPlugin: (params: RetryPluginParams) => FederationRuntimePlugin;
101+
102+
type RetryPluginParams = {
103+
fetch?: FetchWithRetryOptions; // fetch retry options
104+
script?: ScriptWithRetryOptions; // script retry options
105+
};
106+
107+
type FetchWithRetryOptions = {
108+
url?: string;
109+
options?: RequestInit;
110+
retryTimes?: number;
111+
retryDelay?: number;
112+
fallback?: () => string;
113+
}
114+
115+
type ScriptWithRetryOptions = {
116+
url?: string;
117+
attrs?: Record<string, string>;
118+
retryTimes?: number;
119+
customCreateScript?: CreateScriptFunc;
120+
}
121+
122+
```
123+
124+
125+
## RetryPluginParams type description
126+
127+
`RetryPluginParams` is the parameter type used to configure `RetryPlugin`, which contains retry options for two types of resources: `fetch` and `script`.
128+
129+
### Properties
130+
131+
- **fetch**: `FetchWithRetryOptions` (optional)
132+
- Used to configure the retry options for fetch type resources.
133+
134+
- **script**: `ScriptWithRetryOptions` (optional)
135+
- Used to configure the retry options for script type resources.
136+
137+
138+
## FetchWithRetryOptions type description
139+
140+
`FetchWithRetryOptions` is the type used to configure the retry options for fetch type resources.
141+
142+
### 属性
143+
### Properties
144+
145+
- **url**:
146+
- `string`
147+
- Optional. When not set, all failed resources will default to retry logic.
148+
- The URL of the resource to be retried.
149+
150+
- **options**:
151+
- `RequestInit`
152+
- Optional.
153+
- The request options for the fetch request.
154+
155+
- **retryTimes**:
156+
- `number`
157+
- Optional.
158+
- The number of retry attempts. Defaults to 3.
159+
160+
- **retryDelay**:
161+
- `number`
162+
- Optional.
163+
- The delay between retry attempts in milliseconds. Defaults to 1000.
164+
165+
- **fallback**:
166+
- `() => string`
167+
- Optional. A function that returns a Promise that resolves to a Response object. This function is called when all retry attempts have failed.
168+
169+
170+
### ScriptWithRetryOptions Type Description
171+
172+
`ScriptWithRetryOptions` is the type used to configure the retry options for script type resources.
173+
174+
### Properties
175+
176+
- **url**:
177+
- `string`
178+
- Optional. When not set, all failed resources will default to retry logic.
179+
- The URL of the resource to be retried.
180+
181+
- **attrs**:
182+
- `Record<string, string>`
183+
- Optional
184+
- The attributes to be passed to the script element.
185+
186+
- **retryTimes**:
187+
- `number`
188+
- Optional
189+
- The number of retry attempts. Defaults to 3.
190+
191+
- **retryDelay**:
192+
- `number`
193+
- Optional
194+
- The delay between retry attempts in milliseconds. Defaults to 1000.
195+
196+
- **customCreateScript**:
197+
- `CreateScriptFunc`
198+
- Optional.
199+
- A custom function to create the script element.

apps/website-new/docs/zh/plugin/_meta.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,10 @@
33
"type": "dir",
44
"name": "dev",
55
"label": "插件开发"
6+
},
7+
{
8+
"type": "dir",
9+
"name": "plugins",
10+
"label": "插件"
611
}
712
]

0 commit comments

Comments
 (0)