webpack 5.107.0 → 5.107.1

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.
Files changed (47) hide show
  1. package/lib/BannerPlugin.js +3 -4
  2. package/lib/Chunk.js +21 -25
  3. package/lib/ChunkGroup.js +57 -15
  4. package/lib/Compilation.js +33 -11
  5. package/lib/EvalSourceMapDevToolPlugin.js +0 -1
  6. package/lib/ExportsInfo.js +30 -34
  7. package/lib/ExternalModule.js +15 -11
  8. package/lib/ExternalModuleFactoryPlugin.js +2 -1
  9. package/lib/Module.js +1 -1
  10. package/lib/ModuleNotFoundError.js +10 -0
  11. package/lib/ModuleSourceTypeConstants.js +24 -22
  12. package/lib/NormalModule.js +106 -46
  13. package/lib/NormalModuleFactory.js +38 -26
  14. package/lib/RuntimePlugin.js +1 -1
  15. package/lib/SourceMapDevToolPlugin.js +250 -49
  16. package/lib/Template.js +1 -1
  17. package/lib/TemplatedPathPlugin.js +22 -4
  18. package/lib/asset/AssetBytesGenerator.js +6 -6
  19. package/lib/asset/AssetGenerator.js +14 -14
  20. package/lib/asset/AssetModulesPlugin.js +3 -7
  21. package/lib/asset/AssetSourceGenerator.js +6 -6
  22. package/lib/css/CssModulesPlugin.js +2 -2
  23. package/lib/dependencies/CommonJsImportsParserPlugin.js +108 -1
  24. package/lib/dependencies/CssUrlDependency.js +3 -2
  25. package/lib/dependencies/HarmonyDetectionParserPlugin.js +21 -1
  26. package/lib/dependencies/HtmlScriptSrcDependency.js +264 -25
  27. package/lib/dependencies/HtmlSourceDependency.js +3 -2
  28. package/lib/html/HtmlModulesPlugin.js +1 -5
  29. package/lib/html/walkHtmlTokens.js +641 -125
  30. package/lib/index.js +2 -0
  31. package/lib/javascript/JavascriptModulesPlugin.js +2 -2
  32. package/lib/optimize/SideEffectsFlagPlugin.js +1 -2
  33. package/lib/optimize/SplitChunksPlugin.js +4 -4
  34. package/lib/runtime/AutoPublicPathRuntimeModule.js +3 -3
  35. package/lib/runtime/GetChunkFilenameRuntimeModule.js +5 -5
  36. package/lib/sharing/ConsumeSharedPlugin.js +2 -8
  37. package/lib/sharing/ProvideSharedPlugin.js +4 -4
  38. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +1 -2
  39. package/package.json +3 -3
  40. package/schemas/WebpackOptions.check.js +1 -1
  41. package/schemas/WebpackOptions.json +11 -9
  42. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  43. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  44. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  45. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  46. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  47. package/types.d.ts +355 -144
@@ -61,6 +61,7 @@ const parseJson = require("./util/parseJson");
61
61
  /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
62
62
  /** @typedef {import("../declarations/WebpackOptions").NoParse} NoParse */
63
63
  /** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
64
+ /** @typedef {import("./Dependency")} Dependency */
64
65
  /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
65
66
  /** @typedef {import("./Generator")} Generator */
66
67
  /** @typedef {import("./Generator").GenerateErrorFn} GenerateErrorFn */
@@ -85,8 +86,13 @@ const parseJson = require("./util/parseJson");
85
86
  /** @typedef {import("./Module").UnsafeCacheData} UnsafeCacheData */
86
87
  /** @typedef {import("./ModuleGraph")} ModuleGraph */
87
88
  /** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
89
+ /** @typedef {Iterator<SideEffectsWalk, ConnectionState, ConnectionState>} SideEffectsWalk */
88
90
  /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
89
91
  /** @typedef {import("./NormalModuleFactory").NormalModuleTypes} NormalModuleTypes */
92
+ /** @typedef {import("./NormalModuleFactory").ParserByType} ParserByType */
93
+ /** @typedef {import("./NormalModuleFactory").ParserOptionsByType} ParserOptionsByType */
94
+ /** @typedef {import("./NormalModuleFactory").GeneratorByType} GeneratorByType */
95
+ /** @typedef {import("./NormalModuleFactory").GeneratorOptionsByType} GeneratorOptionsByType */
90
96
  /** @typedef {import("./NormalModuleFactory").ResourceSchemeData} ResourceSchemeData */
91
97
  /** @typedef {import("./Parser")} Parser */
92
98
  /** @typedef {import("./Parser").PreparsedAst} PreparsedAst */
@@ -126,6 +132,87 @@ const getExtractSourceMap = memoize(() => require("./util/extractSourceMap"));
126
132
 
127
133
  const getValidate = memoize(() => require("schema-utils").validate);
128
134
 
135
+ const getHarmonyImportSideEffectDependency = memoize(() =>
136
+ require("./dependencies/HarmonyImportSideEffectDependency")
137
+ );
138
+
139
+ /**
140
+ * @param {NormalModule} mod the module
141
+ * @param {ModuleGraph} moduleGraph the module graph
142
+ * @param {Dependency} dep the dep that triggered the bailout
143
+ */
144
+ const recordSideEffectsBailout = (mod, moduleGraph, dep) => {
145
+ if (mod._addedSideEffectsBailout === undefined) {
146
+ mod._addedSideEffectsBailout = new WeakSet();
147
+ } else if (mod._addedSideEffectsBailout.has(moduleGraph)) {
148
+ return;
149
+ }
150
+ mod._addedSideEffectsBailout.add(moduleGraph);
151
+ moduleGraph
152
+ .getOptimizationBailout(mod)
153
+ .push(
154
+ () =>
155
+ `Dependency (${dep.type}) with side effects at ${formatLocation(dep.loc)}`
156
+ );
157
+ };
158
+
159
+ /**
160
+ * Generator form of `getSideEffectsConnectionState` — descends through
161
+ * `HarmonyImportSideEffectDependency` via `yield` so the trampoline in
162
+ * `getSideEffectsConnectionState` can drive the walk iteratively (#20986).
163
+ * @param {NormalModule} mod the module being evaluated
164
+ * @param {ModuleGraph} moduleGraph the module graph
165
+ * @returns {SideEffectsWalk} the generator
166
+ */
167
+ function* walkSideEffects(mod, moduleGraph) {
168
+ if (mod.factoryMeta !== undefined) {
169
+ if (mod.factoryMeta.sideEffectFree) return false;
170
+ if (mod.factoryMeta.sideEffectFree === false) return true;
171
+ }
172
+ if (!(mod.buildMeta !== undefined && mod.buildMeta.sideEffectFree)) {
173
+ return true;
174
+ }
175
+ if (mod._isEvaluatingSideEffects) {
176
+ return ModuleGraphConnection.CIRCULAR_CONNECTION;
177
+ }
178
+
179
+ const SideEffectDep = getHarmonyImportSideEffectDependency();
180
+ mod._isEvaluatingSideEffects = true;
181
+ /** @type {ConnectionState} */
182
+ let current = false;
183
+
184
+ for (const dep of mod.dependencies) {
185
+ /** @type {ConnectionState} */
186
+ let state;
187
+ if (dep instanceof SideEffectDep) {
188
+ const refModule = moduleGraph.getModule(dep);
189
+ if (!refModule) {
190
+ state = true;
191
+ } else if (refModule instanceof NormalModule) {
192
+ state = yield walkSideEffects(refModule, moduleGraph);
193
+ } else {
194
+ state = refModule.getSideEffectsConnectionState(moduleGraph);
195
+ }
196
+ } else {
197
+ state = dep.getModuleEvaluationSideEffectsState(moduleGraph);
198
+ }
199
+
200
+ if (state === true) {
201
+ recordSideEffectsBailout(mod, moduleGraph, dep);
202
+ mod._isEvaluatingSideEffects = false;
203
+ return true;
204
+ }
205
+ if (state !== ModuleGraphConnection.CIRCULAR_CONNECTION) {
206
+ current = ModuleGraphConnection.addConnectionStates(current, state);
207
+ }
208
+ }
209
+
210
+ mod._isEvaluatingSideEffects = false;
211
+ // When caching is implemented here, make sure to not cache when
212
+ // at least one circular connection was folded into `current`.
213
+ return current;
214
+ }
215
+
129
216
  const ABSOLUTE_PATH_REGEX = /^(?:[a-z]:\\|\\\\|\/)/i;
130
217
 
131
218
  /**
@@ -229,9 +316,10 @@ const asBuffer = (input) => {
229
316
  */
230
317
 
231
318
  /**
319
+ * @template {NormalModuleTypes | ""} [T=NormalModuleTypes | ""]
232
320
  * @typedef {object} NormalModuleCreateData
233
321
  * @property {string=} layer an optional layer in which the module is
234
- * @property {NormalModuleTypes | ""} type module type. When deserializing, this is set to an empty string "".
322
+ * @property {T} type module type. When deserializing, this is set to an empty string "".
235
323
  * @property {string} request request string
236
324
  * @property {string} userRequest request intended by user (without loaders from config)
237
325
  * @property {string} rawRequest request without resolving
@@ -240,10 +328,10 @@ const asBuffer = (input) => {
240
328
  * @property {(ResourceSchemeData & Partial<ResolveRequest>)=} resourceResolveData resource resolve data
241
329
  * @property {string} context context directory for resolving
242
330
  * @property {string=} matchResource path + query of the matched resource (virtual)
243
- * @property {Parser} parser the parser used
244
- * @property {ParserOptions=} parserOptions the options of the parser used
245
- * @property {Generator} generator the generator used
246
- * @property {GeneratorOptions=} generatorOptions the options of the generator used
331
+ * @property {ParserByType[T]} parser the parser used
332
+ * @property {ParserOptionsByType[T]=} parserOptions the options of the parser used
333
+ * @property {GeneratorByType[T]} generator the generator used
334
+ * @property {GeneratorOptionsByType[T]=} generatorOptions the options of the generator used
247
335
  * @property {ResolveOptions=} resolveOptions options used for resolving requests from this module
248
336
  * @property {boolean} extractSourceMap enable/disable extracting source map
249
337
  */
@@ -405,12 +493,10 @@ class NormalModule extends Module {
405
493
  */
406
494
  this._forceBuild = true;
407
495
  /**
408
- * @private
409
496
  * @type {boolean}
410
497
  */
411
498
  this._isEvaluatingSideEffects = false;
412
499
  /**
413
- * @private
414
500
  * @type {WeakSet<ModuleGraph> | undefined}
415
501
  */
416
502
  this._addedSideEffectsBailout = undefined;
@@ -1453,47 +1539,21 @@ class NormalModule extends Module {
1453
1539
  * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only
1454
1540
  */
1455
1541
  getSideEffectsConnectionState(moduleGraph) {
1456
- if (this.factoryMeta !== undefined) {
1457
- if (this.factoryMeta.sideEffectFree) return false;
1458
- if (this.factoryMeta.sideEffectFree === false) return true;
1459
- }
1460
- if (this.buildMeta !== undefined && this.buildMeta.sideEffectFree) {
1461
- if (this._isEvaluatingSideEffects) {
1462
- return ModuleGraphConnection.CIRCULAR_CONNECTION;
1463
- }
1464
- this._isEvaluatingSideEffects = true;
1465
- /** @type {ConnectionState} */
1466
- let current = false;
1467
- for (const dep of this.dependencies) {
1468
- const state = dep.getModuleEvaluationSideEffectsState(moduleGraph);
1469
- if (state === true) {
1470
- if (
1471
- this._addedSideEffectsBailout === undefined
1472
- ? ((this._addedSideEffectsBailout = new WeakSet()), true)
1473
- : !this._addedSideEffectsBailout.has(moduleGraph)
1474
- ) {
1475
- this._addedSideEffectsBailout.add(moduleGraph);
1476
- moduleGraph
1477
- .getOptimizationBailout(this)
1478
- .push(
1479
- () =>
1480
- `Dependency (${
1481
- dep.type
1482
- }) with side effects at ${formatLocation(dep.loc)}`
1483
- );
1484
- }
1485
- this._isEvaluatingSideEffects = false;
1486
- return true;
1487
- } else if (state !== ModuleGraphConnection.CIRCULAR_CONNECTION) {
1488
- current = ModuleGraphConnection.addConnectionStates(current, state);
1489
- }
1542
+ // Trampoline `walkSideEffects` so the descent doesn't consume the
1543
+ // call stack (#20986).
1544
+ const stack = [walkSideEffects(this, moduleGraph)];
1545
+ /** @type {ConnectionState} */
1546
+ let r = false;
1547
+ while (stack.length > 0) {
1548
+ const step = stack[stack.length - 1].next(r);
1549
+ if (step.done) {
1550
+ stack.pop();
1551
+ r = step.value;
1552
+ } else {
1553
+ stack.push(step.value);
1490
1554
  }
1491
- this._isEvaluatingSideEffects = false;
1492
- // When caching is implemented here, make sure to not cache when
1493
- // at least one circular connection was in the loop above
1494
- return current;
1495
1555
  }
1496
- return true;
1556
+ return r;
1497
1557
  }
1498
1558
 
1499
1559
  /**
@@ -69,7 +69,7 @@ const {
69
69
  */
70
70
 
71
71
  /** @typedef {Pick<RuleSetRule, "type" | "sideEffects" | "parser" | "generator" | "resolve" | "layer" | "extractSourceMap">} ModuleSettings */
72
- /** @typedef {Partial<NormalModuleCreateData & { settings: ModuleSettings }>} CreateData */
72
+ /** @typedef {NormalModuleCreateData & { settings: ModuleSettings }} CreateData */
73
73
 
74
74
  /**
75
75
  * Defines the resolve data type used by this module.
@@ -82,7 +82,7 @@ const {
82
82
  * @property {ImportAttributes=} attributes
83
83
  * @property {ModuleDependency[]} dependencies
84
84
  * @property {string} dependencyType
85
- * @property {CreateData} createData
85
+ * @property {Partial<CreateData>} createData
86
86
  * @property {FileSystemDependencies} fileDependencies
87
87
  * @property {FileSystemDependencies} missingDependencies
88
88
  * @property {FileSystemDependencies} contextDependencies
@@ -324,7 +324,7 @@ const ruleSetCompiler = new RuleSetCompiler([
324
324
  /** @typedef {import("./html/HtmlParser")} HtmlParser */
325
325
  /** @typedef {import("../declarations/WebpackOptions").EmptyParserOptions} HtmlParserOptions */
326
326
  /** @typedef {import("./html/HtmlGenerator")} HtmlGenerator */
327
- /** @typedef {import("../declarations/WebpackOptions").EmptyGeneratorOptions} HtmlGeneratorOptions */
327
+ /** @typedef {import("../declarations/WebpackOptions").HtmlGeneratorOptions} HtmlGeneratorOptions */
328
328
 
329
329
  /* eslint-disable jsdoc/type-formatting */
330
330
  /**
@@ -339,8 +339,8 @@ const ruleSetCompiler = new RuleSetCompiler([
339
339
  * [ASSET_MODULE_TYPE_RESOURCE, AssetParser, EmptyParserOptions, AssetGenerator, AssetGeneratorOptions],
340
340
  * [ASSET_MODULE_TYPE_SOURCE, AssetSourceParser, EmptyParserOptions, AssetSourceGenerator, EmptyGeneratorOptions],
341
341
  * [ASSET_MODULE_TYPE_BYTES, AssetBytesParser, EmptyParserOptions, AssetBytesGenerator, EmptyGeneratorOptions],
342
- * [WEBASSEMBLY_MODULE_TYPE_ASYNC, AsyncWebAssemblyParser, EmptyParserOptions, Generator, EmptyParserOptions],
343
- * [WEBASSEMBLY_MODULE_TYPE_SYNC, WebAssemblyParser, EmptyParserOptions, Generator, EmptyParserOptions],
342
+ * [WEBASSEMBLY_MODULE_TYPE_ASYNC, AsyncWebAssemblyParser, EmptyParserOptions, Generator, EmptyGeneratorOptions],
343
+ * [WEBASSEMBLY_MODULE_TYPE_SYNC, WebAssemblyParser, EmptyParserOptions, Generator, EmptyGeneratorOptions],
344
344
  * [CSS_MODULE_TYPE, CssParser, CssParserOptions, CssGenerator, CssGeneratorOptions],
345
345
  * [CSS_MODULE_TYPE_AUTO, CssParser, CssModuleParserOptions, CssGenerator, CssModuleGeneratorOptions],
346
346
  * [CSS_MODULE_TYPE_MODULE, CssParser, CssModuleParserOptions, CssGenerator, CssModuleGeneratorOptions],
@@ -366,6 +366,18 @@ const ruleSetCompiler = new RuleSetCompiler([
366
366
  * @typedef {T extends [infer Head extends [string, ...unknown[]], ...infer Tail extends [string, ...unknown[]][]] ? Record<Head[0], SyncBailHook<ExtractTupleElements<Head, A>, R extends number ? Head[R] : R>> & RecordFactoryFromTuple<Tail, A, R> : unknown } RecordFactoryFromTuple
367
367
  */
368
368
 
369
+ /**
370
+ * Maps each tuple in `T` to a record from its `[0]` key to its `[I]` value.
371
+ * @template {unknown[]} T
372
+ * @template {number} I
373
+ * @typedef {T extends [infer Head extends [string, ...unknown[]], ...infer Tail extends [string, ...unknown[]][]] ? Record<Head[0], I extends keyof Head ? Head[I] : never> & TupleToTypeMap<Tail, I> : unknown } TupleToTypeMap
374
+ */
375
+
376
+ /** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 1>} ParserByType */
377
+ /** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 2>} ParserOptionsByType */
378
+ /** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 3>} GeneratorByType */
379
+ /** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 4>} GeneratorOptionsByType */
380
+
369
381
  class NormalModuleFactory extends ModuleFactory {
370
382
  /**
371
383
  * Creates an instance of NormalModuleFactory.
@@ -493,7 +505,9 @@ class NormalModuleFactory extends ModuleFactory {
493
505
  // Ignored
494
506
  if (result === false) return callback();
495
507
 
496
- const createData = resolveData.createData;
508
+ const createData =
509
+ /** @type {CreateData} */
510
+ (resolveData.createData);
497
511
 
498
512
  this.hooks.createModule.callAsync(
499
513
  createData,
@@ -506,18 +520,12 @@ class NormalModuleFactory extends ModuleFactory {
506
520
 
507
521
  // TODO webpack 6 make it required and move javascript/wasm/asset properties to own module
508
522
  createdModule = this.hooks.createModuleClass
509
- .for(
510
- /** @type {ModuleSettings} */
511
- (createData.settings).type
512
- )
523
+ .for(createData.settings.type)
513
524
  .call(createData, resolveData);
514
525
 
515
526
  if (!createdModule) {
516
527
  createdModule = /** @type {Module} */ (
517
- new NormalModule(
518
- /** @type {NormalModuleCreateData} */
519
- (createData)
520
- )
528
+ new NormalModule(createData)
521
529
  );
522
530
  }
523
531
  }
@@ -1405,9 +1413,10 @@ If changing the source code is not an option there is also a resolve options cal
1405
1413
 
1406
1414
  /**
1407
1415
  * Returns parser.
1408
- * @param {string} type type
1416
+ * @template {string} T
1417
+ * @param {T} type type
1409
1418
  * @param {ParserOptions} parserOptions parser options
1410
- * @returns {Parser} parser
1419
+ * @returns {ParserByType[T]} parser
1411
1420
  */
1412
1421
  getParser(type, parserOptions = EMPTY_PARSER_OPTIONS) {
1413
1422
  let cache = this.parserCache.get(type);
@@ -1424,14 +1433,15 @@ If changing the source code is not an option there is also a resolve options cal
1424
1433
  cache.set(parserOptions, parser);
1425
1434
  }
1426
1435
 
1427
- return parser;
1436
+ return /** @type {ParserByType[T]} */ (parser);
1428
1437
  }
1429
1438
 
1430
1439
  /**
1431
1440
  * Creates a parser from the provided type.
1432
- * @param {string} type type
1441
+ * @template {string} T
1442
+ * @param {T} type type
1433
1443
  * @param {ParserOptions} parserOptions parser options
1434
- * @returns {Parser} parser
1444
+ * @returns {ParserByType[T]} parser
1435
1445
  */
1436
1446
  createParser(type, parserOptions = {}) {
1437
1447
  parserOptions = mergeGlobalOptions(
@@ -1444,14 +1454,15 @@ If changing the source code is not an option there is also a resolve options cal
1444
1454
  throw new Error(`No parser registered for ${type}`);
1445
1455
  }
1446
1456
  this.hooks.parser.for(type).call(parser, parserOptions);
1447
- return parser;
1457
+ return /** @type {ParserByType[T]} */ (parser);
1448
1458
  }
1449
1459
 
1450
1460
  /**
1451
1461
  * Returns generator.
1452
- * @param {string} type type of generator
1462
+ * @template {string} T
1463
+ * @param {T} type type of generator
1453
1464
  * @param {GeneratorOptions} generatorOptions generator options
1454
- * @returns {Generator} generator
1465
+ * @returns {GeneratorByType[T]} generator
1455
1466
  */
1456
1467
  getGenerator(type, generatorOptions = EMPTY_GENERATOR_OPTIONS) {
1457
1468
  let cache = this.generatorCache.get(type);
@@ -1468,14 +1479,15 @@ If changing the source code is not an option there is also a resolve options cal
1468
1479
  cache.set(generatorOptions, generator);
1469
1480
  }
1470
1481
 
1471
- return generator;
1482
+ return /** @type {GeneratorByType[T]} */ (generator);
1472
1483
  }
1473
1484
 
1474
1485
  /**
1475
1486
  * Creates a generator.
1476
- * @param {string} type type of generator
1487
+ * @template {string} T
1488
+ * @param {T} type type of generator
1477
1489
  * @param {GeneratorOptions} generatorOptions generator options
1478
- * @returns {Generator} generator
1490
+ * @returns {GeneratorByType[T]} generator
1479
1491
  */
1480
1492
  createGenerator(type, generatorOptions = {}) {
1481
1493
  generatorOptions = mergeGlobalOptions(
@@ -1490,7 +1502,7 @@ If changing the source code is not an option there is also a resolve options cal
1490
1502
  throw new Error(`No generator registered for ${type}`);
1491
1503
  }
1492
1504
  this.hooks.generator.for(type).call(generator, generatorOptions);
1493
- return generator;
1505
+ return /** @type {GeneratorByType[T]} */ (generator);
1494
1506
  }
1495
1507
 
1496
1508
  /**
@@ -281,7 +281,7 @@ class RuntimePlugin {
281
281
 
282
282
  if (
283
283
  typeof publicPath !== "string" ||
284
- /\[(?:full)?hash\]/.test(publicPath)
284
+ FULLHASH_REGEXP.test(publicPath)
285
285
  ) {
286
286
  module.fullHash = true;
287
287
  }