@rsbuild/plugin-assets-retry 1.2.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -23
- package/README.zh-CN.md +137 -23
- package/dist/index.cjs +59 -56
- package/dist/index.d.ts +100 -5
- package/dist/index.js +57 -57
- package/dist/runtime/asyncChunkRetry.js +189 -222
- package/dist/runtime/asyncChunkRetry.min.js +1 -1
- package/dist/runtime/initialChunkRetry.js +205 -267
- package/dist/runtime/initialChunkRetry.min.js +1 -1
- package/package.json +9 -8
- package/dist/AsyncChunkRetryPlugin.d.ts +0 -15
- package/dist/runtime/asyncChunkRetry.d.ts +0 -19
- package/dist/runtime/initialChunkRetry.d.ts +0 -5
- package/dist/types.d.ts +0 -72
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ bun add @rsbuild/plugin-assets-retry -D
|
|
|
37
37
|
You can register the plugin in the `rsbuild.config.ts` file:
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
|
-
import { pluginAssetsRetry } from
|
|
40
|
+
import { pluginAssetsRetry } from '@rsbuild/plugin-assets-retry';
|
|
41
41
|
|
|
42
42
|
export default {
|
|
43
43
|
plugins: [pluginAssetsRetry()],
|
|
@@ -59,33 +59,43 @@ type AssetsRetryHookContext = {
|
|
|
59
59
|
isAsyncChunk: boolean;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
type
|
|
62
|
+
type RuntimeRetryOptions = {
|
|
63
63
|
type?: string[];
|
|
64
64
|
domain?: string[];
|
|
65
65
|
max?: number;
|
|
66
|
-
test?: string | ((url: string) => boolean);
|
|
67
|
-
crossOrigin?: boolean |
|
|
68
|
-
inlineScript?: boolean;
|
|
66
|
+
test?: string | RegExp | ((url: string) => boolean);
|
|
67
|
+
crossOrigin?: boolean | 'anonymous' | 'use-credentials';
|
|
69
68
|
delay?: number | ((context: AssetsRetryHookContext) => number);
|
|
70
69
|
onRetry?: (context: AssetsRetryHookContext) => void;
|
|
71
70
|
onSuccess?: (context: AssetsRetryHookContext) => void;
|
|
72
71
|
onFail?: (context: AssetsRetryHookContext) => void;
|
|
73
72
|
};
|
|
73
|
+
|
|
74
|
+
type AssetsRetryOptions =
|
|
75
|
+
| ({
|
|
76
|
+
inlineScript?: boolean;
|
|
77
|
+
minify?: boolean;
|
|
78
|
+
} & RuntimeRetryOptions)
|
|
79
|
+
| {
|
|
80
|
+
inlineScript?: boolean;
|
|
81
|
+
minify?: boolean;
|
|
82
|
+
rules: RuntimeRetryOptions[];
|
|
83
|
+
};
|
|
74
84
|
```
|
|
75
85
|
|
|
76
86
|
- **Default:**
|
|
77
87
|
|
|
78
88
|
```ts
|
|
79
89
|
const defaultAssetsRetryOptions = {
|
|
80
|
-
type: ["script", "link", "img"],
|
|
81
|
-
domain: [],
|
|
82
90
|
max: 3,
|
|
83
|
-
|
|
91
|
+
type: ['script', 'link', 'img'],
|
|
92
|
+
domain: [],
|
|
84
93
|
crossOrigin: false,
|
|
94
|
+
test: '',
|
|
85
95
|
delay: 0,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
addQuery: false,
|
|
97
|
+
inlineScript: true,
|
|
98
|
+
minify: rsbuildConfig.mode === 'production',
|
|
89
99
|
};
|
|
90
100
|
```
|
|
91
101
|
|
|
@@ -103,11 +113,11 @@ For example:
|
|
|
103
113
|
defineConfig({
|
|
104
114
|
plugins: [
|
|
105
115
|
pluginAssetsRetry({
|
|
106
|
-
domain: [
|
|
107
|
-
})
|
|
116
|
+
domain: ['cdn1.com', 'cdn2.com', 'cdn3.com'],
|
|
117
|
+
}),
|
|
108
118
|
],
|
|
109
119
|
output: {
|
|
110
|
-
assetPrefix:
|
|
120
|
+
assetPrefix: 'https://cdn1.com', // or "//cdn1.com"
|
|
111
121
|
},
|
|
112
122
|
});
|
|
113
123
|
```
|
|
@@ -127,7 +137,7 @@ For example, only script tags and link tags are processed:
|
|
|
127
137
|
|
|
128
138
|
```js
|
|
129
139
|
pluginAssetsRetry({
|
|
130
|
-
type: [
|
|
140
|
+
type: ['script', 'link'],
|
|
131
141
|
});
|
|
132
142
|
```
|
|
133
143
|
|
|
@@ -182,7 +192,7 @@ The callback function when the asset is being retried. For example:
|
|
|
182
192
|
pluginAssetsRetry({
|
|
183
193
|
onRetry: ({ times, domain, url, tagName, isAsyncChunk }) => {
|
|
184
194
|
console.log(
|
|
185
|
-
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}
|
|
195
|
+
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
|
|
186
196
|
);
|
|
187
197
|
},
|
|
188
198
|
});
|
|
@@ -198,7 +208,7 @@ The callback function when the asset is successfully retried. For example:
|
|
|
198
208
|
pluginAssetsRetry({
|
|
199
209
|
onSuccess: ({ times, domain, url, tagName, isAsyncChunk }) => {
|
|
200
210
|
console.log(
|
|
201
|
-
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}
|
|
211
|
+
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
|
|
202
212
|
);
|
|
203
213
|
},
|
|
204
214
|
});
|
|
@@ -214,7 +224,7 @@ The callback function when the asset is failed to be retried. For example:
|
|
|
214
224
|
pluginAssetsRetry({
|
|
215
225
|
onFail: ({ times, domain, url, tagName, isAsyncChunk }) => {
|
|
216
226
|
console.log(
|
|
217
|
-
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}
|
|
227
|
+
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
|
|
218
228
|
);
|
|
219
229
|
},
|
|
220
230
|
});
|
|
@@ -242,7 +252,7 @@ When set to `true`, `retry=${times}` will be added to the query when requesting,
|
|
|
242
252
|
|
|
243
253
|
When you want to customize query, you can pass a function, for example:
|
|
244
254
|
|
|
245
|
-
- **Example:** All assets requested do not contain query:
|
|
255
|
+
- **Example 1:** All assets requested do not contain query:
|
|
246
256
|
|
|
247
257
|
```js
|
|
248
258
|
pluginAssetsRetry({
|
|
@@ -254,7 +264,7 @@ pluginAssetsRetry({
|
|
|
254
264
|
});
|
|
255
265
|
```
|
|
256
266
|
|
|
257
|
-
- **Example:** If there is a query in some of the requested assets, you can read it with `originalQuery`:
|
|
267
|
+
- **Example 2:** If there is a query in some of the requested assets, you can read it with `originalQuery`:
|
|
258
268
|
|
|
259
269
|
```js
|
|
260
270
|
pluginAssetsRetry({
|
|
@@ -321,7 +331,81 @@ Or pass a function that receives `AssetsRetryHookContext` and returns the delay
|
|
|
321
331
|
```js
|
|
322
332
|
// Calculate delay based on retry attempts
|
|
323
333
|
pluginAssetsRetry({
|
|
324
|
-
delay:
|
|
334
|
+
delay: ctx => (ctx.times + 1) * 1000,
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### rules
|
|
339
|
+
|
|
340
|
+
- **Type:** `RuntimeRetryOptions[]`
|
|
341
|
+
- **Default:** `undefined`
|
|
342
|
+
|
|
343
|
+
Configure multiple retry rules with different options. Each rule will be evaluated in order, and the first matching rule will be used for retry logic. This is useful when you have different retry requirements for different types of assets or domains.
|
|
344
|
+
|
|
345
|
+
When using `rules`, the plugin will:
|
|
346
|
+
|
|
347
|
+
1. Check each rule in order by `test` `domain` `type`
|
|
348
|
+
|
|
349
|
+
2. If the rule is matched, the rule's configuration will be used to retry
|
|
350
|
+
|
|
351
|
+
3. If no rule is matched, the resource will not be retried
|
|
352
|
+
|
|
353
|
+
Each rule supports all the same options as the top-level configuration, including `type`, `domain`, `max`, `test`, `crossOrigin`, `delay`, `onRetry`, `onSuccess`, and `onFail`.
|
|
354
|
+
|
|
355
|
+
- **Example 1:** Different retry strategies for different CDNs:
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
pluginAssetsRetry({
|
|
359
|
+
rules: [
|
|
360
|
+
{
|
|
361
|
+
// Rule for primary CDN
|
|
362
|
+
test: /cdn1\.example\.com/,
|
|
363
|
+
domain: ['cdn1.example.com', 'cdn1-backup.example.com'],
|
|
364
|
+
max: 3,
|
|
365
|
+
delay: 1000,
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
// Rule for secondary CDN with more retries
|
|
369
|
+
test: /cdn2\.example\.com/,
|
|
370
|
+
domain: ['cdn2.example.com', 'cdn2-backup.example.com'],
|
|
371
|
+
max: 5,
|
|
372
|
+
delay: 500,
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
// Default rule for other assets
|
|
376
|
+
domain: ['default.example.com', 'default-backup.example.com'],
|
|
377
|
+
max: 2,
|
|
378
|
+
},
|
|
379
|
+
],
|
|
380
|
+
});
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
- **Example 2:** Different retry strategies for different asset types:
|
|
384
|
+
|
|
385
|
+
```js
|
|
386
|
+
pluginAssetsRetry({
|
|
387
|
+
rules: [
|
|
388
|
+
{
|
|
389
|
+
// Critical JavaScript files get more retries
|
|
390
|
+
type: ['script'],
|
|
391
|
+
// Or test: /\.js$/,
|
|
392
|
+
max: 5,
|
|
393
|
+
delay: 1000,
|
|
394
|
+
onFail: ({ url }) => console.error(`Critical JS failed: ${url}`),
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
// CSS files get fewer retries
|
|
398
|
+
test: /\.css$/,
|
|
399
|
+
max: 2,
|
|
400
|
+
delay: 500,
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
// Images get minimal retries
|
|
404
|
+
test: /\.(png|jpg|gif|svg)$/,
|
|
405
|
+
max: 1,
|
|
406
|
+
delay: 0,
|
|
407
|
+
},
|
|
408
|
+
],
|
|
325
409
|
});
|
|
326
410
|
```
|
|
327
411
|
|
|
@@ -336,12 +420,12 @@ When you use Assets Retry plugin, the Rsbuild injects some runtime code into the
|
|
|
336
420
|
Here's an example of incorrect usage:
|
|
337
421
|
|
|
338
422
|
```js
|
|
339
|
-
import { someMethod } from
|
|
423
|
+
import { someMethod } from 'utils';
|
|
340
424
|
|
|
341
425
|
pluginAssetsRetry({
|
|
342
426
|
onRetry() {
|
|
343
427
|
// Incorrect usage, includes sensitive information
|
|
344
|
-
const privateToken =
|
|
428
|
+
const privateToken = 'a-private-token';
|
|
345
429
|
|
|
346
430
|
// Incorrect usage, uses an external method
|
|
347
431
|
someMethod(privateToken);
|
|
@@ -353,6 +437,10 @@ pluginAssetsRetry({
|
|
|
353
437
|
|
|
354
438
|
Assets Retry plugin may not work in the following scenarios:
|
|
355
439
|
|
|
440
|
+
### Sync script tag loaded resources
|
|
441
|
+
|
|
442
|
+
`<script src="..."></script>` tags load resources synchronously, and retrying them does not guarantee the order of resource loading. Therefore, the Assets Retry plugin will not retry resources loaded by synchronous script tags. It will only retry resources loaded by async/defer script tags.
|
|
443
|
+
|
|
356
444
|
### Module Federation
|
|
357
445
|
|
|
358
446
|
For remote modules loaded by Module Federation, you can use the [@module-federation/retry-plugin](https://www.npmjs.com/package/@module-federation/retry-plugin) from Module Federation 2.0 to implement static asset retries.
|
|
@@ -385,6 +473,32 @@ If you want Assets Retry plugin to work on resources in custom templates, you ca
|
|
|
385
473
|
</html>
|
|
386
474
|
```
|
|
387
475
|
|
|
476
|
+
#### Identifying retry scripts in HTML templates
|
|
477
|
+
|
|
478
|
+
The Assets Retry plugin adds a unique `data-rsbuild-assets-retry` attribute to retry scripts, allowing you to easily identify them in custom HTML templates.
|
|
479
|
+
|
|
480
|
+
You can import the attribute constant:
|
|
481
|
+
|
|
482
|
+
```js
|
|
483
|
+
import { ASSETS_RETRY_DATA_ATTRIBUTE } from '@rsbuild/plugin-assets-retry';
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
The attribute values are:
|
|
487
|
+
- `"inline"` for inline scripts (when `inlineScript: true`)
|
|
488
|
+
- `"external"` for external scripts (when `inlineScript: false`)
|
|
489
|
+
|
|
490
|
+
Example usage in HTML templates:
|
|
491
|
+
|
|
492
|
+
```html
|
|
493
|
+
<!-- Filter retry scripts -->
|
|
494
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag => tag.attributes['data-rsbuild-assets-retry'] === 'inline') %>
|
|
495
|
+
|
|
496
|
+
<!-- Filter non-retry scripts -->
|
|
497
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag => !tag.attributes['data-rsbuild-assets-retry']) %>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
This allows you to place retry scripts at the top of your HTML head for optimal loading order.
|
|
501
|
+
|
|
388
502
|
## License
|
|
389
503
|
|
|
390
504
|
[MIT](./LICENSE).
|
package/README.zh-CN.md
CHANGED
|
@@ -35,7 +35,7 @@ bun add @rsbuild/plugin-assets-retry -D
|
|
|
35
35
|
你可以在 `rsbuild.config.ts` 文件中注册插件:
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
|
-
import { pluginAssetsRetry } from
|
|
38
|
+
import { pluginAssetsRetry } from '@rsbuild/plugin-assets-retry';
|
|
39
39
|
|
|
40
40
|
export default {
|
|
41
41
|
plugins: [pluginAssetsRetry()],
|
|
@@ -57,33 +57,43 @@ type AssetsRetryHookContext = {
|
|
|
57
57
|
isAsyncChunk: boolean;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
type
|
|
60
|
+
type RuntimeRetryOptions = {
|
|
61
61
|
type?: string[];
|
|
62
62
|
domain?: string[];
|
|
63
63
|
max?: number;
|
|
64
64
|
test?: string | ((url: string) => boolean);
|
|
65
|
-
crossOrigin?: boolean |
|
|
66
|
-
inlineScript?: boolean;
|
|
65
|
+
crossOrigin?: boolean | 'anonymous' | 'use-credentials';
|
|
67
66
|
delay?: number | ((context: AssetsRetryHookContext) => number);
|
|
68
67
|
onRetry?: (context: AssetsRetryHookContext) => void;
|
|
69
68
|
onSuccess?: (context: AssetsRetryHookContext) => void;
|
|
70
69
|
onFail?: (context: AssetsRetryHookContext) => void;
|
|
71
70
|
};
|
|
71
|
+
|
|
72
|
+
type AssetsRetryOptions =
|
|
73
|
+
| ({
|
|
74
|
+
inlineScript?: boolean;
|
|
75
|
+
minify?: boolean;
|
|
76
|
+
} & RuntimeRetryOptions)
|
|
77
|
+
| {
|
|
78
|
+
inlineScript?: boolean;
|
|
79
|
+
minify?: boolean;
|
|
80
|
+
rules: RuntimeRetryOptions[];
|
|
81
|
+
};
|
|
72
82
|
```
|
|
73
83
|
|
|
74
84
|
- **默认值:**
|
|
75
85
|
|
|
76
86
|
```ts
|
|
77
|
-
const
|
|
78
|
-
type: ["script", "link", "img"],
|
|
79
|
-
domain: [],
|
|
87
|
+
const defaultAssetsRetryOptions = {
|
|
80
88
|
max: 3,
|
|
81
|
-
|
|
89
|
+
type: ['script', 'link', 'img'],
|
|
90
|
+
domain: [],
|
|
82
91
|
crossOrigin: false,
|
|
92
|
+
test: '',
|
|
83
93
|
delay: 0,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
94
|
+
addQuery: false,
|
|
95
|
+
inlineScript: true,
|
|
96
|
+
minify: rsbuildConfig.mode === 'production',
|
|
87
97
|
};
|
|
88
98
|
```
|
|
89
99
|
|
|
@@ -101,11 +111,11 @@ const defaultOptions = {
|
|
|
101
111
|
defineConfig({
|
|
102
112
|
plugins: [
|
|
103
113
|
pluginAssetsRetry({
|
|
104
|
-
domain: [
|
|
105
|
-
})
|
|
114
|
+
domain: ['cdn1.com', 'cdn2.com', 'cdn3.com'],
|
|
115
|
+
}),
|
|
106
116
|
],
|
|
107
117
|
output: {
|
|
108
|
-
assetPrefix:
|
|
118
|
+
assetPrefix: 'https://cdn1.com', // 或者 "//cdn1.com"
|
|
109
119
|
},
|
|
110
120
|
});
|
|
111
121
|
```
|
|
@@ -125,7 +135,7 @@ defineConfig({
|
|
|
125
135
|
|
|
126
136
|
```js
|
|
127
137
|
pluginAssetsRetry({
|
|
128
|
-
type: [
|
|
138
|
+
type: ['script', 'link'],
|
|
129
139
|
});
|
|
130
140
|
```
|
|
131
141
|
|
|
@@ -180,7 +190,7 @@ pluginAssetsRetry({
|
|
|
180
190
|
pluginAssetsRetry({
|
|
181
191
|
onRetry: ({ times, domain, url, tagName, isAsyncChunk }) => {
|
|
182
192
|
console.log(
|
|
183
|
-
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}
|
|
193
|
+
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
|
|
184
194
|
);
|
|
185
195
|
},
|
|
186
196
|
});
|
|
@@ -196,7 +206,7 @@ pluginAssetsRetry({
|
|
|
196
206
|
pluginAssetsRetry({
|
|
197
207
|
onSuccess: ({ times, domain, url, tagName, isAsyncChunk }) => {
|
|
198
208
|
console.log(
|
|
199
|
-
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}
|
|
209
|
+
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
|
|
200
210
|
);
|
|
201
211
|
},
|
|
202
212
|
});
|
|
@@ -212,7 +222,7 @@ pluginAssetsRetry({
|
|
|
212
222
|
pluginAssetsRetry({
|
|
213
223
|
onFail: ({ times, domain, url, tagName, isAsyncChunk }) => {
|
|
214
224
|
console.log(
|
|
215
|
-
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}
|
|
225
|
+
`Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
|
|
216
226
|
);
|
|
217
227
|
},
|
|
218
228
|
});
|
|
@@ -240,7 +250,7 @@ type AddQuery =
|
|
|
240
250
|
|
|
241
251
|
当你想要自定义 query 时,可以传入一个函数,比如:
|
|
242
252
|
|
|
243
|
-
-
|
|
253
|
+
- **示例 1:** 请求的所有资源都不含 query:
|
|
244
254
|
|
|
245
255
|
```js
|
|
246
256
|
pluginAssetsRetry({
|
|
@@ -252,7 +262,7 @@ pluginAssetsRetry({
|
|
|
252
262
|
});
|
|
253
263
|
```
|
|
254
264
|
|
|
255
|
-
-
|
|
265
|
+
- **示例 2:** 当请求的某些资源中含有 query 时,可以使用 `originalQuery` 读取:
|
|
256
266
|
|
|
257
267
|
```js
|
|
258
268
|
pluginAssetsRetry({
|
|
@@ -319,7 +329,81 @@ pluginAssetsRetry({
|
|
|
319
329
|
```js
|
|
320
330
|
// 通过次数来计算延迟时间
|
|
321
331
|
pluginAssetsRetry({
|
|
322
|
-
delay:
|
|
332
|
+
delay: ctx => (ctx.times + 1) * 1000,
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### rules
|
|
337
|
+
|
|
338
|
+
- **类型:** `RuntimeRetryOptions[]`
|
|
339
|
+
- **默认值:** `undefined`
|
|
340
|
+
|
|
341
|
+
配置多个重试规则,每个规则可以有不同的选项。规则会按顺序进行评估,第一个匹配的规则将用于重试逻辑。这在你对不同类型的资源或域名有不同的重试需求时非常有用。
|
|
342
|
+
|
|
343
|
+
使用 `rules` 时,插件会:
|
|
344
|
+
|
|
345
|
+
1. 按顺序通过 `test` `domain` `type` 检查每个规则
|
|
346
|
+
|
|
347
|
+
2. 如果匹配到规则,会使用规则的配置进行重试
|
|
348
|
+
|
|
349
|
+
3. 如果没有匹配到规则,则不会重试该资源
|
|
350
|
+
|
|
351
|
+
每个规则支持与顶层配置相同的所有选项,包括 `type`、`domain`、`test`、`max`、`crossOrigin`、`delay`、`onRetry`、`onSuccess` 和 `onFail`。
|
|
352
|
+
|
|
353
|
+
- **示例 1:** 不同 CDN 的不同重试策略:
|
|
354
|
+
|
|
355
|
+
```js
|
|
356
|
+
pluginAssetsRetry({
|
|
357
|
+
rules: [
|
|
358
|
+
{
|
|
359
|
+
// 主 CDN 的规则
|
|
360
|
+
test: /cdn1\.example\.com/,
|
|
361
|
+
domain: ['cdn1.example.com', 'cdn1-backup.example.com'],
|
|
362
|
+
max: 3,
|
|
363
|
+
delay: 1000,
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
// 次要 CDN 的规则,更多重试次数
|
|
367
|
+
test: /cdn2\.example\.com/,
|
|
368
|
+
domain: ['cdn2.example.com', 'cdn2-backup.example.com'],
|
|
369
|
+
max: 5,
|
|
370
|
+
delay: 500,
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
// 其他资源的默认规则
|
|
374
|
+
domain: ['default.example.com', 'default-backup.example.com'],
|
|
375
|
+
max: 2,
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
- **示例 2:** 不同资源类型的不同重试策略:
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
pluginAssetsRetry({
|
|
385
|
+
rules: [
|
|
386
|
+
{
|
|
387
|
+
// 关键 JavaScript 文件获得更多重试次数
|
|
388
|
+
test: /\.js$/,
|
|
389
|
+
// 或者 type: ['script'],
|
|
390
|
+
max: 5,
|
|
391
|
+
delay: 1000,
|
|
392
|
+
onFail: ({ url }) => console.error(`关键 JS 失败: ${url}`),
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
// CSS 文件获得较少的重试次数
|
|
396
|
+
test: /\.css$/,
|
|
397
|
+
max: 2,
|
|
398
|
+
delay: 500,
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
// 图片获得最少的重试次数
|
|
402
|
+
test: /\.(png|jpg|gif|svg)$/,
|
|
403
|
+
max: 1,
|
|
404
|
+
delay: 0,
|
|
405
|
+
},
|
|
406
|
+
],
|
|
323
407
|
});
|
|
324
408
|
```
|
|
325
409
|
|
|
@@ -334,12 +418,12 @@ pluginAssetsRetry({
|
|
|
334
418
|
以下是一个错误示例:
|
|
335
419
|
|
|
336
420
|
```js
|
|
337
|
-
import { someMethod } from
|
|
421
|
+
import { someMethod } from 'utils';
|
|
338
422
|
|
|
339
423
|
pluginAssetsRetry({
|
|
340
424
|
onRetry() {
|
|
341
425
|
// 错误用法,包含了敏感信息
|
|
342
|
-
const privateToken =
|
|
426
|
+
const privateToken = 'a-private-token';
|
|
343
427
|
|
|
344
428
|
// 错误用法,使用了外部的方法
|
|
345
429
|
someMethod(privateToken);
|
|
@@ -351,6 +435,10 @@ pluginAssetsRetry({
|
|
|
351
435
|
|
|
352
436
|
以下场景 Assets Retry 插件可能无法生效:
|
|
353
437
|
|
|
438
|
+
### 同步 script 标签加载的资源
|
|
439
|
+
|
|
440
|
+
`<script src="..."></script>` 标签加载的资源是同步加载的,如果进行重试无法保证资源加载的顺序,因此 Assets Retry 插件不会对同步加载的 script 标签进行重试。只会对 async/defer 的 script 标签进行重试。
|
|
441
|
+
|
|
354
442
|
### 模块联邦
|
|
355
443
|
|
|
356
444
|
对于模块联邦加载的远程模块,你可以使用模块联邦 2.0 的 [@module-federation/retry-plugin](https://www.npmjs.com/package/@module-federation/retry-plugin) 来实现静态资源重试。
|
|
@@ -383,6 +471,32 @@ Assets Retry 插件通过监听页面 error 事件来获悉当前资源是否加
|
|
|
383
471
|
</html>
|
|
384
472
|
```
|
|
385
473
|
|
|
474
|
+
#### 在 HTML 模板中识别重试脚本
|
|
475
|
+
|
|
476
|
+
Assets Retry 插件为重试脚本添加了唯一的 `data-rsbuild-assets-retry` 属性,使您可以在自定义 HTML 模板中轻松识别它们。
|
|
477
|
+
|
|
478
|
+
您可以导入属性常量:
|
|
479
|
+
|
|
480
|
+
```js
|
|
481
|
+
import { ASSETS_RETRY_DATA_ATTRIBUTE } from '@rsbuild/plugin-assets-retry';
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
属性值包括:
|
|
485
|
+
- `"inline"` 用于内联脚本(当 `inlineScript: true` 时)
|
|
486
|
+
- `"external"` 用于外部脚本(当 `inlineScript: false` 时)
|
|
487
|
+
|
|
488
|
+
在 HTML 模板中的使用示例:
|
|
489
|
+
|
|
490
|
+
```html
|
|
491
|
+
<!-- 筛选重试脚本 -->
|
|
492
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag => tag.attributes['data-rsbuild-assets-retry'] === 'inline') %>
|
|
493
|
+
|
|
494
|
+
<!-- 筛选非重试脚本 -->
|
|
495
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag => !tag.attributes['data-rsbuild-assets-retry']) %>
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
这允许您将重试脚本放置在 HTML 头部的顶部以获得最佳的加载顺序。
|
|
499
|
+
|
|
386
500
|
## License
|
|
387
501
|
|
|
388
502
|
[MIT](./LICENSE).
|