@rsbuild/plugin-assets-retry 1.5.1 → 2.0.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 +5 -3
- package/README.zh-CN.md +8 -6
- package/dist/index.js +77 -73
- package/dist/runtime/asyncChunkRetry.js +84 -97
- package/dist/runtime/asyncChunkRetry.min.js +1 -1
- package/dist/runtime/initialChunkRetry.js +83 -94
- package/dist/runtime/initialChunkRetry.min.js +1 -1
- package/package.json +29 -29
- package/dist/index.cjs +0 -381
package/README.md
CHANGED
|
@@ -330,7 +330,7 @@ Or pass a function that receives `AssetsRetryHookContext` and returns the delay
|
|
|
330
330
|
```js
|
|
331
331
|
// Calculate delay based on retry attempts
|
|
332
332
|
pluginAssetsRetry({
|
|
333
|
-
delay: ctx => (ctx.times + 1) * 1000,
|
|
333
|
+
delay: (ctx) => (ctx.times + 1) * 1000,
|
|
334
334
|
});
|
|
335
335
|
```
|
|
336
336
|
|
|
@@ -491,10 +491,12 @@ Example usage in HTML templates:
|
|
|
491
491
|
|
|
492
492
|
```html
|
|
493
493
|
<!-- Filter retry scripts -->
|
|
494
|
-
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
494
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
495
|
+
tag.attributes['data-rsbuild-assets-retry'] === 'inline') %>
|
|
495
496
|
|
|
496
497
|
<!-- Filter non-retry scripts -->
|
|
497
|
-
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
498
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
499
|
+
!tag.attributes['data-rsbuild-assets-retry']) %>
|
|
498
500
|
```
|
|
499
501
|
|
|
500
502
|
This allows you to place retry scripts at the top of your HTML head for optimal loading order.
|
package/README.zh-CN.md
CHANGED
|
@@ -328,7 +328,7 @@ pluginAssetsRetry({
|
|
|
328
328
|
```js
|
|
329
329
|
// 通过次数来计算延迟时间
|
|
330
330
|
pluginAssetsRetry({
|
|
331
|
-
delay: ctx => (ctx.times + 1) * 1000,
|
|
331
|
+
delay: (ctx) => (ctx.times + 1) * 1000,
|
|
332
332
|
});
|
|
333
333
|
```
|
|
334
334
|
|
|
@@ -472,9 +472,9 @@ Assets Retry 插件通过监听页面 error 事件来获悉当前资源是否加
|
|
|
472
472
|
|
|
473
473
|
#### 在 HTML 模板中识别重试脚本
|
|
474
474
|
|
|
475
|
-
Assets Retry 插件为重试脚本添加了唯一的 `data-rsbuild-assets-retry`
|
|
475
|
+
Assets Retry 插件为重试脚本添加了唯一的 `data-rsbuild-assets-retry` 属性,使你可以在自定义 HTML 模板中轻松识别它们。
|
|
476
476
|
|
|
477
|
-
|
|
477
|
+
你可以导入属性常量:
|
|
478
478
|
|
|
479
479
|
```js
|
|
480
480
|
import { ASSETS_RETRY_DATA_ATTRIBUTE } from '@rsbuild/plugin-assets-retry';
|
|
@@ -489,13 +489,15 @@ import { ASSETS_RETRY_DATA_ATTRIBUTE } from '@rsbuild/plugin-assets-retry';
|
|
|
489
489
|
|
|
490
490
|
```html
|
|
491
491
|
<!-- 筛选重试脚本 -->
|
|
492
|
-
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
492
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
493
|
+
tag.attributes['data-rsbuild-assets-retry'] === 'inline') %>
|
|
493
494
|
|
|
494
495
|
<!-- 筛选非重试脚本 -->
|
|
495
|
-
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
496
|
+
<%= htmlWebpackPlugin.tags.headTags.filter(tag =>
|
|
497
|
+
!tag.attributes['data-rsbuild-assets-retry']) %>
|
|
496
498
|
```
|
|
497
499
|
|
|
498
|
-
|
|
500
|
+
这允许你将重试脚本放置在 HTML 头部的顶部以获得最佳的加载顺序。
|
|
499
501
|
|
|
500
502
|
## License
|
|
501
503
|
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,46 @@
|
|
|
1
|
-
import * as __rspack_external_crypto from "crypto";
|
|
2
1
|
import node_fs from "node:fs";
|
|
3
2
|
import node_path from "node:path";
|
|
4
3
|
import { fileURLToPath } from "node:url";
|
|
5
4
|
import { ensureAssetPrefix, logger, rspack } from "@rsbuild/core";
|
|
6
|
-
var __webpack_modules__ = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
var __webpack_modules__ = {};
|
|
6
|
+
var __webpack_module_cache__ = {};
|
|
7
|
+
function __webpack_require__(moduleId) {
|
|
8
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
9
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
10
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
11
|
+
exports: {}
|
|
12
|
+
};
|
|
13
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
14
|
+
return module.exports;
|
|
15
|
+
}
|
|
16
|
+
__webpack_require__.m = __webpack_modules__;
|
|
17
|
+
(()=>{
|
|
18
|
+
__webpack_require__.n = (module)=>{
|
|
19
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
20
|
+
__webpack_require__.d(getter, {
|
|
21
|
+
a: getter
|
|
22
|
+
});
|
|
23
|
+
return getter;
|
|
24
|
+
};
|
|
25
|
+
})();
|
|
26
|
+
(()=>{
|
|
27
|
+
__webpack_require__.d = (exports, definition)=>{
|
|
28
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: definition[key]
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
})();
|
|
34
|
+
(()=>{
|
|
35
|
+
__webpack_require__.add = function(modules) {
|
|
36
|
+
Object.assign(__webpack_require__.m, modules);
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
(()=>{
|
|
40
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
41
|
+
})();
|
|
42
|
+
__webpack_require__.add({
|
|
43
|
+
"./node_modules/.pnpm/serialize-javascript@7.0.5/node_modules/serialize-javascript/index.js" (module) {
|
|
12
44
|
var UID_LENGTH = 16;
|
|
13
45
|
var UID = generateUID();
|
|
14
46
|
var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L)-' + UID + '-(\\d+)__@"', 'g');
|
|
@@ -16,6 +48,7 @@ var __webpack_modules__ = {
|
|
|
16
48
|
var IS_PURE_FUNCTION = /function.*?\(/;
|
|
17
49
|
var IS_ARROW_FUNCTION = /.*?=>.*?/;
|
|
18
50
|
var UNSAFE_CHARS_REGEXP = /[<>\/\u2028\u2029]/g;
|
|
51
|
+
var SCRIPT_CLOSE_REGEXP = /<\/script[^>]*>/gi;
|
|
19
52
|
var RESERVED_SYMBOLS = [
|
|
20
53
|
'*',
|
|
21
54
|
'async'
|
|
@@ -30,8 +63,16 @@ var __webpack_modules__ = {
|
|
|
30
63
|
function escapeUnsafeChars(unsafeChar) {
|
|
31
64
|
return ESCAPED_CHARS[unsafeChar];
|
|
32
65
|
}
|
|
66
|
+
function escapeFunctionBody(str) {
|
|
67
|
+
str = str.replace(SCRIPT_CLOSE_REGEXP, function(match) {
|
|
68
|
+
return match.replace(/</g, '\\u003C').replace(/\//g, '\\u002F').replace(/>/g, '\\u003E');
|
|
69
|
+
});
|
|
70
|
+
str = str.replace(/\u2028/g, '\\u2028');
|
|
71
|
+
str = str.replace(/\u2029/g, '\\u2029');
|
|
72
|
+
return str;
|
|
73
|
+
}
|
|
33
74
|
function generateUID() {
|
|
34
|
-
var bytes =
|
|
75
|
+
var bytes = crypto.getRandomValues(new Uint8Array(UID_LENGTH));
|
|
35
76
|
var result = '';
|
|
36
77
|
for(var i = 0; i < UID_LENGTH; ++i)result += bytes[i].toString(16);
|
|
37
78
|
return result;
|
|
@@ -66,10 +107,8 @@ var __webpack_modules__ = {
|
|
|
66
107
|
if (origValue instanceof Date) return '@__D-' + UID + '-' + (dates.push(origValue) - 1) + '__@';
|
|
67
108
|
if (origValue instanceof Map) return '@__M-' + UID + '-' + (maps.push(origValue) - 1) + '__@';
|
|
68
109
|
if (origValue instanceof Set) return '@__S-' + UID + '-' + (sets.push(origValue) - 1) + '__@';
|
|
69
|
-
if (origValue
|
|
70
|
-
var isSparse =
|
|
71
|
-
return true;
|
|
72
|
-
}).length !== origValue.length;
|
|
110
|
+
if (Array.isArray(origValue)) {
|
|
111
|
+
var isSparse = Object.keys(origValue).length !== origValue.length;
|
|
73
112
|
if (isSparse) return '@__A-' + UID + '-' + (arrays.push(origValue) - 1) + '__@';
|
|
74
113
|
}
|
|
75
114
|
if (origValue instanceof URL) return '@__L-' + UID + '-' + (urls.push(origValue) - 1) + '__@';
|
|
@@ -80,9 +119,10 @@ var __webpack_modules__ = {
|
|
|
80
119
|
if ('bigint' === type) return '@__B-' + UID + '-' + (bigInts.push(origValue) - 1) + '__@';
|
|
81
120
|
return value;
|
|
82
121
|
}
|
|
83
|
-
function serializeFunc(fn) {
|
|
122
|
+
function serializeFunc(fn, options) {
|
|
84
123
|
var serializedFn = fn.toString();
|
|
85
124
|
if (IS_NATIVE_CODE_REGEXP.test(serializedFn)) throw new TypeError('Serializing native function: ' + fn.name);
|
|
125
|
+
if (options && true !== options.unsafe) serializedFn = escapeFunctionBody(serializedFn);
|
|
86
126
|
if (IS_PURE_FUNCTION.test(serializedFn)) return serializedFn;
|
|
87
127
|
if (IS_ARROW_FUNCTION.test(serializedFn)) return serializedFn;
|
|
88
128
|
var argsStartsAt = serializedFn.indexOf('(');
|
|
@@ -104,8 +144,15 @@ var __webpack_modules__ = {
|
|
|
104
144
|
if (0 === functions.length && 0 === regexps.length && 0 === dates.length && 0 === maps.length && 0 === sets.length && 0 === arrays.length && 0 === undefs.length && 0 === infinities.length && 0 === bigInts.length && 0 === urls.length) return str;
|
|
105
145
|
return str.replace(PLACE_HOLDER_REGEXP, function(match, backSlash, type, valueIndex) {
|
|
106
146
|
if (backSlash) return match;
|
|
107
|
-
if ('D' === type)
|
|
108
|
-
|
|
147
|
+
if ('D' === type) {
|
|
148
|
+
var isoStr = String(dates[valueIndex].toISOString());
|
|
149
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(isoStr)) throw new TypeError('Invalid Date ISO string');
|
|
150
|
+
return "new Date(\"" + isoStr + "\")";
|
|
151
|
+
}
|
|
152
|
+
if ('R' === type) {
|
|
153
|
+
var flags = String(regexps[valueIndex].flags).replace(/[^gimsuydv]/g, '');
|
|
154
|
+
return "new RegExp(" + serialize(regexps[valueIndex].source) + ", \"" + flags + "\")";
|
|
155
|
+
}
|
|
109
156
|
if ('M' === type) return "new Map(" + serialize(Array.from(maps[valueIndex].entries()), options) + ")";
|
|
110
157
|
if ('S' === type) return "new Set(" + serialize(Array.from(sets[valueIndex].values()), options) + ")";
|
|
111
158
|
if ('A' === type) return "Array.prototype.slice.call(" + serialize(Object.assign({
|
|
@@ -116,56 +163,13 @@ var __webpack_modules__ = {
|
|
|
116
163
|
if ('B' === type) return "BigInt(\"" + bigInts[valueIndex] + "\")";
|
|
117
164
|
if ('L' === type) return "new URL(" + serialize(urls[valueIndex].toString(), options) + ")";
|
|
118
165
|
var fn = functions[valueIndex];
|
|
119
|
-
return serializeFunc(fn);
|
|
166
|
+
return serializeFunc(fn, options);
|
|
120
167
|
});
|
|
121
168
|
};
|
|
122
|
-
},
|
|
123
|
-
crypto: function(module) {
|
|
124
|
-
module.exports = __rspack_external_crypto;
|
|
125
169
|
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
function __webpack_require__(moduleId) {
|
|
129
|
-
var cachedModule = __webpack_module_cache__[moduleId];
|
|
130
|
-
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
131
|
-
var module = __webpack_module_cache__[moduleId] = {
|
|
132
|
-
exports: {}
|
|
133
|
-
};
|
|
134
|
-
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
135
|
-
return module.exports;
|
|
136
|
-
}
|
|
137
|
-
(()=>{
|
|
138
|
-
__webpack_require__.n = (module)=>{
|
|
139
|
-
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
140
|
-
__webpack_require__.d(getter, {
|
|
141
|
-
a: getter
|
|
142
|
-
});
|
|
143
|
-
return getter;
|
|
144
|
-
};
|
|
145
|
-
})();
|
|
146
|
-
(()=>{
|
|
147
|
-
__webpack_require__.d = (exports, definition)=>{
|
|
148
|
-
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
149
|
-
enumerable: true,
|
|
150
|
-
get: definition[key]
|
|
151
|
-
});
|
|
152
|
-
};
|
|
153
|
-
})();
|
|
154
|
-
(()=>{
|
|
155
|
-
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
156
|
-
})();
|
|
157
|
-
var serialize_javascript = __webpack_require__("./node_modules/.pnpm/serialize-javascript@6.0.2/node_modules/serialize-javascript/index.js");
|
|
170
|
+
});
|
|
171
|
+
const serialize_javascript = __webpack_require__("./node_modules/.pnpm/serialize-javascript@7.0.5/node_modules/serialize-javascript/index.js");
|
|
158
172
|
var serialize_javascript_default = /*#__PURE__*/ __webpack_require__.n(serialize_javascript);
|
|
159
|
-
function _define_property(obj, key, value) {
|
|
160
|
-
if (key in obj) Object.defineProperty(obj, key, {
|
|
161
|
-
value: value,
|
|
162
|
-
enumerable: true,
|
|
163
|
-
configurable: true,
|
|
164
|
-
writable: true
|
|
165
|
-
});
|
|
166
|
-
else obj[key] = value;
|
|
167
|
-
return obj;
|
|
168
|
-
}
|
|
169
173
|
const AsyncChunkRetryPlugin_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
170
174
|
function modifyWebpackRuntimeModule(module, modifier) {
|
|
171
175
|
try {
|
|
@@ -190,6 +194,15 @@ function modifyRuntimeModule(module, modifier, isRspack) {
|
|
|
190
194
|
else modifyWebpackRuntimeModule(module, modifier);
|
|
191
195
|
}
|
|
192
196
|
class AsyncChunkRetryPlugin {
|
|
197
|
+
name = 'ASYNC_CHUNK_RETRY_PLUGIN';
|
|
198
|
+
isRspack;
|
|
199
|
+
minify;
|
|
200
|
+
runtimeOptions;
|
|
201
|
+
constructor(options, isRspack, minify){
|
|
202
|
+
this.runtimeOptions = options;
|
|
203
|
+
this.isRspack = isRspack;
|
|
204
|
+
this.minify = minify;
|
|
205
|
+
}
|
|
193
206
|
getRawRuntimeRetryCode() {
|
|
194
207
|
const { RuntimeGlobals } = rspack;
|
|
195
208
|
const filename = 'asyncChunkRetry';
|
|
@@ -201,7 +214,7 @@ class AsyncChunkRetryPlugin {
|
|
|
201
214
|
compiler.hooks.thisCompilation.tap(this.name, (compilation)=>{
|
|
202
215
|
const isRspack = this.isRspack;
|
|
203
216
|
compilation.hooks.runtimeModule.tap(this.name, (module)=>{
|
|
204
|
-
const constructorName =
|
|
217
|
+
const constructorName = module.constructorName || module.constructor?.name;
|
|
205
218
|
const isCssLoadingRuntimeModule = 'CssLoadingRuntimeModule' === constructorName;
|
|
206
219
|
if (isCssLoadingRuntimeModule) return void modifyRuntimeModule(module, (originSource)=>originSource.replace('var fullhref = __webpack_require__.p + href;', 'var fullhref = __webpack_require__.rbLoadStyleSheet ? __webpack_require__.rbLoadStyleSheet(href, chunkId) : (__webpack_require__.p + href);'), isRspack);
|
|
207
220
|
const isPublicPathModule = 'publicPath' === module.name || 'PublicPathRuntimeModule' === constructorName || 'AutoPublicPathRuntimeModule' === constructorName;
|
|
@@ -212,21 +225,12 @@ class AsyncChunkRetryPlugin {
|
|
|
212
225
|
});
|
|
213
226
|
});
|
|
214
227
|
}
|
|
215
|
-
constructor(options, isRspack, minify){
|
|
216
|
-
_define_property(this, "name", 'ASYNC_CHUNK_RETRY_PLUGIN');
|
|
217
|
-
_define_property(this, "isRspack", void 0);
|
|
218
|
-
_define_property(this, "minify", void 0);
|
|
219
|
-
_define_property(this, "runtimeOptions", void 0);
|
|
220
|
-
this.runtimeOptions = options;
|
|
221
|
-
this.isRspack = isRspack;
|
|
222
|
-
this.minify = minify;
|
|
223
|
-
}
|
|
224
228
|
}
|
|
225
229
|
const src_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
226
230
|
const PLUGIN_ASSETS_RETRY_NAME = 'rsbuild:assets-retry';
|
|
227
231
|
const ASSETS_RETRY_DATA_ATTRIBUTE = 'data-rsbuild-assets-retry';
|
|
228
232
|
function getRuntimeOptions(userOptions, defaultCrossOrigin) {
|
|
229
|
-
const { inlineScript, minify, ...runtimeOptions } = userOptions;
|
|
233
|
+
const { inlineScript: _inlineScript, minify: _minify, ...runtimeOptions } = userOptions;
|
|
230
234
|
const defaultOptions = {
|
|
231
235
|
max: 3,
|
|
232
236
|
type: [
|
|
@@ -272,7 +276,7 @@ const pluginAssetsRetry = (userOptions = {})=>({
|
|
|
272
276
|
const { inlineScript = true } = userOptions;
|
|
273
277
|
const getScriptPath = (environment)=>{
|
|
274
278
|
const distDir = environment.config.output.distPath.js;
|
|
275
|
-
return node_path.posix.join(distDir, "assets-retry.
|
|
279
|
+
return node_path.posix.join(distDir, "assets-retry.2-0-0.js");
|
|
276
280
|
};
|
|
277
281
|
const getDefaultValueFromRsbuildConfig = (config)=>{
|
|
278
282
|
const minify = 'boolean' == typeof config.output.minify ? config.output.minify : config.output.minify?.js;
|
|
@@ -1,55 +1,50 @@
|
|
|
1
|
-
(
|
|
2
|
-
|
|
3
|
-
var ERROR_PREFIX = '[@rsbuild/plugin-assets-retry] ';
|
|
1
|
+
(()=>{
|
|
2
|
+
const ERROR_PREFIX = '[@rsbuild/plugin-assets-retry] ';
|
|
4
3
|
function findCurrentDomain(url, config) {
|
|
5
|
-
|
|
6
|
-
for(
|
|
7
|
-
|
|
4
|
+
const domains = config.domain;
|
|
5
|
+
for(let i = 0; i < domains.length; i++){
|
|
6
|
+
const domain = domains[i];
|
|
8
7
|
if (-1 !== url.indexOf(domain)) return domain;
|
|
9
8
|
}
|
|
10
9
|
return window.origin;
|
|
11
10
|
}
|
|
12
11
|
function findNextDomain(url, config) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const domains = config.domain;
|
|
13
|
+
const currentDomain = findCurrentDomain(url, config);
|
|
14
|
+
const index = domains.indexOf(currentDomain);
|
|
16
15
|
return -1 === index ? currentDomain : domains[(index + 1) % domains.length];
|
|
17
16
|
}
|
|
18
|
-
|
|
17
|
+
const postfixRE = /[?#].*$/;
|
|
19
18
|
function cleanUrl(url) {
|
|
20
19
|
return url.replace(postfixRE, '');
|
|
21
20
|
}
|
|
22
21
|
function getQueryFromUrl(url) {
|
|
23
|
-
|
|
24
|
-
return parts ?
|
|
22
|
+
const parts = url.split('?')[1];
|
|
23
|
+
return parts ? `?${parts.split('#')[0]}` : '';
|
|
25
24
|
}
|
|
26
25
|
function getUrlRetryQuery(existRetryTimes, originalQuery, config) {
|
|
27
|
-
if (true === config.addQuery) return '' !== originalQuery ?
|
|
26
|
+
if (true === config.addQuery) return '' !== originalQuery ? `${originalQuery}&retry=${existRetryTimes}` : `?retry=${existRetryTimes}`;
|
|
28
27
|
if ('function' == typeof config.addQuery) return config.addQuery({
|
|
29
28
|
times: existRetryTimes,
|
|
30
|
-
originalQuery
|
|
29
|
+
originalQuery
|
|
31
30
|
});
|
|
32
31
|
return '';
|
|
33
32
|
}
|
|
34
33
|
function getNextRetryUrl(currRetryUrl, domain, nextDomain, existRetryTimes, originalQuery, config) {
|
|
35
34
|
return cleanUrl(currRetryUrl.replace(domain, nextDomain)) + getUrlRetryQuery(existRetryTimes + 1, originalQuery, config);
|
|
36
35
|
}
|
|
37
|
-
function _instanceof(left, right) {
|
|
38
|
-
if (null != right && "undefined" != typeof Symbol && right[Symbol.hasInstance]) return !!right[Symbol.hasInstance](left);
|
|
39
|
-
return left instanceof right;
|
|
40
|
-
}
|
|
41
36
|
function findMatchingRule(url, type, rules) {
|
|
42
|
-
for(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
37
|
+
for(let i = 0; i < rules.length; i++){
|
|
38
|
+
const rule = rules[i];
|
|
39
|
+
const tester = rule.test;
|
|
40
|
+
let shouldMatch = true;
|
|
41
|
+
if (tester instanceof RegExp) shouldMatch = tester.test(url);
|
|
47
42
|
else if ('string' == typeof tester) {
|
|
48
|
-
|
|
43
|
+
const regexp = new RegExp(tester);
|
|
49
44
|
shouldMatch = regexp.test(url);
|
|
50
45
|
} else if ('function' == typeof tester) shouldMatch = tester(url);
|
|
51
46
|
if (rule.domain && rule.domain.length > 0) {
|
|
52
|
-
|
|
47
|
+
const domain = findCurrentDomain(url, rule);
|
|
53
48
|
if (!rule.domain.includes(domain)) shouldMatch = false;
|
|
54
49
|
}
|
|
55
50
|
if (rule.type && rule.type.length > 0) {
|
|
@@ -59,54 +54,54 @@
|
|
|
59
54
|
}
|
|
60
55
|
return null;
|
|
61
56
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
const asyncChunkRetry_rules = __RETRY_OPTIONS__;
|
|
58
|
+
const retryCollector = {};
|
|
59
|
+
const retryCssCollector = {};
|
|
60
|
+
const globalCurrRetrying = {};
|
|
61
|
+
const globalCurrRetryingCss = {};
|
|
67
62
|
function getCurrentRetry(chunkId, existRetryTimes, isCssAsyncChunk) {
|
|
68
63
|
var _retryCssCollector_chunkId, _retryCollector_chunkId;
|
|
69
64
|
return isCssAsyncChunk ? null == (_retryCssCollector_chunkId = retryCssCollector[chunkId]) ? void 0 : _retryCssCollector_chunkId[existRetryTimes] : null == (_retryCollector_chunkId = retryCollector[chunkId]) ? void 0 : _retryCollector_chunkId[existRetryTimes];
|
|
70
65
|
}
|
|
71
66
|
function initRetry(chunkId, isCssAsyncChunk) {
|
|
72
|
-
|
|
67
|
+
const originalScriptFilename = isCssAsyncChunk ? originalGetCssFilename(chunkId) : originalGetChunkScriptFilename(chunkId);
|
|
73
68
|
if (!originalScriptFilename) throw new Error('only support cssExtract');
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
const originalPublicPath = __RUNTIME_GLOBALS_PUBLIC_PATH__;
|
|
70
|
+
const originalSrcUrl = '/' === originalPublicPath[0] && '/' !== originalPublicPath[1] ? window.origin + originalPublicPath + originalScriptFilename : originalPublicPath + originalScriptFilename;
|
|
71
|
+
const originalQuery = getQueryFromUrl(originalSrcUrl);
|
|
72
|
+
const existRetryTimes = 0;
|
|
73
|
+
const tagName = isCssAsyncChunk ? 'link' : "script";
|
|
74
|
+
const rule = findMatchingRule(originalSrcUrl, tagName, asyncChunkRetry_rules);
|
|
80
75
|
if (!rule) return null;
|
|
81
|
-
|
|
76
|
+
const nextDomain = findCurrentDomain(originalSrcUrl, rule);
|
|
82
77
|
return {
|
|
83
|
-
nextDomain
|
|
78
|
+
nextDomain,
|
|
84
79
|
nextRetryUrl: getNextRetryUrl(originalSrcUrl, nextDomain, nextDomain, existRetryTimes, originalQuery, rule),
|
|
85
|
-
originalScriptFilename
|
|
86
|
-
originalSrcUrl
|
|
87
|
-
originalQuery
|
|
88
|
-
rule
|
|
80
|
+
originalScriptFilename,
|
|
81
|
+
originalSrcUrl,
|
|
82
|
+
originalQuery,
|
|
83
|
+
rule
|
|
89
84
|
};
|
|
90
85
|
}
|
|
91
86
|
function asyncChunkRetry_nextRetry(chunkId, existRetryTimes, isCssAsyncChunk) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
const currRetry = getCurrentRetry(chunkId, existRetryTimes, isCssAsyncChunk);
|
|
88
|
+
let nextRetry;
|
|
89
|
+
const nextExistRetryTimes = existRetryTimes + 1;
|
|
95
90
|
if (0 === existRetryTimes || void 0 === currRetry) {
|
|
96
91
|
nextRetry = initRetry(chunkId, isCssAsyncChunk);
|
|
97
92
|
if (!nextRetry) return null;
|
|
98
93
|
if (isCssAsyncChunk) retryCssCollector[chunkId] = [];
|
|
99
94
|
else retryCollector[chunkId] = [];
|
|
100
95
|
} else {
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
const { originalScriptFilename, originalSrcUrl, originalQuery, rule } = currRetry;
|
|
97
|
+
const nextDomain = findNextDomain(currRetry.nextDomain, rule);
|
|
103
98
|
nextRetry = {
|
|
104
|
-
nextDomain
|
|
99
|
+
nextDomain,
|
|
105
100
|
nextRetryUrl: getNextRetryUrl(currRetry.nextRetryUrl, currRetry.nextDomain, nextDomain, existRetryTimes, originalQuery, rule),
|
|
106
|
-
originalScriptFilename
|
|
107
|
-
originalSrcUrl
|
|
108
|
-
originalQuery
|
|
109
|
-
rule
|
|
101
|
+
originalScriptFilename,
|
|
102
|
+
originalSrcUrl,
|
|
103
|
+
originalQuery,
|
|
104
|
+
rule
|
|
110
105
|
};
|
|
111
106
|
}
|
|
112
107
|
if (isCssAsyncChunk) {
|
|
@@ -118,24 +113,22 @@
|
|
|
118
113
|
}
|
|
119
114
|
return nextRetry;
|
|
120
115
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
};
|
|
126
|
-
var originalLoadScript = __RUNTIME_GLOBALS_LOAD_SCRIPT__;
|
|
116
|
+
const originalEnsureChunk = __RUNTIME_GLOBALS_ENSURE_CHUNK__;
|
|
117
|
+
const originalGetChunkScriptFilename = __RUNTIME_GLOBALS_GET_CHUNK_SCRIPT_FILENAME__;
|
|
118
|
+
const originalGetCssFilename = __RUNTIME_GLOBALS_GET_MINI_CSS_EXTRACT_FILENAME__ || __RUNTIME_GLOBALS_GET_CSS_FILENAME__ || (()=>null);
|
|
119
|
+
const originalLoadScript = __RUNTIME_GLOBALS_LOAD_SCRIPT__;
|
|
127
120
|
function ensureChunk(chunkId) {
|
|
128
|
-
|
|
121
|
+
const args = Array.prototype.slice.call(arguments);
|
|
129
122
|
if (!args[10]) args[10] = {
|
|
130
123
|
count: 0,
|
|
131
124
|
cssFailedCount: 0
|
|
132
125
|
};
|
|
133
|
-
|
|
134
|
-
|
|
126
|
+
const callingCounter = args[10];
|
|
127
|
+
const result = originalEnsureChunk.apply(null, args);
|
|
135
128
|
try {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (
|
|
129
|
+
const originalScriptFilename = originalGetChunkScriptFilename(chunkId);
|
|
130
|
+
const originalCssFilename = originalGetCssFilename(chunkId);
|
|
131
|
+
if ("u" > typeof window) {
|
|
139
132
|
if (originalScriptFilename) window.__RB_ASYNC_CHUNKS__[originalScriptFilename] = true;
|
|
140
133
|
if (originalCssFilename) window.__RB_ASYNC_CHUNKS__[originalCssFilename] = true;
|
|
141
134
|
}
|
|
@@ -144,20 +137,20 @@
|
|
|
144
137
|
}
|
|
145
138
|
if (!callingCounter || 'number' != typeof callingCounter.count || 'number' != typeof callingCounter.cssFailedCount) return result;
|
|
146
139
|
callingCounter.count += 1;
|
|
147
|
-
return result.catch(
|
|
140
|
+
return result.catch((error)=>{
|
|
148
141
|
var _error_message;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
142
|
+
const existRetryTimesAll = callingCounter.count - 1;
|
|
143
|
+
const cssExistRetryTimes = callingCounter.cssFailedCount;
|
|
144
|
+
const jsExistRetryTimes = existRetryTimesAll - cssExistRetryTimes;
|
|
145
|
+
let originalScriptFilename;
|
|
146
|
+
let nextRetryUrl;
|
|
147
|
+
let nextDomain;
|
|
148
|
+
let rule;
|
|
149
|
+
const isCssAsyncChunkLoadFailed = Boolean(null == error ? void 0 : null == (_error_message = error.message) ? void 0 : _error_message.includes('CSS chunk'));
|
|
157
150
|
if (isCssAsyncChunkLoadFailed) callingCounter.cssFailedCount += 1;
|
|
158
|
-
|
|
151
|
+
const existRetryTimes = isCssAsyncChunkLoadFailed ? cssExistRetryTimes : jsExistRetryTimes;
|
|
159
152
|
try {
|
|
160
|
-
|
|
153
|
+
const retryResult = asyncChunkRetry_nextRetry(chunkId, existRetryTimes, isCssAsyncChunkLoadFailed);
|
|
161
154
|
if (!retryResult) throw error;
|
|
162
155
|
originalScriptFilename = retryResult.originalScriptFilename;
|
|
163
156
|
nextRetryUrl = retryResult.nextRetryUrl;
|
|
@@ -167,33 +160,27 @@
|
|
|
167
160
|
if (e !== error) console.error(ERROR_PREFIX, 'failed to get nextRetryUrl', e);
|
|
168
161
|
throw error;
|
|
169
162
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
times: times,
|
|
163
|
+
const createContext = (times)=>({
|
|
164
|
+
times,
|
|
173
165
|
domain: nextDomain,
|
|
174
166
|
url: nextRetryUrl,
|
|
175
167
|
tagName: isCssAsyncChunkLoadFailed ? 'link' : "script",
|
|
176
168
|
isAsyncChunk: true
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
var context = createContext(existRetryTimes);
|
|
169
|
+
});
|
|
170
|
+
const context = createContext(existRetryTimes);
|
|
180
171
|
if (existRetryTimes >= rule.max) {
|
|
181
172
|
var _error_message1;
|
|
182
|
-
error.message = (null == (_error_message1 = error.message) ? void 0 : _error_message1.includes('retries:')) ? error.message :
|
|
173
|
+
error.message = (null == (_error_message1 = error.message) ? void 0 : _error_message1.includes('retries:')) ? error.message : `Loading chunk ${chunkId} from "${originalScriptFilename}" failed after ${rule.max} retries: "${error.message}"`;
|
|
183
174
|
if ('function' == typeof rule.onFail) rule.onFail(context);
|
|
184
175
|
throw error;
|
|
185
176
|
}
|
|
186
177
|
if ('function' == typeof rule.onRetry) rule.onRetry(context);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return delayPromise.then(function() {
|
|
192
|
-
return ensureChunk.apply(ensureChunk, args);
|
|
193
|
-
}).then(function(result) {
|
|
194
|
-
var isLastSuccessRetry = (null == callingCounter ? void 0 : callingCounter.count) === existRetryTimesAll + 2;
|
|
178
|
+
const delayTime = 'function' == typeof rule.delay ? rule.delay(context) : rule.delay;
|
|
179
|
+
const delayPromise = delayTime > 0 ? new Promise((resolve)=>setTimeout(resolve, delayTime)) : Promise.resolve();
|
|
180
|
+
return delayPromise.then(()=>ensureChunk.apply(ensureChunk, args)).then((result)=>{
|
|
181
|
+
const isLastSuccessRetry = (null == callingCounter ? void 0 : callingCounter.count) === existRetryTimesAll + 2;
|
|
195
182
|
if ('function' == typeof rule.onSuccess && isLastSuccessRetry) {
|
|
196
|
-
|
|
183
|
+
const context = createContext(existRetryTimes + 1);
|
|
197
184
|
rule.onSuccess(context);
|
|
198
185
|
}
|
|
199
186
|
return result;
|
|
@@ -201,18 +188,18 @@
|
|
|
201
188
|
});
|
|
202
189
|
}
|
|
203
190
|
function loadScript() {
|
|
204
|
-
|
|
205
|
-
|
|
191
|
+
const args = Array.prototype.slice.call(arguments);
|
|
192
|
+
const retry = globalCurrRetrying[args[3]];
|
|
206
193
|
if (retry) args[0] = retry.nextRetryUrl;
|
|
207
194
|
return originalLoadScript.apply(null, args);
|
|
208
195
|
}
|
|
209
196
|
function loadStyleSheet(href, chunkId) {
|
|
210
|
-
|
|
197
|
+
const retry = globalCurrRetryingCss[chunkId];
|
|
211
198
|
return retry && retry.nextRetryUrl || __RUNTIME_GLOBALS_PUBLIC_PATH__ + href;
|
|
212
199
|
}
|
|
213
200
|
function registerAsyncChunkRetry() {
|
|
214
|
-
if (
|
|
215
|
-
if (
|
|
201
|
+
if ("u" > typeof window && !window.__RB_ASYNC_CHUNKS__) window.__RB_ASYNC_CHUNKS__ = {};
|
|
202
|
+
if ("u" > typeof __RUNTIME_GLOBALS_REQUIRE__) try {
|
|
216
203
|
__RUNTIME_GLOBALS_ENSURE_CHUNK__ = ensureChunk;
|
|
217
204
|
__RUNTIME_GLOBALS_LOAD_SCRIPT__ = loadScript;
|
|
218
205
|
__RUNTIME_GLOBALS_RSBUILD_LOAD_STYLESHEET__ = loadStyleSheet;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
(()=>{let e="[@rsbuild/plugin-assets-retry] ";function t(e,t){let n=t.domain;for(let t=0;t<n.length;t++){let r=n[t];if(-1!==e.indexOf(r))return r}return window.origin}let n=/[?#].*$/;function r(e,t,r,_,l,o){var i;return e.replace(t,r).replace(n,"")+(i=_+1,!0===o.addQuery?""!==l?`${l}&retry=${i}`:"?retry="+i:"function"==typeof o.addQuery?o.addQuery({times:i,originalQuery:l}):"")}let _=__RETRY_OPTIONS__,l={},o={},i={},u={},a=__RUNTIME_GLOBALS_ENSURE_CHUNK__,c=__RUNTIME_GLOBALS_GET_CHUNK_SCRIPT_FILENAME__,s=__RUNTIME_GLOBALS_GET_MINI_CSS_EXTRACT_FILENAME__||__RUNTIME_GLOBALS_GET_CSS_FILENAME__||(()=>null),f=__RUNTIME_GLOBALS_LOAD_SCRIPT__;function y(n){let f=Array.prototype.slice.call(arguments);f[10]||(f[10]={count:0,cssFailedCount:0});let d=f[10],S=a.apply(null,f);try{let e=c(n),t=s(n);"u">typeof window&&(e&&(window.__RB_ASYNC_CHUNKS__[e]=!0),t&&(window.__RB_ASYNC_CHUNKS__[t]=!0))}catch(t){console.error(e,"get original script or CSS filename error",t)}return d&&"number"==typeof d.count&&"number"==typeof d.cssFailedCount?(d.count+=1,S.catch(a=>{var S,p;let R,E,L,U,N=d.count-1,m=d.cssFailedCount,A=!!(null==a||null==(S=a.message)?void 0:S.includes("CSS chunk"));A&&(d.cssFailedCount+=1);let C=A?m:N-m;try{let e=function(e,n,a){var f,y,d;let S,p=a?null==(f=o[e])?void 0:f[n]:null==(y=l[e])?void 0:y[n],R=n+1;if(0===n||void 0===p){if(!(S=function(e,n){let l,o=n?s(e):c(e);if(!o)throw Error("only support cssExtract");let i=__RUNTIME_GLOBALS_PUBLIC_PATH__,u="/"===i[0]&&"/"!==i[1]?window.origin+i+o:i+o,a=(l=u.split("?")[1])?"?"+l.split("#")[0]:"",f=function(e,n,r){for(let _=0;_<r.length;_++){let l=r[_],o=l.test,i=!0;if(o instanceof RegExp?i=o.test(e):"string"==typeof o?i=new RegExp(o).test(e):"function"==typeof o&&(i=o(e)),l.domain&&l.domain.length>0){let n=t(e,l);l.domain.includes(n)||(i=!1)}if(l.type&&l.type.length>0&&!l.type.includes(n)&&(i=!1),i)return l}return null}(u,n?"link":"script",_);if(!f)return null;let y=t(u,f);return{nextDomain:y,nextRetryUrl:r(u,y,y,0,a,f),originalScriptFilename:o,originalSrcUrl:u,originalQuery:a,rule:f}}(e,a)))return null;a?o[e]=[]:l[e]=[]}else{let e,_,l,{originalScriptFilename:o,originalSrcUrl:i,originalQuery:u,rule:a}=p,c=(d=p.nextDomain,e=a.domain,_=t(d,a),l=e.indexOf(_),-1===l?_:e[(l+1)%e.length]);S={nextDomain:c,nextRetryUrl:r(p.nextRetryUrl,p.nextDomain,c,n,u,a),originalScriptFilename:o,originalSrcUrl:i,originalQuery:u,rule:a}}return a?(o[e][R]=S,u[e]=S):(l[e][R]=S,i[e]=S),S}(n,C,A);if(!e)throw a;R=e.originalScriptFilename,E=e.nextRetryUrl,L=e.nextDomain,U=e.rule}catch(t){throw t!==a&&console.error(e,"failed to get nextRetryUrl",t),a}let T=e=>({times:e,domain:L,url:E,tagName:A?"link":"script",isAsyncChunk:!0}),g=T(C);if(C>=U.max)throw a.message=(null==(p=a.message)?void 0:p.includes("retries:"))?a.message:`Loading chunk ${n} from "${R}" failed after ${U.max} retries: "${a.message}"`,"function"==typeof U.onFail&&U.onFail(g),a;"function"==typeof U.onRetry&&U.onRetry(g);let I="function"==typeof U.delay?U.delay(g):U.delay;return(I>0?new Promise(e=>setTimeout(e,I)):Promise.resolve()).then(()=>y.apply(y,f)).then(e=>{let t=(null==d?void 0:d.count)===N+2;if("function"==typeof U.onSuccess&&t){let e=T(C+1);U.onSuccess(e)}return e})})):S}if("u">typeof window&&!window.__RB_ASYNC_CHUNKS__&&(window.__RB_ASYNC_CHUNKS__={}),"u">typeof __RUNTIME_GLOBALS_REQUIRE__)try{__RUNTIME_GLOBALS_ENSURE_CHUNK__=y,__RUNTIME_GLOBALS_LOAD_SCRIPT__=function(){let e=Array.prototype.slice.call(arguments),t=i[e[3]];return t&&(e[0]=t.nextRetryUrl),f.apply(null,e)},__RUNTIME_GLOBALS_RSBUILD_LOAD_STYLESHEET__=function(e,t){let n=u[t];return n&&n.nextRetryUrl||__RUNTIME_GLOBALS_PUBLIC_PATH__+e}}catch(t){console.error(e,"Register async chunk retry runtime failed",t)}})();
|