webpack 5.21.0 → 5.23.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (61) hide show
  1. package/lib/ChunkGraph.js +3 -2
  2. package/lib/CodeGenerationResults.js +2 -1
  3. package/lib/Compilation.js +91 -40
  4. package/lib/EvalDevToolModulePlugin.js +4 -0
  5. package/lib/EvalSourceMapDevToolPlugin.js +4 -0
  6. package/lib/ExportsInfo.js +1 -0
  7. package/lib/ExternalModule.js +8 -7
  8. package/lib/FlagDependencyUsagePlugin.js +7 -6
  9. package/lib/JavascriptMetaInfoPlugin.js +62 -0
  10. package/lib/LibManifestPlugin.js +1 -13
  11. package/lib/Module.js +2 -3
  12. package/lib/MultiCompiler.js +170 -77
  13. package/lib/MultiStats.js +9 -6
  14. package/lib/NormalModuleFactory.js +135 -22
  15. package/lib/RuntimeGlobals.js +5 -0
  16. package/lib/RuntimePlugin.js +10 -1
  17. package/lib/Watching.js +70 -27
  18. package/lib/WebpackOptionsApply.js +7 -7
  19. package/lib/config/defaults.js +26 -10
  20. package/lib/config/target.js +1 -1
  21. package/lib/container/ContainerEntryModule.js +2 -1
  22. package/lib/dependencies/AMDDefineDependency.js +1 -1
  23. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +8 -0
  24. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +2 -1
  25. package/lib/dependencies/HarmonyExportInitFragment.js +2 -3
  26. package/lib/dependencies/HarmonyImportSpecifierDependency.js +9 -2
  27. package/lib/dependencies/LoaderPlugin.js +9 -2
  28. package/lib/dependencies/URLDependency.js +35 -13
  29. package/lib/dependencies/URLPlugin.js +3 -1
  30. package/lib/dependencies/WorkerPlugin.js +7 -1
  31. package/lib/hmr/LazyCompilationPlugin.js +2 -2
  32. package/lib/index.js +1 -0
  33. package/lib/javascript/CommonJsChunkFormatPlugin.js +15 -4
  34. package/lib/javascript/JavascriptModulesPlugin.js +143 -78
  35. package/lib/javascript/JavascriptParser.js +1 -0
  36. package/lib/json/JsonGenerator.js +29 -8
  37. package/lib/library/AbstractLibraryPlugin.js +108 -32
  38. package/lib/library/AmdLibraryPlugin.js +12 -6
  39. package/lib/library/AssignLibraryPlugin.js +137 -26
  40. package/lib/library/EnableLibraryPlugin.js +18 -7
  41. package/lib/library/ExportPropertyLibraryPlugin.js +16 -5
  42. package/lib/library/JsonpLibraryPlugin.js +3 -1
  43. package/lib/library/ModuleLibraryPlugin.js +100 -0
  44. package/lib/library/SystemLibraryPlugin.js +1 -1
  45. package/lib/node/NodeTargetPlugin.js +1 -1
  46. package/lib/optimize/ConcatenatedModule.js +54 -35
  47. package/lib/optimize/InnerGraph.js +5 -4
  48. package/lib/runtime/GetChunkFilenameRuntimeModule.js +2 -3
  49. package/lib/runtime/RelativeUrlRuntimeModule.js +41 -0
  50. package/lib/runtime/StartupChunkDependenciesPlugin.js +1 -0
  51. package/lib/serialization/ObjectMiddleware.js +34 -19
  52. package/lib/stats/DefaultStatsFactoryPlugin.js +1 -12
  53. package/lib/stats/DefaultStatsPrinterPlugin.js +19 -6
  54. package/lib/util/IterableHelpers.js +46 -0
  55. package/lib/util/LazyBucketSortedSet.js +3 -2
  56. package/lib/util/SetHelpers.js +11 -0
  57. package/lib/webpack.js +56 -50
  58. package/package.json +3 -3
  59. package/schemas/WebpackOptions.json +8 -1
  60. package/types.d.ts +38 -7
  61. package/lib/FlagUsingEvalPlugin.js +0 -44
@@ -11,6 +11,7 @@ const { SyncHook, MultiHook } = require("tapable");
11
11
  const ConcurrentCompilationError = require("./ConcurrentCompilationError");
12
12
  const MultiStats = require("./MultiStats");
13
13
  const MultiWatching = require("./MultiWatching");
14
+ const ArrayQueue = require("./util/ArrayQueue");
14
15
 
15
16
  /** @template T @typedef {import("tapable").AsyncSeriesHook<T>} AsyncSeriesHook<T> */
16
17
  /** @template T @template R @typedef {import("tapable").SyncBailHook<T, R>} SyncBailHook<T, R> */
@@ -23,12 +24,6 @@ const MultiWatching = require("./MultiWatching");
23
24
  /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
24
25
  /** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
25
26
 
26
- /** @typedef {number} CompilerStatus */
27
-
28
- const STATUS_PENDING = 0;
29
- const STATUS_DONE = 1;
30
- const STATUS_NEW = 2;
31
-
32
27
  /**
33
28
  * @template T
34
29
  * @callback Callback
@@ -42,11 +37,17 @@ const STATUS_NEW = 2;
42
37
  * @param {Callback<MultiStats>} callback
43
38
  */
44
39
 
40
+ /**
41
+ * @typedef {Object} MultiCompilerOptions
42
+ * @property {number=} parallelism how many Compilers are allows to run at the same time in parallel
43
+ */
44
+
45
45
  module.exports = class MultiCompiler {
46
46
  /**
47
47
  * @param {Compiler[] | Record<string, Compiler>} compilers child compilers
48
+ * @param {MultiCompilerOptions} options options
48
49
  */
49
- constructor(compilers) {
50
+ constructor(compilers, options) {
50
51
  if (!Array.isArray(compilers)) {
51
52
  compilers = Object.keys(compilers).map(name => {
52
53
  compilers[name].name = name;
@@ -71,6 +72,10 @@ module.exports = class MultiCompiler {
71
72
  )
72
73
  });
73
74
  this.compilers = compilers;
75
+ /** @type {MultiCompilerOptions} */
76
+ this._options = {
77
+ parallelism: options.parallelism || Infinity
78
+ };
74
79
  /** @type {WeakMap<Compiler, string[]>} */
75
80
  this.dependencies = new WeakMap();
76
81
  this.running = false;
@@ -104,7 +109,10 @@ module.exports = class MultiCompiler {
104
109
  }
105
110
 
106
111
  get options() {
107
- return this.compilers.map(c => c.options);
112
+ return Object.assign(
113
+ this.compilers.map(c => c.options),
114
+ this._options
115
+ );
108
116
  }
109
117
 
110
118
  get outputPath() {
@@ -257,7 +265,9 @@ module.exports = class MultiCompiler {
257
265
  return true;
258
266
  }
259
267
 
268
+ // TODO webpack 6 remove
260
269
  /**
270
+ * @deprecated This method should have been private
261
271
  * @param {Compiler[]} compilers the child compilers
262
272
  * @param {RunWithDependenciesHandler} fn a handler to run for each compiler
263
273
  * @param {Callback<MultiStats>} callback the compiler's handler
@@ -300,6 +310,133 @@ module.exports = class MultiCompiler {
300
310
  runCompilers(callback);
301
311
  }
302
312
 
313
+ /**
314
+ * @template SetupResult
315
+ * @param {function(Compiler, number, Callback<Stats>, function(): boolean, function(): void, function(): void): SetupResult} setup setup a single compiler
316
+ * @param {function(Compiler, Callback<Stats>): void} run run/continue a single compiler
317
+ * @param {Callback<MultiStats>} callback callback when all compilers are done, result includes Stats of all changed compilers
318
+ * @returns {SetupResult[]} result of setup
319
+ */
320
+ _runGraph(setup, run, callback) {
321
+ /** @typedef {{ compiler: Compiler, result: Stats, state: "blocked" | "queued" | "running" | "done", children: Node[], parents: Node[] }} Node */
322
+
323
+ /** @type {Node[]} */
324
+ const nodes = this.compilers.map(compiler => ({
325
+ compiler,
326
+ result: undefined,
327
+ state: "blocked",
328
+ children: [],
329
+ parents: []
330
+ }));
331
+ /** @type {Map<string, Node>} */
332
+ const compilerToNode = new Map();
333
+ for (const node of nodes) compilerToNode.set(node.compiler.name, node);
334
+ for (const node of nodes) {
335
+ const dependencies = this.dependencies.get(node.compiler);
336
+ if (!dependencies) continue;
337
+ for (const dep of dependencies) {
338
+ const parent = compilerToNode.get(dep);
339
+ node.parents.push(parent);
340
+ parent.children.push(node);
341
+ }
342
+ }
343
+ const queue = new ArrayQueue();
344
+ for (const node of nodes) {
345
+ if (node.parents.length === 0) {
346
+ node.state = "queued";
347
+ queue.enqueue(node);
348
+ }
349
+ }
350
+ let errored = false;
351
+ let running = 0;
352
+ const parallelism = this._options.parallelism;
353
+ const nodeDone = (node, err, stats) => {
354
+ if (errored) return;
355
+ if (err) {
356
+ errored = true;
357
+ return asyncLib.each(
358
+ nodes,
359
+ (node, callback) => {
360
+ if (node.compiler.watching) {
361
+ node.compiler.watching.close(callback);
362
+ } else {
363
+ callback();
364
+ }
365
+ },
366
+ () => callback(err)
367
+ );
368
+ }
369
+ node.result = stats;
370
+ if (node.state === "running") {
371
+ running--;
372
+ node.state = "done";
373
+ for (const child of node.children) {
374
+ if (child.state !== "blocked") continue;
375
+ if (child.parents.every(p => p.state === "done")) {
376
+ child.state = "queued";
377
+ queue.enqueue(child);
378
+ }
379
+ }
380
+ process.nextTick(processQueue);
381
+ }
382
+ };
383
+ const nodeInvalid = node => {
384
+ if (node.state === "done") {
385
+ node.state = "blocked";
386
+ for (const child of node.children) {
387
+ nodeInvalid(child);
388
+ }
389
+ }
390
+ };
391
+ const nodeChange = node => {
392
+ nodeInvalid(node);
393
+ if (
394
+ node.state === "blocked" &&
395
+ node.parents.every(p => p.state === "done")
396
+ ) {
397
+ node.state = "queued";
398
+ queue.enqueue(node);
399
+ processQueue();
400
+ }
401
+ };
402
+ const setupResults = [];
403
+ nodes.forEach((node, i) => {
404
+ setupResults.push(
405
+ setup(
406
+ node.compiler,
407
+ i,
408
+ nodeDone.bind(null, node),
409
+ () => node.state === "blocked" || node.state === "queued",
410
+ () => nodeChange(node),
411
+ () => nodeInvalid(node)
412
+ )
413
+ );
414
+ });
415
+ const processQueue = () => {
416
+ while (running < parallelism && queue.length > 0 && !errored) {
417
+ const node = queue.dequeue();
418
+ running++;
419
+ node.state = "running";
420
+ run(node.compiler, nodeDone.bind(null, node));
421
+ }
422
+ if (!errored && running === 0) {
423
+ const stats = [];
424
+ for (const node of nodes) {
425
+ const result = node.result;
426
+ if (result) {
427
+ node.result = undefined;
428
+ stats.push(result);
429
+ }
430
+ }
431
+ if (stats.length > 0) {
432
+ callback(null, new MultiStats(stats));
433
+ }
434
+ }
435
+ };
436
+ processQueue();
437
+ return setupResults;
438
+ }
439
+
303
440
  /**
304
441
  * @param {WatchOptions|WatchOptions[]} watchOptions the watcher's options
305
442
  * @param {Callback<MultiStats>} handler signals when the call finishes
@@ -310,55 +447,29 @@ module.exports = class MultiCompiler {
310
447
  return handler(new ConcurrentCompilationError());
311
448
  }
312
449
 
313
- /** @type {Watching[]} */
314
- const watchings = [];
315
-
316
- /** @type {Stats[]} */
317
- const allStats = this.compilers.map(() => null);
318
-
319
- /** @type {CompilerStatus[]} */
320
- const compilerStatus = this.compilers.map(() => STATUS_PENDING);
321
-
322
450
  if (this.validateDependencies(handler)) {
323
- this.running = true;
324
- this.runWithDependencies(
325
- this.compilers,
326
- (compiler, callback) => {
327
- const compilerIdx = this.compilers.indexOf(compiler);
328
- let firstRun = true;
329
- let watching = compiler.watch(
330
- Array.isArray(watchOptions)
331
- ? watchOptions[compilerIdx]
332
- : watchOptions,
333
- (err, stats) => {
334
- if (err) handler(err);
335
- if (stats) {
336
- allStats[compilerIdx] = stats;
337
- compilerStatus[compilerIdx] = STATUS_NEW;
338
- if (compilerStatus.every(status => status !== STATUS_PENDING)) {
339
- const freshStats = allStats.filter((s, idx) => {
340
- return compilerStatus[idx] === STATUS_NEW;
341
- });
342
- compilerStatus.fill(STATUS_DONE);
343
- const multiStats = new MultiStats(freshStats);
344
- handler(null, multiStats);
345
- }
346
- }
347
- if (firstRun && !err) {
348
- firstRun = false;
349
- callback();
350
- }
351
- }
451
+ const watchings = this._runGraph(
452
+ (compiler, idx, callback, isBlocked, setChanged, setInvalid) => {
453
+ const watching = compiler.watch(
454
+ Array.isArray(watchOptions) ? watchOptions[idx] : watchOptions,
455
+ callback
352
456
  );
353
- watchings.push(watching);
457
+ if (watching) {
458
+ watching._onInvalid = setInvalid;
459
+ watching._onChange = setChanged;
460
+ watching._isBlocked = isBlocked;
461
+ }
462
+ return watching;
354
463
  },
355
- () => {
356
- // ignore
357
- }
464
+ (compiler, initial, callback) => {
465
+ if (!compiler.watching.running) compiler.watching.invalidate();
466
+ },
467
+ handler
358
468
  );
469
+ return new MultiWatching(watchings, this);
359
470
  }
360
471
 
361
- return new MultiWatching(watchings, this);
472
+ return new MultiWatching([], this);
362
473
  }
363
474
 
364
475
  /**
@@ -370,34 +481,16 @@ module.exports = class MultiCompiler {
370
481
  return callback(new ConcurrentCompilationError());
371
482
  }
372
483
 
373
- const finalCallback = (err, stats) => {
374
- this.running = false;
375
-
376
- if (callback !== undefined) {
377
- return callback(err, stats);
378
- }
379
- };
380
-
381
- const allStats = this.compilers.map(() => null);
382
484
  if (this.validateDependencies(callback)) {
383
- this.running = true;
384
- this.runWithDependencies(
385
- this.compilers,
386
- (compiler, callback) => {
387
- const compilerIdx = this.compilers.indexOf(compiler);
388
- compiler.run((err, stats) => {
389
- if (err) {
390
- return callback(err);
391
- }
392
- allStats[compilerIdx] = stats;
393
- callback();
394
- });
395
- },
396
- err => {
397
- if (err) {
398
- return finalCallback(err);
485
+ this._runGraph(
486
+ () => {},
487
+ (compiler, callback) => compiler.run(callback),
488
+ (err, stats) => {
489
+ this.running = false;
490
+
491
+ if (callback !== undefined) {
492
+ return callback(err, stats);
399
493
  }
400
- finalCallback(null, new MultiStats(allStats));
401
494
  }
402
495
  );
403
496
  }
package/lib/MultiStats.js CHANGED
@@ -47,17 +47,20 @@ class MultiStats {
47
47
  if (!options) {
48
48
  options = {};
49
49
  }
50
- const { children: _, ...baseOptions } = options;
50
+ const { children: childrenOptions = undefined, ...baseOptions } =
51
+ typeof options === "string" ? { preset: options } : options;
51
52
  const children = this.stats.map((stat, idx) => {
52
- const childOptions = Array.isArray(options.children)
53
- ? options.children[idx]
54
- : options.children;
53
+ const childOptions = Array.isArray(childrenOptions)
54
+ ? childrenOptions[idx]
55
+ : childrenOptions;
55
56
  return stat.compilation.createStatsOptions(
56
57
  {
57
58
  ...baseOptions,
58
- ...(childOptions && typeof childOptions === "object"
59
+ ...(typeof childOptions === "string"
60
+ ? { preset: childOptions }
61
+ : childOptions && typeof childOptions === "object"
59
62
  ? childOptions
60
- : { preset: childOptions })
63
+ : undefined)
61
64
  },
62
65
  context
63
66
  );
@@ -750,35 +750,148 @@ class NormalModuleFactory extends ModuleFactory {
750
750
  resolveContext,
751
751
  (err, resolvedResource, resolvedResourceResolveData) => {
752
752
  if (err) {
753
- if (resolver.options.fullySpecified) {
754
- resolver
755
- .withOptions({
756
- fullySpecified: false
757
- })
758
- .resolve(
759
- contextInfo,
760
- context,
761
- unresolvedResource,
762
- resolveContext,
763
- (err2, resolvedResource) => {
764
- if (!err2 && resolvedResource) {
765
- const resource = parseResource(
766
- resolvedResource
767
- ).path.replace(/^.*[\\/]/, "");
768
- err.message += `
769
- Did you mean '${resource}'?
753
+ return this._resolveResourceErrorHints(
754
+ err,
755
+ contextInfo,
756
+ context,
757
+ unresolvedResource,
758
+ resolver,
759
+ resolveContext,
760
+ (err2, hints) => {
761
+ if (err2) {
762
+ err.message += `
763
+ An fatal error happened during resolving additional hints for this error: ${err2.message}`;
764
+ err.stack += `
765
+
766
+ An fatal error happened during resolving additional hints for this error:
767
+ ${err2.stack}`;
768
+ return callback(err);
769
+ }
770
+ if (hints && hints.length > 0) {
771
+ err.message += `
772
+ ${hints.join("\n\n")}`;
773
+ }
774
+ callback(err);
775
+ }
776
+ );
777
+ }
778
+ callback(err, resolvedResource, resolvedResourceResolveData);
779
+ }
780
+ );
781
+ }
782
+
783
+ _resolveResourceErrorHints(
784
+ error,
785
+ contextInfo,
786
+ context,
787
+ unresolvedResource,
788
+ resolver,
789
+ resolveContext,
790
+ callback
791
+ ) {
792
+ asyncLib.parallel(
793
+ [
794
+ callback => {
795
+ if (!resolver.options.fullySpecified) return callback();
796
+ resolver
797
+ .withOptions({
798
+ fullySpecified: false
799
+ })
800
+ .resolve(
801
+ contextInfo,
802
+ context,
803
+ unresolvedResource,
804
+ resolveContext,
805
+ (err, resolvedResource) => {
806
+ if (!err && resolvedResource) {
807
+ const resource = parseResource(resolvedResource).path.replace(
808
+ /^.*[\\/]/,
809
+ ""
810
+ );
811
+ return callback(
812
+ null,
813
+ `Did you mean '${resource}'?
770
814
  BREAKING CHANGE: The request '${unresolvedResource}' failed to resolve only because it was resolved as fully specified
771
815
  (probably because the origin is a '*.mjs' file or a '*.js' file where the package.json contains '"type": "module"').
772
816
  The extension in the request is mandatory for it to be fully specified.
773
- Add the extension to the request.`;
817
+ Add the extension to the request.`
818
+ );
819
+ }
820
+ callback();
821
+ }
822
+ );
823
+ },
824
+ callback => {
825
+ if (!resolver.options.enforceExtension) return callback();
826
+ resolver
827
+ .withOptions({
828
+ enforceExtension: false,
829
+ extensions: []
830
+ })
831
+ .resolve(
832
+ contextInfo,
833
+ context,
834
+ unresolvedResource,
835
+ resolveContext,
836
+ (err, resolvedResource) => {
837
+ if (!err && resolvedResource) {
838
+ let hint = "";
839
+ const match = /(\.[^.]+)(\?|$)/.exec(unresolvedResource);
840
+ if (match) {
841
+ const fixedRequest = unresolvedResource.replace(
842
+ /(\.[^.]+)(\?|$)/,
843
+ "$2"
844
+ );
845
+ if (resolver.options.extensions.has(match[1])) {
846
+ hint = `Did you mean '${fixedRequest}'?`;
847
+ } else {
848
+ hint = `Did you mean '${fixedRequest}'? Also note that '${match[1]}' is not in 'resolve.extensions' yet and need to be added for this to work?`;
849
+ }
850
+ } else {
851
+ hint = `Did you mean to omit the extension or to remove 'resolve.enforceExtension'?`;
774
852
  }
775
- callback(err);
853
+ return callback(
854
+ null,
855
+ `The request '${unresolvedResource}' failed to resolve only because 'resolve.enforceExtension' was specified.
856
+ ${hint}
857
+ Including the extension in the request is no longer possible. Did you mean to enforce including the extension in requests with 'resolve.extensions: []' instead?`
858
+ );
776
859
  }
777
- );
778
- return;
860
+ callback();
861
+ }
862
+ );
863
+ },
864
+ callback => {
865
+ if (
866
+ /^\.\.?\//.test(unresolvedResource) ||
867
+ resolver.options.preferRelative
868
+ ) {
869
+ return callback();
779
870
  }
871
+ resolver.resolve(
872
+ contextInfo,
873
+ context,
874
+ `./${unresolvedResource}`,
875
+ resolveContext,
876
+ (err, resolvedResource) => {
877
+ if (err || !resolvedResource) return callback();
878
+ const moduleDirectories = resolver.options.modules
879
+ .map(m => (Array.isArray(m) ? m.join(", ") : m))
880
+ .join(", ");
881
+ callback(
882
+ null,
883
+ `Did you mean './${unresolvedResource}'?
884
+ Requests that should resolve in the current directory need to start with './'.
885
+ Requests that start with a name are treated as module requests and resolve within module directories (${moduleDirectories}).
886
+ If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.`
887
+ );
888
+ }
889
+ );
780
890
  }
781
- callback(err, resolvedResource, resolvedResourceResolveData);
891
+ ],
892
+ (err, hints) => {
893
+ if (err) return callback(err);
894
+ callback(null, hints.filter(Boolean));
782
895
  }
783
896
  );
784
897
  }
@@ -304,6 +304,11 @@ exports.systemContext = "__webpack_require__.y";
304
304
  */
305
305
  exports.baseURI = "__webpack_require__.b";
306
306
 
307
+ /**
308
+ * a RelativeURL class when relative URLs are used
309
+ */
310
+ exports.relativeUrl = "__webpack_require__.U";
311
+
307
312
  /**
308
313
  * Creates an async module. The body function must be a async function.
309
314
  * "module.exports" will be decorated with an AsyncModulePromise.
@@ -22,6 +22,7 @@ const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModu
22
22
  const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
23
23
  const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
24
24
  const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
25
+ const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule");
25
26
  const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
26
27
  const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
27
28
  const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
@@ -48,6 +49,7 @@ const GLOBALS_ON_REQUIRE = [
48
49
  RuntimeGlobals.interceptModuleExecution,
49
50
  RuntimeGlobals.publicPath,
50
51
  RuntimeGlobals.baseURI,
52
+ RuntimeGlobals.relativeUrl,
51
53
  RuntimeGlobals.scriptNonce,
52
54
  RuntimeGlobals.uncaughtErrorHandler,
53
55
  RuntimeGlobals.asyncModule,
@@ -55,7 +57,8 @@ const GLOBALS_ON_REQUIRE = [
55
57
  RuntimeGlobals.instantiateWasm,
56
58
  RuntimeGlobals.shareScopeMap,
57
59
  RuntimeGlobals.initializeSharing,
58
- RuntimeGlobals.loadScript
60
+ RuntimeGlobals.loadScript,
61
+ RuntimeGlobals.systemContext
59
62
  ];
60
63
 
61
64
  const MODULE_DEPENDENCIES = {
@@ -312,6 +315,12 @@ class RuntimePlugin {
312
315
  compilation.addRuntimeModule(chunk, new LoadScriptRuntimeModule());
313
316
  return true;
314
317
  });
318
+ compilation.hooks.runtimeRequirementInTree
319
+ .for(RuntimeGlobals.relativeUrl)
320
+ .tap("RuntimePlugin", (chunk, set) => {
321
+ compilation.addRuntimeModule(chunk, new RelativeUrlRuntimeModule());
322
+ return true;
323
+ });
315
324
  // TODO webpack 6: remove CompatRuntimeModule
316
325
  compilation.hooks.additionalTreeRuntimeRequirements.tap(
317
326
  "RuntimePlugin",