@rsbuild/plugin-assets-retry 1.2.2 → 1.3.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 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 "@rsbuild/plugin-assets-retry";
40
+ import { pluginAssetsRetry } from '@rsbuild/plugin-assets-retry';
41
41
 
42
42
  export default {
43
43
  plugins: [pluginAssetsRetry()],
@@ -64,7 +64,7 @@ type AssetsRetryOptions = {
64
64
  domain?: string[];
65
65
  max?: number;
66
66
  test?: string | ((url: string) => boolean);
67
- crossOrigin?: boolean | "anonymous" | "use-credentials";
67
+ crossOrigin?: boolean | 'anonymous' | 'use-credentials';
68
68
  inlineScript?: boolean;
69
69
  delay?: number | ((context: AssetsRetryHookContext) => number);
70
70
  onRetry?: (context: AssetsRetryHookContext) => void;
@@ -77,10 +77,10 @@ type AssetsRetryOptions = {
77
77
 
78
78
  ```ts
79
79
  const defaultAssetsRetryOptions = {
80
- type: ["script", "link", "img"],
80
+ type: ['script', 'link', 'img'],
81
81
  domain: [],
82
82
  max: 3,
83
- test: "",
83
+ test: '',
84
84
  crossOrigin: false,
85
85
  delay: 0,
86
86
  onRetry: () => {},
@@ -103,11 +103,11 @@ For example:
103
103
  defineConfig({
104
104
  plugins: [
105
105
  pluginAssetsRetry({
106
- domain: ["cdn1.com", "cdn2.com", "cdn3.com"],
107
- })
106
+ domain: ['cdn1.com', 'cdn2.com', 'cdn3.com'],
107
+ }),
108
108
  ],
109
109
  output: {
110
- assetPrefix: "https://cdn1.com", // or "//cdn1.com"
110
+ assetPrefix: 'https://cdn1.com', // or "//cdn1.com"
111
111
  },
112
112
  });
113
113
  ```
@@ -127,7 +127,7 @@ For example, only script tags and link tags are processed:
127
127
 
128
128
  ```js
129
129
  pluginAssetsRetry({
130
- type: ["script", "link"],
130
+ type: ['script', 'link'],
131
131
  });
132
132
  ```
133
133
 
@@ -182,7 +182,7 @@ The callback function when the asset is being retried. For example:
182
182
  pluginAssetsRetry({
183
183
  onRetry: ({ times, domain, url, tagName, isAsyncChunk }) => {
184
184
  console.log(
185
- `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`
185
+ `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
186
186
  );
187
187
  },
188
188
  });
@@ -198,7 +198,7 @@ The callback function when the asset is successfully retried. For example:
198
198
  pluginAssetsRetry({
199
199
  onSuccess: ({ times, domain, url, tagName, isAsyncChunk }) => {
200
200
  console.log(
201
- `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`
201
+ `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
202
202
  );
203
203
  },
204
204
  });
@@ -214,7 +214,7 @@ The callback function when the asset is failed to be retried. For example:
214
214
  pluginAssetsRetry({
215
215
  onFail: ({ times, domain, url, tagName, isAsyncChunk }) => {
216
216
  console.log(
217
- `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`
217
+ `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
218
218
  );
219
219
  },
220
220
  });
@@ -321,7 +321,7 @@ Or pass a function that receives `AssetsRetryHookContext` and returns the delay
321
321
  ```js
322
322
  // Calculate delay based on retry attempts
323
323
  pluginAssetsRetry({
324
- delay: (ctx) => (ctx.times + 1) * 1000,
324
+ delay: ctx => (ctx.times + 1) * 1000,
325
325
  });
326
326
  ```
327
327
 
@@ -336,12 +336,12 @@ When you use Assets Retry plugin, the Rsbuild injects some runtime code into the
336
336
  Here's an example of incorrect usage:
337
337
 
338
338
  ```js
339
- import { someMethod } from "utils";
339
+ import { someMethod } from 'utils';
340
340
 
341
341
  pluginAssetsRetry({
342
342
  onRetry() {
343
343
  // Incorrect usage, includes sensitive information
344
- const privateToken = "a-private-token";
344
+ const privateToken = 'a-private-token';
345
345
 
346
346
  // Incorrect usage, uses an external method
347
347
  someMethod(privateToken);
@@ -353,6 +353,10 @@ pluginAssetsRetry({
353
353
 
354
354
  Assets Retry plugin may not work in the following scenarios:
355
355
 
356
+ ### Sync script tag loaded resources
357
+
358
+ `<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.
359
+
356
360
  ### Module Federation
357
361
 
358
362
  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.
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 "@rsbuild/plugin-assets-retry";
38
+ import { pluginAssetsRetry } from '@rsbuild/plugin-assets-retry';
39
39
 
40
40
  export default {
41
41
  plugins: [pluginAssetsRetry()],
@@ -62,7 +62,7 @@ type AssetsRetryOptions = {
62
62
  domain?: string[];
63
63
  max?: number;
64
64
  test?: string | ((url: string) => boolean);
65
- crossOrigin?: boolean | "anonymous" | "use-credentials";
65
+ crossOrigin?: boolean | 'anonymous' | 'use-credentials';
66
66
  inlineScript?: boolean;
67
67
  delay?: number | ((context: AssetsRetryHookContext) => number);
68
68
  onRetry?: (context: AssetsRetryHookContext) => void;
@@ -75,10 +75,10 @@ type AssetsRetryOptions = {
75
75
 
76
76
  ```ts
77
77
  const defaultOptions = {
78
- type: ["script", "link", "img"],
78
+ type: ['script', 'link', 'img'],
79
79
  domain: [],
80
80
  max: 3,
81
- test: "",
81
+ test: '',
82
82
  crossOrigin: false,
83
83
  delay: 0,
84
84
  onRetry: () => {},
@@ -101,11 +101,11 @@ const defaultOptions = {
101
101
  defineConfig({
102
102
  plugins: [
103
103
  pluginAssetsRetry({
104
- domain: ["cdn1.com", "cdn2.com", "cdn3.com"],
105
- })
104
+ domain: ['cdn1.com', 'cdn2.com', 'cdn3.com'],
105
+ }),
106
106
  ],
107
107
  output: {
108
- assetPrefix: "https://cdn1.com", // 或者 "//cdn1.com"
108
+ assetPrefix: 'https://cdn1.com', // 或者 "//cdn1.com"
109
109
  },
110
110
  });
111
111
  ```
@@ -125,7 +125,7 @@ defineConfig({
125
125
 
126
126
  ```js
127
127
  pluginAssetsRetry({
128
- type: ["script", "link"],
128
+ type: ['script', 'link'],
129
129
  });
130
130
  ```
131
131
 
@@ -180,7 +180,7 @@ pluginAssetsRetry({
180
180
  pluginAssetsRetry({
181
181
  onRetry: ({ times, domain, url, tagName, isAsyncChunk }) => {
182
182
  console.log(
183
- `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`
183
+ `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
184
184
  );
185
185
  },
186
186
  });
@@ -196,7 +196,7 @@ pluginAssetsRetry({
196
196
  pluginAssetsRetry({
197
197
  onSuccess: ({ times, domain, url, tagName, isAsyncChunk }) => {
198
198
  console.log(
199
- `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`
199
+ `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
200
200
  );
201
201
  },
202
202
  });
@@ -212,7 +212,7 @@ pluginAssetsRetry({
212
212
  pluginAssetsRetry({
213
213
  onFail: ({ times, domain, url, tagName, isAsyncChunk }) => {
214
214
  console.log(
215
- `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`
215
+ `Retry ${times} times, domain: ${domain}, url: ${url}, tagName: ${tagName}, isAsyncChunk: ${isAsyncChunk}`,
216
216
  );
217
217
  },
218
218
  });
@@ -319,7 +319,7 @@ pluginAssetsRetry({
319
319
  ```js
320
320
  // 通过次数来计算延迟时间
321
321
  pluginAssetsRetry({
322
- delay: (ctx) => (ctx.times + 1) * 1000,
322
+ delay: ctx => (ctx.times + 1) * 1000,
323
323
  });
324
324
  ```
325
325
 
@@ -334,12 +334,12 @@ pluginAssetsRetry({
334
334
  以下是一个错误示例:
335
335
 
336
336
  ```js
337
- import { someMethod } from "utils";
337
+ import { someMethod } from 'utils';
338
338
 
339
339
  pluginAssetsRetry({
340
340
  onRetry() {
341
341
  // 错误用法,包含了敏感信息
342
- const privateToken = "a-private-token";
342
+ const privateToken = 'a-private-token';
343
343
 
344
344
  // 错误用法,使用了外部的方法
345
345
  someMethod(privateToken);
@@ -351,6 +351,10 @@ pluginAssetsRetry({
351
351
 
352
352
  以下场景 Assets Retry 插件可能无法生效:
353
353
 
354
+ ### 同步 script 标签加载的资源
355
+
356
+ `<script src="..."></script>` 标签加载的资源是同步加载的,如果进行重试无法保证资源加载的顺序,因此 Assets Retry 插件不会对同步加载的 script 标签进行重试。只会对 async/defer 的 script 标签进行重试。
357
+
354
358
  ### 模块联邦
355
359
 
356
360
  对于模块联邦加载的远程模块,你可以使用模块联邦 2.0 的 [@module-federation/retry-plugin](https://www.npmjs.com/package/@module-federation/retry-plugin) 来实现静态资源重试。
package/dist/index.cjs CHANGED
@@ -213,25 +213,19 @@ var __webpack_exports__ = {};
213
213
  if (isRspack) modifyRspackRuntimeModule(module, modifier);
214
214
  else modifyWebpackRuntimeModule(module, modifier);
215
215
  }
216
- function pick(obj, keys) {
217
- return keys.reduce((ret, key)=>{
218
- if (void 0 !== obj[key]) ret[key] = obj[key];
219
- return ret;
220
- }, {});
221
- }
222
216
  class AsyncChunkRetryPlugin {
223
217
  getRawRuntimeRetryCode() {
224
218
  const { RuntimeGlobals } = core_namespaceObject.rspack;
225
219
  const filename = 'asyncChunkRetry';
226
- const runtimeFilePath = external_node_path_default().join(AsyncChunkRetryPlugin_dirname, 'runtime', this.options.minify ? `${filename}.min.js` : `${filename}.js`);
220
+ const runtimeFilePath = external_node_path_default().join(AsyncChunkRetryPlugin_dirname, 'runtime', this.minify ? `${filename}.min.js` : `${filename}.js`);
227
221
  const rawText = external_node_fs_default().readFileSync(runtimeFilePath, 'utf-8');
228
222
  return rawText.replaceAll('__RUNTIME_GLOBALS_REQUIRE__', RuntimeGlobals.require).replaceAll('__RUNTIME_GLOBALS_ENSURE_CHUNK__', RuntimeGlobals.ensureChunk).replaceAll('__RUNTIME_GLOBALS_GET_CHUNK_SCRIPT_FILENAME__', RuntimeGlobals.getChunkScriptFilename).replaceAll('__RUNTIME_GLOBALS_GET_CSS_FILENAME__', RuntimeGlobals.getChunkCssFilename).replaceAll('__RUNTIME_GLOBALS_GET_MINI_CSS_EXTRACT_FILENAME__', '__webpack_require__.miniCssF').replaceAll('__RUNTIME_GLOBALS_RSBUILD_LOAD_STYLESHEET__', '__webpack_require__.rbLoadStyleSheet').replaceAll('__RUNTIME_GLOBALS_PUBLIC_PATH__', RuntimeGlobals.publicPath).replaceAll('__RUNTIME_GLOBALS_LOAD_SCRIPT__', RuntimeGlobals.loadScript).replaceAll('__RETRY_OPTIONS__', serialize_javascript_default()(this.runtimeOptions));
229
223
  }
230
224
  apply(compiler) {
231
225
  compiler.hooks.thisCompilation.tap(this.name, (compilation)=>{
226
+ const isRspack = this.isRspack;
232
227
  compilation.hooks.runtimeModule.tap(this.name, (module)=>{
233
228
  var _module_constructor;
234
- const { isRspack } = this.options;
235
229
  const constructorName = isRspack ? module.constructorName : null == (_module_constructor = module.constructor) ? void 0 : _module_constructor.name;
236
230
  const isCssLoadingRuntimeModule = 'CssLoadingRuntimeModule' === constructorName;
237
231
  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);
@@ -243,26 +237,20 @@ var __webpack_exports__ = {};
243
237
  });
244
238
  });
245
239
  }
246
- constructor(options){
240
+ constructor(options, isRspack, minify){
247
241
  _define_property(this, "name", 'ASYNC_CHUNK_RETRY_PLUGIN');
248
- _define_property(this, "options", void 0);
242
+ _define_property(this, "isRspack", void 0);
243
+ _define_property(this, "minify", void 0);
249
244
  _define_property(this, "runtimeOptions", void 0);
250
- this.options = options;
251
- this.runtimeOptions = pick(options, [
252
- 'domain',
253
- 'max',
254
- 'onRetry',
255
- 'onSuccess',
256
- 'onFail',
257
- 'addQuery',
258
- 'test',
259
- 'delay'
260
- ]);
245
+ this.runtimeOptions = options;
246
+ this.isRspack = isRspack;
247
+ this.minify = minify;
261
248
  }
262
249
  }
263
250
  const src_dirname = external_node_path_default().dirname((0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__));
264
251
  const PLUGIN_ASSETS_RETRY_NAME = 'rsbuild:assets-retry';
265
252
  function getRuntimeOptions(userOptions) {
253
+ const { inlineScript, minify, ...restOptions } = userOptions;
266
254
  const defaultOptions = {
267
255
  max: 3,
268
256
  type: [
@@ -272,24 +260,23 @@ var __webpack_exports__ = {};
272
260
  ],
273
261
  domain: [],
274
262
  crossOrigin: false,
275
- delay: 0
263
+ delay: 0,
264
+ addQuery: false
276
265
  };
277
266
  const result = {
278
267
  ...defaultOptions,
279
- ...userOptions
268
+ ...restOptions
280
269
  };
281
270
  if (!Array.isArray(result.type) || 0 === result.type.length) result.type = defaultOptions.type;
282
271
  if (!Array.isArray(result.domain) || 0 === result.domain.length) result.domain = defaultOptions.domain;
283
272
  if (Array.isArray(result.domain)) result.domain = result.domain.filter(Boolean);
284
273
  return result;
285
274
  }
286
- async function getRetryCode(options) {
275
+ async function getRetryCode(runtimeOptions, minify) {
287
276
  const filename = 'initialChunkRetry';
288
- const { minify, inlineScript: _, ...restOptions } = options;
289
277
  const runtimeFilePath = external_node_path_default().join(src_dirname, 'runtime', minify ? `${filename}.min.js` : `${filename}.js`);
290
278
  const runtimeCode = await external_node_fs_default().promises.readFile(runtimeFilePath, 'utf-8');
291
- const runtimeOptions = getRuntimeOptions(restOptions);
292
- return `(function(){${runtimeCode}})()`.replace('__RUNTIME_GLOBALS_OPTIONS__', serialize_javascript_default()(runtimeOptions));
279
+ return runtimeCode.replace('__RETRY_OPTIONS__', serialize_javascript_default()(runtimeOptions));
293
280
  }
294
281
  const pluginAssetsRetry = (userOptions = {})=>({
295
282
  name: PLUGIN_ASSETS_RETRY_NAME,
@@ -297,9 +284,9 @@ var __webpack_exports__ = {};
297
284
  const { inlineScript = true } = userOptions;
298
285
  const getScriptPath = (environment)=>{
299
286
  const distDir = environment.config.output.distPath.js;
300
- return external_node_path_default().posix.join(distDir, "assets-retry.1-2-2.js");
287
+ return external_node_path_default().posix.join(distDir, "assets-retry.1-3-0.js");
301
288
  };
302
- const formatOptions = (config)=>{
289
+ const normalizeOptions = (config)=>{
303
290
  const options = {
304
291
  ...userOptions
305
292
  };
@@ -312,7 +299,9 @@ var __webpack_exports__ = {};
312
299
  return options;
313
300
  };
314
301
  if (inlineScript) api.modifyHTMLTags(async ({ headTags, bodyTags }, { environment })=>{
315
- const code = await getRetryCode(formatOptions(environment.config));
302
+ const options = normalizeOptions(environment.config);
303
+ const runtimeOptions = getRuntimeOptions(options);
304
+ const code = await getRetryCode(runtimeOptions, options.minify);
316
305
  headTags.unshift({
317
306
  tag: "script",
318
307
  attrs: {},
@@ -342,20 +331,22 @@ var __webpack_exports__ = {};
342
331
  stage: 'additional'
343
332
  }, async ({ sources, compilation, environment })=>{
344
333
  const scriptPath = getScriptPath(environment);
345
- const code = await getRetryCode(formatOptions(environment.config));
334
+ const options = normalizeOptions(environment.config);
335
+ const runtimeOptions = getRuntimeOptions(options);
336
+ const code = await getRetryCode(runtimeOptions, options.minify);
346
337
  compilation.emitAsset(scriptPath, new sources.RawSource(code));
347
338
  });
348
339
  }
349
340
  api.modifyBundlerChain(async (chain, { environment })=>{
350
341
  const { config, htmlPaths } = environment;
351
342
  if (!userOptions || 0 === Object.keys(htmlPaths).length) return;
352
- const options = formatOptions(config);
343
+ const options = normalizeOptions(config);
344
+ const runtimeOptions = getRuntimeOptions(options);
353
345
  const isRspack = 'rspack' === api.context.bundlerType;
354
346
  chain.plugin('async-chunk-retry').use(AsyncChunkRetryPlugin, [
355
- {
356
- ...options,
357
- isRspack
358
- }
347
+ runtimeOptions,
348
+ isRspack,
349
+ options.minify
359
350
  ]);
360
351
  });
361
352
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,96 @@
1
- import type { RsbuildPlugin } from '@rsbuild/core';
2
- import type { PluginAssetsRetryOptions } from './types.js';
3
- export type { PluginAssetsRetryOptions };
4
- export declare const PLUGIN_ASSETS_RETRY_NAME = "rsbuild:assets-retry";
5
- export declare const pluginAssetsRetry: (userOptions?: PluginAssetsRetryOptions) => RsbuildPlugin;
1
+ import type { CrossOrigin as CrossOrigin_2 } from '@rsbuild/core';
2
+ import type { RsbuildPlugin } from '@rsbuild/core';
3
+
4
+ declare type AssetsRetryHookContext_2 = {
5
+ url: string;
6
+ times: number;
7
+ domain: string;
8
+ tagName: string;
9
+ isAsyncChunk: boolean;
10
+ };
11
+
12
+ declare type CompileTimeRetryOptions = {
13
+ /**
14
+ * Whether to inline the runtime JavaScript code of Assets Retry plugin into the HTML file.
15
+ * @default true
16
+ */
17
+ inlineScript?: boolean;
18
+ /**
19
+ * Whether to minify the runtime JavaScript code of Assets Retry plugin.
20
+ * @default rsbuildConfig.mode === 'production'
21
+ */
22
+ minify?: boolean;
23
+ };
24
+
25
+ export declare const PLUGIN_ASSETS_RETRY_NAME = "rsbuild:assets-retry";
26
+
27
+ export declare const pluginAssetsRetry: (userOptions?: PluginAssetsRetryOptions) => RsbuildPlugin;
28
+
29
+ export declare type PluginAssetsRetryOptions = RuntimeRetryOptions & CompileTimeRetryOptions;
30
+
31
+ declare type RuntimeRetryOptions = RuntimeRetryOptionsWithDefaultValue & RuntimeRetryOptionsWithoutDefaultValue;
32
+
33
+ declare type RuntimeRetryOptionsWithDefaultValue = {
34
+ /**
35
+ * The maximum number of retries for a single asset.
36
+ * @default 3
37
+ */
38
+ max?: number;
39
+ /**
40
+ * Used to specify the HTML tag types that need to be retried.
41
+ * @default ['script', 'link', 'img']
42
+ */
43
+ type?: string[];
44
+ /**
45
+ * Specifies the retry domain when assets fail to load.
46
+ */
47
+ domain?: string[];
48
+ /**
49
+ * Set the `crossorigin` attribute for tags.
50
+ * @default rsbuildConfig.html.crossorigin
51
+ */
52
+ crossOrigin?: boolean | CrossOrigin_2;
53
+ /**
54
+ * The delay time between retries. Unit: ms
55
+ * @default 0
56
+ */
57
+ delay?: number | ((context: AssetsRetryHookContext_2) => number);
58
+ /**
59
+ * The function to add query parameters to the URL of the asset being retried.
60
+ * @param times e.g: 1 -> 2 -> 3
61
+ * @param originalQuery initial request url's query e.g: <script src="https://cdn.com/a.js?version=1"></script> -> "?version=1"
62
+ * @default false
63
+ * @description
64
+ *
65
+ * if set to `true`, `?retry=${times}` will be added to the url.
66
+ *
67
+ * ```ts
68
+ * ({ times, originalQuery }) => hasQuery(originalQuery) ? `${getQuery(originalQuery)}&retry=${times}` : `?retry=${times}`
69
+ * ```
70
+ */
71
+ addQuery?: boolean | ((context: {
72
+ times: number;
73
+ originalQuery: string;
74
+ }) => string);
75
+ };
76
+
77
+ declare type RuntimeRetryOptionsWithoutDefaultValue = {
78
+ /**
79
+ * The test function of the asset to be retried.
80
+ */
81
+ test?: string | ((url: string) => boolean);
82
+ /**
83
+ * The callback function when the asset is failed to be retried.
84
+ */
85
+ onFail?: (context: AssetsRetryHookContext_2) => void;
86
+ /**
87
+ * The callback function when the asset is being retried.
88
+ */
89
+ onRetry?: (context: AssetsRetryHookContext_2) => void;
90
+ /**
91
+ * The callback function when the asset is successfully retried.
92
+ */
93
+ onSuccess?: (context: AssetsRetryHookContext_2) => void;
94
+ };
95
+
96
+ export { }
package/dist/index.js CHANGED
@@ -189,25 +189,19 @@ function modifyRuntimeModule(module, modifier, isRspack) {
189
189
  if (isRspack) modifyRspackRuntimeModule(module, modifier);
190
190
  else modifyWebpackRuntimeModule(module, modifier);
191
191
  }
192
- function pick(obj, keys) {
193
- return keys.reduce((ret, key)=>{
194
- if (void 0 !== obj[key]) ret[key] = obj[key];
195
- return ret;
196
- }, {});
197
- }
198
192
  class AsyncChunkRetryPlugin {
199
193
  getRawRuntimeRetryCode() {
200
194
  const { RuntimeGlobals } = rspack;
201
195
  const filename = 'asyncChunkRetry';
202
- const runtimeFilePath = node_path.join(AsyncChunkRetryPlugin_dirname, 'runtime', this.options.minify ? `${filename}.min.js` : `${filename}.js`);
196
+ const runtimeFilePath = node_path.join(AsyncChunkRetryPlugin_dirname, 'runtime', this.minify ? `${filename}.min.js` : `${filename}.js`);
203
197
  const rawText = node_fs.readFileSync(runtimeFilePath, 'utf-8');
204
198
  return rawText.replaceAll('__RUNTIME_GLOBALS_REQUIRE__', RuntimeGlobals.require).replaceAll('__RUNTIME_GLOBALS_ENSURE_CHUNK__', RuntimeGlobals.ensureChunk).replaceAll('__RUNTIME_GLOBALS_GET_CHUNK_SCRIPT_FILENAME__', RuntimeGlobals.getChunkScriptFilename).replaceAll('__RUNTIME_GLOBALS_GET_CSS_FILENAME__', RuntimeGlobals.getChunkCssFilename).replaceAll('__RUNTIME_GLOBALS_GET_MINI_CSS_EXTRACT_FILENAME__', '__webpack_require__.miniCssF').replaceAll('__RUNTIME_GLOBALS_RSBUILD_LOAD_STYLESHEET__', '__webpack_require__.rbLoadStyleSheet').replaceAll('__RUNTIME_GLOBALS_PUBLIC_PATH__', RuntimeGlobals.publicPath).replaceAll('__RUNTIME_GLOBALS_LOAD_SCRIPT__', RuntimeGlobals.loadScript).replaceAll('__RETRY_OPTIONS__', serialize_javascript_default()(this.runtimeOptions));
205
199
  }
206
200
  apply(compiler) {
207
201
  compiler.hooks.thisCompilation.tap(this.name, (compilation)=>{
202
+ const isRspack = this.isRspack;
208
203
  compilation.hooks.runtimeModule.tap(this.name, (module)=>{
209
204
  var _module_constructor;
210
- const { isRspack } = this.options;
211
205
  const constructorName = isRspack ? module.constructorName : null == (_module_constructor = module.constructor) ? void 0 : _module_constructor.name;
212
206
  const isCssLoadingRuntimeModule = 'CssLoadingRuntimeModule' === constructorName;
213
207
  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);
@@ -219,26 +213,20 @@ class AsyncChunkRetryPlugin {
219
213
  });
220
214
  });
221
215
  }
222
- constructor(options){
216
+ constructor(options, isRspack, minify){
223
217
  _define_property(this, "name", 'ASYNC_CHUNK_RETRY_PLUGIN');
224
- _define_property(this, "options", void 0);
218
+ _define_property(this, "isRspack", void 0);
219
+ _define_property(this, "minify", void 0);
225
220
  _define_property(this, "runtimeOptions", void 0);
226
- this.options = options;
227
- this.runtimeOptions = pick(options, [
228
- 'domain',
229
- 'max',
230
- 'onRetry',
231
- 'onSuccess',
232
- 'onFail',
233
- 'addQuery',
234
- 'test',
235
- 'delay'
236
- ]);
221
+ this.runtimeOptions = options;
222
+ this.isRspack = isRspack;
223
+ this.minify = minify;
237
224
  }
238
225
  }
239
226
  const src_dirname = node_path.dirname(fileURLToPath(import.meta.url));
240
227
  const PLUGIN_ASSETS_RETRY_NAME = 'rsbuild:assets-retry';
241
228
  function getRuntimeOptions(userOptions) {
229
+ const { inlineScript, minify, ...restOptions } = userOptions;
242
230
  const defaultOptions = {
243
231
  max: 3,
244
232
  type: [
@@ -248,24 +236,23 @@ function getRuntimeOptions(userOptions) {
248
236
  ],
249
237
  domain: [],
250
238
  crossOrigin: false,
251
- delay: 0
239
+ delay: 0,
240
+ addQuery: false
252
241
  };
253
242
  const result = {
254
243
  ...defaultOptions,
255
- ...userOptions
244
+ ...restOptions
256
245
  };
257
246
  if (!Array.isArray(result.type) || 0 === result.type.length) result.type = defaultOptions.type;
258
247
  if (!Array.isArray(result.domain) || 0 === result.domain.length) result.domain = defaultOptions.domain;
259
248
  if (Array.isArray(result.domain)) result.domain = result.domain.filter(Boolean);
260
249
  return result;
261
250
  }
262
- async function getRetryCode(options) {
251
+ async function getRetryCode(runtimeOptions, minify) {
263
252
  const filename = 'initialChunkRetry';
264
- const { minify, inlineScript: _, ...restOptions } = options;
265
253
  const runtimeFilePath = node_path.join(src_dirname, 'runtime', minify ? `${filename}.min.js` : `${filename}.js`);
266
254
  const runtimeCode = await node_fs.promises.readFile(runtimeFilePath, 'utf-8');
267
- const runtimeOptions = getRuntimeOptions(restOptions);
268
- return `(function(){${runtimeCode}})()`.replace('__RUNTIME_GLOBALS_OPTIONS__', serialize_javascript_default()(runtimeOptions));
255
+ return runtimeCode.replace('__RETRY_OPTIONS__', serialize_javascript_default()(runtimeOptions));
269
256
  }
270
257
  const pluginAssetsRetry = (userOptions = {})=>({
271
258
  name: PLUGIN_ASSETS_RETRY_NAME,
@@ -273,9 +260,9 @@ const pluginAssetsRetry = (userOptions = {})=>({
273
260
  const { inlineScript = true } = userOptions;
274
261
  const getScriptPath = (environment)=>{
275
262
  const distDir = environment.config.output.distPath.js;
276
- return node_path.posix.join(distDir, "assets-retry.1-2-2.js");
263
+ return node_path.posix.join(distDir, "assets-retry.1-3-0.js");
277
264
  };
278
- const formatOptions = (config)=>{
265
+ const normalizeOptions = (config)=>{
279
266
  const options = {
280
267
  ...userOptions
281
268
  };
@@ -288,7 +275,9 @@ const pluginAssetsRetry = (userOptions = {})=>({
288
275
  return options;
289
276
  };
290
277
  if (inlineScript) api.modifyHTMLTags(async ({ headTags, bodyTags }, { environment })=>{
291
- const code = await getRetryCode(formatOptions(environment.config));
278
+ const options = normalizeOptions(environment.config);
279
+ const runtimeOptions = getRuntimeOptions(options);
280
+ const code = await getRetryCode(runtimeOptions, options.minify);
292
281
  headTags.unshift({
293
282
  tag: "script",
294
283
  attrs: {},
@@ -318,20 +307,22 @@ const pluginAssetsRetry = (userOptions = {})=>({
318
307
  stage: 'additional'
319
308
  }, async ({ sources, compilation, environment })=>{
320
309
  const scriptPath = getScriptPath(environment);
321
- const code = await getRetryCode(formatOptions(environment.config));
310
+ const options = normalizeOptions(environment.config);
311
+ const runtimeOptions = getRuntimeOptions(options);
312
+ const code = await getRetryCode(runtimeOptions, options.minify);
322
313
  compilation.emitAsset(scriptPath, new sources.RawSource(code));
323
314
  });
324
315
  }
325
316
  api.modifyBundlerChain(async (chain, { environment })=>{
326
317
  const { config, htmlPaths } = environment;
327
318
  if (!userOptions || 0 === Object.keys(htmlPaths).length) return;
328
- const options = formatOptions(config);
319
+ const options = normalizeOptions(config);
320
+ const runtimeOptions = getRuntimeOptions(options);
329
321
  const isRspack = 'rspack' === api.context.bundlerType;
330
322
  chain.plugin('async-chunk-retry').use(AsyncChunkRetryPlugin, [
331
- {
332
- ...options,
333
- isRspack
334
- }
323
+ runtimeOptions,
324
+ isRspack,
325
+ options.minify
335
326
  ]);
336
327
  });
337
328
  }