webpack 5.105.3 → 5.105.4

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.
@@ -4019,7 +4019,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
4019
4019
  * @param {string | ChunkGroupOptions} groupOptions options for the chunk group
4020
4020
  * @param {Module=} module the module the references the chunk group
4021
4021
  * @param {DependencyLocation=} loc the location from with the chunk group is referenced (inside of module)
4022
- * @param {string=} request the request from which the the chunk group is referenced
4022
+ * @param {string=} request the request from which the chunk group is referenced
4023
4023
  * @returns {ChunkGroup} the new or existing chunk group
4024
4024
  */
4025
4025
  addChunkInGroup(groupOptions, module, loc, request) {
@@ -4067,7 +4067,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
4067
4067
  * @param {EntryOptions} options options for the entrypoint
4068
4068
  * @param {Module} module the module the references the chunk group
4069
4069
  * @param {DependencyLocation} loc the location from with the chunk group is referenced (inside of module)
4070
- * @param {string} request the request from which the the chunk group is referenced
4070
+ * @param {string} request the request from which the chunk group is referenced
4071
4071
  * @returns {Entrypoint} the new or existing entrypoint
4072
4072
  */
4073
4073
  addAsyncEntrypoint(options, module, loc, request) {
package/lib/Module.js CHANGED
@@ -80,6 +80,8 @@ const makeSerializable = require("./util/makeSerializable");
80
80
  /** @typedef {KnownSourceType | string} SourceType */
81
81
  /** @typedef {ReadonlySet<SourceType>} SourceTypes */
82
82
 
83
+ /** @typedef {ReadonlySet<typeof JAVASCRIPT_TYPE | string>} BasicSourceTypes */
84
+
83
85
  // TODO webpack 6: compilation will be required in CodeGenerationContext
84
86
  /**
85
87
  * @typedef {object} CodeGenerationContext
@@ -966,6 +968,19 @@ class Module extends DependenciesBlock {
966
968
  return JAVASCRIPT_TYPES;
967
969
  }
968
970
 
971
+ /**
972
+ * Basic source types are high-level categories like javascript, css, webassembly, etc.
973
+ * We only have built-in knowledge about the javascript basic type here; other basic types may be
974
+ * added or changed over time by generators and do not need to be handled or detected here.
975
+ *
976
+ * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
977
+ * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
978
+ * @returns {BasicSourceTypes} types available (do not mutate)
979
+ */
980
+ getSourceBasicTypes() {
981
+ return this.getSourceTypes();
982
+ }
983
+
969
984
  /**
970
985
  * @abstract
971
986
  * @deprecated Use codeGeneration() instead
package/lib/MultiStats.js CHANGED
@@ -8,6 +8,7 @@
8
8
  const identifierUtils = require("./util/identifier");
9
9
 
10
10
  /** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
11
+ /** @typedef {import("../declarations/WebpackOptions").StatsValue} StatsValue */
11
12
  /** @typedef {import("./Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
12
13
  /** @typedef {import("./Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
13
14
  /** @typedef {import("./Stats")} Stats */
@@ -25,8 +26,7 @@ const indent = (str, prefix) => {
25
26
  return prefix + rem;
26
27
  };
27
28
 
28
- /** @typedef {undefined | string | boolean | StatsOptions} ChildrenStatsOptions */
29
- /** @typedef {Omit<StatsOptions, "children"> & { children?: ChildrenStatsOptions | ChildrenStatsOptions[] }} MultiStatsOptions */
29
+ /** @typedef {StatsOptions} MultiStatsOptions */
30
30
  /** @typedef {{ version: boolean, hash: boolean, errorsCount: boolean, warningsCount: boolean, errors: boolean, warnings: boolean, children: NormalizedStatsOptions[] }} ChildOptions */
31
31
 
32
32
  class MultiStats {
@@ -56,7 +56,7 @@ class MultiStats {
56
56
  }
57
57
 
58
58
  /**
59
- * @param {undefined | string | boolean | MultiStatsOptions} options stats options
59
+ * @param {undefined | StatsValue} options stats options
60
60
  * @param {CreateStatsOptionsContext} context context
61
61
  * @returns {ChildOptions} context context
62
62
  */
@@ -109,7 +109,7 @@ class MultiStats {
109
109
  }
110
110
 
111
111
  /**
112
- * @param {(string | boolean | MultiStatsOptions)=} options stats options
112
+ * @param {StatsValue=} options stats options
113
113
  * @returns {StatsCompilation} json output
114
114
  */
115
115
  toJson(options) {
@@ -184,7 +184,7 @@ class MultiStats {
184
184
  }
185
185
 
186
186
  /**
187
- * @param {(string | boolean | MultiStatsOptions)=} options stats options
187
+ * @param {StatsValue=} options stats options
188
188
  * @returns {string} string output
189
189
  */
190
190
  toString(options) {
@@ -8,7 +8,10 @@
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const OriginalSource = require("webpack-sources").OriginalSource;
10
10
  const Module = require("./Module");
11
- const { RUNTIME_TYPES } = require("./ModuleSourceTypeConstants");
11
+ const {
12
+ JAVASCRIPT_TYPES,
13
+ RUNTIME_TYPES
14
+ } = require("./ModuleSourceTypeConstants");
12
15
  const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
13
16
 
14
17
  /** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
@@ -29,6 +32,7 @@ const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
29
32
  /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
30
33
  /** @typedef {import("./util/Hash")} Hash */
31
34
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
35
+ /** @typedef {import("./Module").BasicSourceTypes} BasicSourceTypes */
32
36
 
33
37
  class RuntimeModule extends Module {
34
38
  /**
@@ -138,6 +142,19 @@ class RuntimeModule extends Module {
138
142
  return RUNTIME_TYPES;
139
143
  }
140
144
 
145
+ /**
146
+ * Basic source types are high-level categories like javascript, css, webassembly, etc.
147
+ * We only have built-in knowledge about the javascript basic type here; other basic types may be
148
+ * added or changed over time by generators and do not need to be handled or detected here.
149
+ *
150
+ * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
151
+ * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
152
+ * @returns {BasicSourceTypes} types available (do not mutate)
153
+ */
154
+ getSourceBasicTypes() {
155
+ return JAVASCRIPT_TYPES;
156
+ }
157
+
141
158
  /**
142
159
  * @param {CodeGenerationContext} context context for code generation
143
160
  * @returns {CodeGenerationResult} result
package/lib/Stats.js CHANGED
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  /** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
9
+ /** @typedef {import("../declarations/WebpackOptions").StatsValue} StatsValue */
9
10
  /** @typedef {import("./Compilation")} Compilation */
10
11
  /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
11
12
 
@@ -50,7 +51,7 @@ class Stats {
50
51
  }
51
52
 
52
53
  /**
53
- * @param {(string | boolean | StatsOptions)=} options stats options
54
+ * @param {StatsValue=} options stats options
54
55
  * @returns {StatsCompilation} json output
55
56
  */
56
57
  toJson(options) {
@@ -66,7 +67,7 @@ class Stats {
66
67
  }
67
68
 
68
69
  /**
69
- * @param {(string | boolean | StatsOptions)=} options stats options
70
+ * @param {StatsValue=} options stats options
70
71
  * @returns {string} string output
71
72
  */
72
73
  toString(options) {
@@ -7,7 +7,10 @@
7
7
 
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const Module = require("../Module");
10
- const { REMOTE_AND_SHARE_INIT_TYPES } = require("../ModuleSourceTypeConstants");
10
+ const {
11
+ JAVASCRIPT_TYPES,
12
+ REMOTE_AND_SHARE_INIT_TYPES
13
+ } = require("../ModuleSourceTypeConstants");
11
14
  const { WEBPACK_MODULE_TYPE_REMOTE } = require("../ModuleTypeConstants");
12
15
  const RuntimeGlobals = require("../RuntimeGlobals");
13
16
  const makeSerializable = require("../util/makeSerializable");
@@ -34,6 +37,7 @@ const RemoteToExternalDependency = require("./RemoteToExternalDependency");
34
37
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
35
38
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
36
39
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
40
+ /** @typedef {import("../Module").BasicSourceTypes} BasicSourceTypes */
37
41
 
38
42
  const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
39
43
 
@@ -137,6 +141,19 @@ class RemoteModule extends Module {
137
141
  return REMOTE_AND_SHARE_INIT_TYPES;
138
142
  }
139
143
 
144
+ /**
145
+ * Basic source types are high-level categories like javascript, css, webassembly, etc.
146
+ * We only have built-in knowledge about the javascript basic type here; other basic types may be
147
+ * added or changed over time by generators and do not need to be handled or detected here.
148
+ *
149
+ * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
150
+ * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
151
+ * @returns {BasicSourceTypes} types available (do not mutate)
152
+ */
153
+ getSourceBasicTypes() {
154
+ return JAVASCRIPT_TYPES;
155
+ }
156
+
140
157
  /**
141
158
  * @param {ModuleGraph} moduleGraph the module graph
142
159
  * @param {boolean | undefined} strict the importing module is strict
@@ -19,6 +19,7 @@ const {
19
19
  const RuntimeGlobals = require("../RuntimeGlobals");
20
20
  const Template = require("../Template");
21
21
  const CssImportDependency = require("../dependencies/CssImportDependency");
22
+ const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
22
23
  const { getUndoPath } = require("../util/identifier");
23
24
  const memoize = require("../util/memoize");
24
25
 
@@ -469,6 +470,7 @@ class CssGenerator extends Generator {
469
470
  getTypes(module) {
470
471
  const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType;
471
472
  const sourceTypes = new Set();
473
+
472
474
  const connections = this._moduleGraph.getIncomingConnections(module);
473
475
 
474
476
  for (const connection of connections) {
@@ -478,9 +480,17 @@ class CssGenerator extends Generator {
478
480
  ) {
479
481
  continue;
480
482
  }
483
+
484
+ // when no hmr required, css module js output contains no sideEffects at all
485
+ // js sideeffect connection doesn't require js type output
486
+ if (connection.dependency instanceof HarmonyImportSideEffectDependency) {
487
+ continue;
488
+ }
489
+
481
490
  if (!connection.originModule) {
482
491
  continue;
483
492
  }
493
+
484
494
  if (connection.originModule.type.split("/")[0] !== CSS_TYPE) {
485
495
  sourceTypes.add(JAVASCRIPT_TYPE);
486
496
  } else {
@@ -328,6 +328,17 @@ class CreateRequireParserPlugin {
328
328
  return processResolve(expr, false);
329
329
  }
330
330
  });
331
+ parser.hooks.expression
332
+ .for(createRequireSpecifierTag)
333
+ .tap(PLUGIN_NAME, (expr) => {
334
+ const clearDep = new ConstDependency(
335
+ "/* createRequire */ undefined",
336
+ /** @type {Range} */ (expr.range)
337
+ );
338
+ clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
339
+ parser.state.module.addPresentationalDependency(clearDep);
340
+ return true;
341
+ });
331
342
  parser.hooks.call
332
343
  .for(createRequireSpecifierTag)
333
344
  .tap(PLUGIN_NAME, (expr) => {
@@ -27,6 +27,7 @@ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDepend
27
27
  const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
28
28
 
29
29
  /** @typedef {import("estree").Expression} Expression */
30
+ /** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
30
31
  /** @typedef {import("estree").Identifier} Identifier */
31
32
  /** @typedef {import("estree").MemberExpression} MemberExpression */
32
33
  /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
@@ -66,17 +67,44 @@ const harmonySpecifierGuardTag = Symbol("harmony import guard");
66
67
 
67
68
  const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
68
69
 
69
- /** @type {(members: Members) => string} */
70
- const getMembersKey = (members) => members.join(".");
71
-
72
70
  /**
73
- * Strip the root binding name if needed
74
- * @param {HarmonySettings} settings settings
75
- * @param {Ids} ids ids
76
- * @returns {Ids} ids for presence check
71
+ * @param {JavascriptParser} parser the parser
72
+ * @param {PrivateIdentifier | Expression} left left expression
73
+ * @param {Expression} right right expression
74
+ * @returns {{ leftPart: string, members: Members, settings: HarmonySettings } | undefined} info
77
75
  */
78
- const getIdsForPresence = (settings, ids) =>
79
- settings.ids.length ? ids.slice(1) : ids;
76
+ const getInOperatorHarmonyImportInfo = (parser, left, right) => {
77
+ const leftPartEvaluated = parser.evaluateExpression(left);
78
+ if (leftPartEvaluated.couldHaveSideEffects()) return;
79
+ /** @type {string | undefined} */
80
+ const leftPart = leftPartEvaluated.asString();
81
+ if (!leftPart) return;
82
+
83
+ const rightPart = parser.evaluateExpression(right);
84
+ if (!rightPart.isIdentifier()) return;
85
+
86
+ const rootInfo = rightPart.rootInfo;
87
+ const root =
88
+ typeof rootInfo === "string"
89
+ ? rootInfo
90
+ : rootInfo instanceof VariableInfo
91
+ ? rootInfo.name
92
+ : undefined;
93
+ if (!root) return;
94
+
95
+ const settings = /** @type {HarmonySettings | undefined} */ (
96
+ parser.getTagData(root, harmonySpecifierTag)
97
+ );
98
+ if (!settings) {
99
+ return;
100
+ }
101
+
102
+ return {
103
+ leftPart,
104
+ members: /** @type {(() => Members)} */ (rightPart.getMembers)(),
105
+ settings
106
+ };
107
+ };
80
108
 
81
109
  module.exports = class HarmonyImportDependencyParserPlugin {
82
110
  /**
@@ -94,10 +122,14 @@ module.exports = class HarmonyImportDependencyParserPlugin {
94
122
 
95
123
  /**
96
124
  * @param {JavascriptParser} parser the parser
125
+ * @param {HarmonySettings} settings settings
97
126
  * @param {Ids} ids ids
98
127
  * @returns {ExportPresenceMode} exportPresenceMode
99
128
  */
100
- getExportPresenceMode(parser, ids) {
129
+ getExportPresenceMode(parser, settings, ids) {
130
+ // Guards only apply to namespace imports
131
+ if (settings.ids.length) return this.exportPresenceMode;
132
+
101
133
  const harmonySettings = /** @type {HarmonySettings=} */ (
102
134
  parser.currentTagData
103
135
  );
@@ -106,9 +138,12 @@ module.exports = class HarmonyImportDependencyParserPlugin {
106
138
  const data = /** @type {HarmonySpecifierGuards=} */ (
107
139
  parser.getTagData(harmonySettings.name, harmonySpecifierGuardTag)
108
140
  );
109
- return data && data.guards && data.guards.has(getMembersKey(ids))
110
- ? ExportPresenceModes.NONE
111
- : this.exportPresenceMode;
141
+
142
+ if (data && data.guards && data.guards.has(ids[0])) {
143
+ return ExportPresenceModes.NONE;
144
+ }
145
+
146
+ return this.exportPresenceMode;
112
147
  }
113
148
 
114
149
  /**
@@ -195,31 +230,14 @@ module.exports = class HarmonyImportDependencyParserPlugin {
195
230
  );
196
231
  parser.hooks.binaryExpression.tap(PLUGIN_NAME, (expression) => {
197
232
  if (expression.operator !== "in") return;
233
+ const info = getInOperatorHarmonyImportInfo(
234
+ parser,
235
+ expression.left,
236
+ expression.right
237
+ );
238
+ if (!info) return;
198
239
 
199
- const leftPartEvaluated = parser.evaluateExpression(expression.left);
200
- if (leftPartEvaluated.couldHaveSideEffects()) return;
201
- /** @type {string | undefined} */
202
- const leftPart = leftPartEvaluated.asString();
203
- if (!leftPart) return;
204
-
205
- const rightPart = parser.evaluateExpression(expression.right);
206
- if (!rightPart.isIdentifier()) return;
207
-
208
- const rootInfo = rightPart.rootInfo;
209
- if (
210
- typeof rootInfo === "string" ||
211
- !rootInfo ||
212
- !rootInfo.tagInfo ||
213
- rootInfo.tagInfo.tag !== harmonySpecifierTag
214
- ) {
215
- return;
216
- }
217
- const settings =
218
- /** @type {HarmonySettings} */
219
- (rootInfo.tagInfo.data);
220
- const members =
221
- /** @type {(() => Members)} */
222
- (rightPart.getMembers)();
240
+ const { leftPart, members, settings } = info;
223
241
  const dep = new HarmonyEvaluatedImportSpecifierDependency(
224
242
  settings.source,
225
243
  settings.sourceOrder,
@@ -264,10 +282,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
264
282
  settings.name,
265
283
  /** @type {Range} */
266
284
  (expr.range),
267
- this.getExportPresenceMode(
268
- parser,
269
- getIdsForPresence(settings, settings.ids)
270
- ),
285
+ this.exportPresenceMode,
271
286
  settings.phase,
272
287
  settings.attributes,
273
288
  []
@@ -317,10 +332,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
317
332
  settings.name,
318
333
  /** @type {Range} */
319
334
  (expr.range),
320
- this.getExportPresenceMode(
321
- parser,
322
- getIdsForPresence(settings, ids)
323
- ),
335
+ this.getExportPresenceMode(parser, settings, ids),
324
336
  settings.phase,
325
337
  settings.attributes,
326
338
  ranges
@@ -370,10 +382,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
370
382
  ids,
371
383
  settings.name,
372
384
  /** @type {Range} */ (expr.range),
373
- this.getExportPresenceMode(
374
- parser,
375
- getIdsForPresence(settings, ids)
376
- ),
385
+ this.getExportPresenceMode(parser, settings, ids),
377
386
  settings.phase,
378
387
  settings.attributes,
379
388
  ranges
@@ -441,160 +450,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
441
450
  }
442
451
  });
443
452
 
444
- /**
445
- * @param {Expression} expression expression
446
- * @returns {{ root: string, members: Members } | undefined} info
447
- */
448
- const getHarmonyImportInfo = (expression) => {
449
- const nameInfo = parser.getNameForExpression(expression);
450
- if (!nameInfo) return;
451
-
452
- const rootInfo = nameInfo.rootInfo;
453
- const root =
454
- typeof rootInfo === "string"
455
- ? rootInfo
456
- : rootInfo instanceof VariableInfo
457
- ? rootInfo.name
458
- : undefined;
459
- if (!root) return;
460
- if (!parser.getTagData(root, harmonySpecifierTag)) return;
461
- return { root, members: nameInfo.getMembers() };
462
- };
463
-
464
- /**
465
- * @param {Guards} guards guards
466
- * @param {string} root root name
467
- * @param {Members} members members
468
- */
469
- const addToGuards = (guards, root, members) => {
470
- const membersKey = getMembersKey(members);
471
- const guardedMembers = guards.get(root);
472
- if (guardedMembers) {
473
- guardedMembers.add(membersKey);
474
- return;
475
- }
476
-
477
- guards.set(
478
- root,
479
- // Adding `foo.bar` implies guarding `foo` as well
480
- membersKey === "" ? new Set([""]) : new Set([membersKey, ""])
481
- );
482
- };
483
-
484
- /**
485
- * @param {Expression} expression expression
486
- * @param {Guards} guards guards
487
- * @param {boolean} needTruthy need to be truthy
488
- */
489
- const collect = (expression, guards, needTruthy) => {
490
- // !foo
491
- if (
492
- expression.type === "UnaryExpression" &&
493
- expression.operator === "!"
494
- ) {
495
- collect(expression.argument, guards, !needTruthy);
496
- return;
497
- } else if (expression.type === "LogicalExpression" && needTruthy) {
498
- // foo && bar
499
- if (expression.operator === "&&") {
500
- collect(expression.left, guards, true);
501
- collect(expression.right, guards, true);
502
- }
503
- // falsy || foo
504
- else if (expression.operator === "||") {
505
- const leftEvaluation = parser.evaluateExpression(expression.left);
506
- const leftBool = leftEvaluation.asBool();
507
- if (leftBool === false) {
508
- collect(expression.right, guards, true);
509
- }
510
- }
511
- // nullish ?? foo
512
- else if (expression.operator === "??") {
513
- const leftEvaluation = parser.evaluateExpression(expression.left);
514
- const leftNullish = leftEvaluation.asNullish();
515
- if (leftNullish === true) {
516
- collect(expression.right, guards, true);
517
- }
518
- }
519
- return;
520
- }
521
- if (!needTruthy) return;
522
-
523
- /**
524
- * @param {Expression} targetExpression expression
525
- * @returns {boolean} is added
526
- */
527
- const addGuardForExpression = (targetExpression) => {
528
- const info = getHarmonyImportInfo(targetExpression);
529
- if (!info) return false;
530
- addToGuards(guards, info.root, info.members);
531
- return true;
532
- };
533
-
534
- /**
535
- * @param {Expression} left left expression
536
- * @param {Expression} right right expression
537
- * @param {(evaluation: ReturnType<JavascriptParser["evaluateExpression"]>) => boolean} matcher matcher
538
- * @returns {boolean} is added
539
- */
540
- const addGuardForNullishCompare = (left, right, matcher) => {
541
- const leftEval = parser.evaluateExpression(left);
542
- if (leftEval && matcher(leftEval)) {
543
- return addGuardForExpression(right);
544
- }
545
- const rightEval = parser.evaluateExpression(right);
546
- if (rightEval && matcher(rightEval)) {
547
- return addGuardForExpression(/** @type {Expression} */ (left));
548
- }
549
- return false;
550
- };
551
-
552
- if (expression.type === "BinaryExpression") {
553
- // "bar" in foo
554
- if (expression.operator === "in") {
555
- const leftEvaluation = parser.evaluateExpression(expression.left);
556
- if (leftEvaluation.couldHaveSideEffects()) return;
557
- const propertyName = leftEvaluation.asString();
558
- if (!propertyName) return;
559
- parser.evaluateExpression(expression.right);
560
- const info = getHarmonyImportInfo(expression.right);
561
- if (!info) return;
562
-
563
- if (info.members.length) {
564
- for (const member of info.members) {
565
- addToGuards(guards, info.root, [member]);
566
- }
567
- }
568
- addToGuards(guards, info.root, [...info.members, propertyName]);
569
- return;
570
- }
571
- // foo !== undefined
572
- else if (
573
- expression.operator === "!==" &&
574
- addGuardForNullishCompare(
575
- /** @type {Expression} */ (expression.left),
576
- expression.right,
577
- (evaluation) => evaluation.isUndefined()
578
- )
579
- ) {
580
- return;
581
- }
582
- // foo != undefined
583
- // foo != null
584
- else if (
585
- expression.operator === "!=" &&
586
- addGuardForNullishCompare(
587
- /** @type {Expression} */ (expression.left),
588
- expression.right,
589
- (evaluation) => Boolean(evaluation.asNullish())
590
- )
591
- ) {
592
- return;
593
- }
594
- }
595
- addGuardForExpression(expression);
596
- };
597
-
598
453
  /**
599
454
  * @param {Guards} guards guards
600
455
  * @param {() => void} walk walk callback
@@ -645,7 +500,68 @@ module.exports = class HarmonyImportDependencyParserPlugin {
645
500
  if (parser.scope.isAsmJs) return;
646
501
  /** @type {Guards} */
647
502
  const guards = new Map();
648
- collect(expression, guards, true);
503
+
504
+ /**
505
+ * @param {Expression} expression expression
506
+ * @param {boolean} needTruthy need to be truthy
507
+ */
508
+ const collect = (expression, needTruthy) => {
509
+ if (
510
+ expression.type === "UnaryExpression" &&
511
+ expression.operator === "!"
512
+ ) {
513
+ collect(expression.argument, !needTruthy);
514
+ return;
515
+ } else if (expression.type === "LogicalExpression" && needTruthy) {
516
+ if (expression.operator === "&&") {
517
+ collect(expression.left, true);
518
+ collect(expression.right, true);
519
+ } else if (expression.operator === "||") {
520
+ const leftEvaluation = parser.evaluateExpression(expression.left);
521
+ const leftBool = leftEvaluation.asBool();
522
+ if (leftBool === false) {
523
+ collect(expression.right, true);
524
+ }
525
+ } else if (expression.operator === "??") {
526
+ const leftEvaluation = parser.evaluateExpression(expression.left);
527
+ const leftNullish = leftEvaluation.asNullish();
528
+ if (leftNullish === true) {
529
+ collect(expression.right, true);
530
+ }
531
+ }
532
+ return;
533
+ }
534
+ if (!needTruthy) return;
535
+
536
+ // Direct `"x" in ns` guards
537
+ if (
538
+ expression.type === "BinaryExpression" &&
539
+ expression.operator === "in"
540
+ ) {
541
+ if (expression.right.type !== "Identifier") {
542
+ return;
543
+ }
544
+ const info = getInOperatorHarmonyImportInfo(
545
+ parser,
546
+ expression.left,
547
+ expression.right
548
+ );
549
+ if (!info) return;
550
+
551
+ const { settings, leftPart, members } = info;
552
+ // Only direct namespace guards
553
+ if (members.length > 0) return;
554
+ const guarded = guards.get(settings.name);
555
+ if (guarded) {
556
+ guarded.add(leftPart);
557
+ return;
558
+ }
559
+
560
+ guards.set(settings.name, new Set([leftPart]));
561
+ }
562
+ };
563
+
564
+ collect(expression, true);
649
565
 
650
566
  if (guards.size === 0) return;
651
567
  return (walk) => {
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
8
9
  const makeSerializable = require("../util/makeSerializable");
9
10
  const HarmonyImportDependency = require("./HarmonyImportDependency");
10
11
 
@@ -72,11 +73,16 @@ HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDepend
72
73
  */
73
74
  apply(dependency, source, templateContext) {
74
75
  const { moduleGraph, concatenationScope } = templateContext;
75
- if (concatenationScope) {
76
- const module = /** @type {Module} */ (moduleGraph.getModule(dependency));
77
- if (concatenationScope.isModuleInScope(module)) {
78
- return;
79
- }
76
+
77
+ const module = /** @type {Module} */ (moduleGraph.getModule(dependency));
78
+
79
+ if (module && !module.getSourceBasicTypes().has(JAVASCRIPT_TYPE)) {
80
+ // no need to render import
81
+ return;
82
+ }
83
+
84
+ if (concatenationScope && concatenationScope.isModuleInScope(module)) {
85
+ return;
80
86
  }
81
87
  super.apply(dependency, source, templateContext);
82
88
  }
@@ -1004,6 +1004,9 @@ class ConcatenatedModule extends Module {
1004
1004
  if (!(connection.dependency instanceof HarmonyImportDependency)) {
1005
1005
  return false;
1006
1006
  }
1007
+ if (!connection.module.getSourceBasicTypes().has(JAVASCRIPT_TYPE)) {
1008
+ return false;
1009
+ }
1007
1010
  return (
1008
1011
  connection &&
1009
1012
  connection.resolvedOriginModule === module &&
@@ -466,7 +466,10 @@ class ModuleConcatenationPlugin {
466
466
  chunk,
467
467
  m
468
468
  );
469
- if (sourceTypes.size === 1) {
469
+ if (
470
+ sourceTypes.size === 1 &&
471
+ sourceTypes.has(JAVASCRIPT_TYPE)
472
+ ) {
470
473
  chunkGraph.disconnectChunkAndModule(chunk, m);
471
474
  } else {
472
475
  const newSourceTypes = new Set(sourceTypes);
@@ -8,7 +8,10 @@
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
10
10
  const Module = require("../Module");
11
- const { CONSUME_SHARED_TYPES } = require("../ModuleSourceTypeConstants");
11
+ const {
12
+ CONSUME_SHARED_TYPES,
13
+ JAVASCRIPT_TYPES
14
+ } = require("../ModuleSourceTypeConstants");
12
15
  const {
13
16
  WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE
14
17
  } = require("../ModuleTypeConstants");
@@ -41,6 +44,7 @@ const fallbackModuleCache = new WeakMap();
41
44
  /** @typedef {import("../util/Hash")} Hash */
42
45
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
43
46
  /** @typedef {import("../util/semver").SemVerRange} SemVerRange */
47
+ /** @typedef {import("../Module").BasicSourceTypes} BasicSourceTypes */
44
48
 
45
49
  /**
46
50
  * @typedef {object} ConsumeOptions
@@ -159,6 +163,19 @@ class ConsumeSharedModule extends Module {
159
163
  return CONSUME_SHARED_TYPES;
160
164
  }
161
165
 
166
+ /**
167
+ * Basic source types are high-level categories like javascript, css, webassembly, etc.
168
+ * We only have built-in knowledge about the javascript basic type here; other basic types may be
169
+ * added or changed over time by generators and do not need to be handled or detected here.
170
+ *
171
+ * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
172
+ * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
173
+ * @returns {BasicSourceTypes} types available (do not mutate)
174
+ */
175
+ getSourceBasicTypes() {
176
+ return JAVASCRIPT_TYPES;
177
+ }
178
+
162
179
  /**
163
180
  * @param {ModuleGraph} moduleGraph the module graph
164
181
  * @returns {Module | null} fallback module
@@ -43,7 +43,9 @@ class AppendOnlyStackedSet {
43
43
 
44
44
  clear() {
45
45
  this._sets = [];
46
- if (this._current) this._current.clear();
46
+ if (this._current) {
47
+ this._current = undefined;
48
+ }
47
49
  }
48
50
 
49
51
  /**
@@ -52,6 +54,25 @@ class AppendOnlyStackedSet {
52
54
  createChild() {
53
55
  return new AppendOnlyStackedSet(this._sets.length ? [...this._sets] : []);
54
56
  }
57
+
58
+ /**
59
+ * @returns {Iterator<T>} iterable iterator
60
+ */
61
+ [Symbol.iterator]() {
62
+ const iterators = this._sets.map((map) => map[Symbol.iterator]());
63
+ let current = iterators.pop();
64
+ return {
65
+ next() {
66
+ if (!current) return { done: true, value: undefined };
67
+ let result = current.next();
68
+ while (result.done && iterators.length > 0) {
69
+ current = /** @type {SetIterator<T>} */ (iterators.pop());
70
+ result = current.next();
71
+ }
72
+ return result;
73
+ }
74
+ };
75
+ }
55
76
  }
56
77
 
57
78
  module.exports = AppendOnlyStackedSet;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.105.3",
3
+ "version": "5.105.4",
4
4
  "description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
5
5
  "homepage": "https://github.com/webpack/webpack",
6
6
  "bugs": "https://github.com/webpack/webpack/issues",
@@ -95,7 +95,7 @@
95
95
  "acorn-import-phases": "^1.0.3",
96
96
  "browserslist": "^4.28.1",
97
97
  "chrome-trace-event": "^1.0.2",
98
- "enhanced-resolve": "^5.19.0",
98
+ "enhanced-resolve": "^5.20.0",
99
99
  "es-module-lexer": "^2.0.0",
100
100
  "eslint-scope": "5.1.1",
101
101
  "events": "^3.2.0",
@@ -107,7 +107,7 @@
107
107
  "neo-async": "^2.6.2",
108
108
  "schema-utils": "^4.3.3",
109
109
  "tapable": "^2.3.0",
110
- "terser-webpack-plugin": "^5.3.16",
110
+ "terser-webpack-plugin": "^5.3.17",
111
111
  "watchpack": "^2.5.1",
112
112
  "webpack-sources": "^3.3.4"
113
113
  },
package/types.d.ts CHANGED
@@ -311,6 +311,7 @@ declare abstract class AppendOnlyStackedSet<T> {
311
311
  has(el: T): boolean;
312
312
  clear(): void;
313
313
  createChild(): AppendOnlyStackedSet<T>;
314
+ [Symbol.iterator](): Iterator<T>;
314
315
  }
315
316
  declare interface Argument {
316
317
  description?: string;
@@ -1285,7 +1286,6 @@ declare interface CallbackWebpackFunction_2<T, R = void> {
1285
1286
  (err: null | Error, result?: T): R;
1286
1287
  }
1287
1288
  type Cell<T> = undefined | T;
1288
- type ChildrenStatsOptions = undefined | string | boolean | StatsOptions;
1289
1289
  declare class Chunk {
1290
1290
  constructor(name?: null | string, backCompat?: boolean);
1291
1291
  id: null | string | number;
@@ -10647,6 +10647,15 @@ declare class Module extends DependenciesBlock {
10647
10647
  callback: (err?: WebpackError) => void
10648
10648
  ): void;
10649
10649
  getSourceTypes(): ReadonlySet<string>;
10650
+
10651
+ /**
10652
+ * Basic source types are high-level categories like javascript, css, webassembly, etc.
10653
+ * We only have built-in knowledge about the javascript basic type here; other basic types may be
10654
+ * added or changed over time by generators and do not need to be handled or detected here.
10655
+ * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
10656
+ * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
10657
+ */
10658
+ getSourceBasicTypes(): ReadonlySet<string>;
10650
10659
  source(
10651
10660
  dependencyTemplates: DependencyTemplates,
10652
10661
  runtimeTemplate: RuntimeTemplate,
@@ -11583,12 +11592,33 @@ declare abstract class MultiStats {
11583
11592
  get hash(): string;
11584
11593
  hasErrors(): boolean;
11585
11594
  hasWarnings(): boolean;
11586
- toJson(options?: string | boolean | MultiStatsOptions): StatsCompilation;
11587
- toString(options?: string | boolean | MultiStatsOptions): string;
11595
+ toJson(
11596
+ options?:
11597
+ | boolean
11598
+ | StatsOptions
11599
+ | "none"
11600
+ | "summary"
11601
+ | "errors-only"
11602
+ | "errors-warnings"
11603
+ | "minimal"
11604
+ | "normal"
11605
+ | "detailed"
11606
+ | "verbose"
11607
+ ): StatsCompilation;
11608
+ toString(
11609
+ options?:
11610
+ | boolean
11611
+ | StatsOptions
11612
+ | "none"
11613
+ | "summary"
11614
+ | "errors-only"
11615
+ | "errors-warnings"
11616
+ | "minimal"
11617
+ | "normal"
11618
+ | "detailed"
11619
+ | "verbose"
11620
+ ): string;
11588
11621
  }
11589
- type MultiStatsOptions = Omit<StatsOptions, "children"> & {
11590
- children?: string | boolean | StatsOptions | ChildrenStatsOptions[];
11591
- };
11592
11622
  declare abstract class MultiWatching {
11593
11623
  watchings: Watching[];
11594
11624
  compiler: MultiCompiler;
@@ -12274,43 +12304,43 @@ declare interface NormalizedModules {
12274
12304
  type NormalizedStatsOptions = KnownNormalizedStatsOptions &
12275
12305
  Omit<
12276
12306
  StatsOptions,
12277
- | "assetsSort"
12278
- | "assetsSpace"
12279
- | "cachedAssets"
12280
- | "cachedModules"
12281
- | "chunkGroupAuxiliary"
12282
- | "chunkGroupChildren"
12283
- | "chunkGroupMaxAssets"
12307
+ | "context"
12284
12308
  | "chunkGroups"
12285
- | "chunkModulesSpace"
12309
+ | "requestShortener"
12286
12310
  | "chunksSort"
12287
- | "context"
12288
- | "dependentModules"
12289
- | "entrypoints"
12290
- | "excludeAssets"
12291
- | "excludeModules"
12311
+ | "modulesSort"
12312
+ | "chunkModulesSort"
12313
+ | "nestedModulesSort"
12314
+ | "assetsSort"
12315
+ | "ids"
12316
+ | "cachedAssets"
12292
12317
  | "groupAssetsByEmitStatus"
12293
- | "groupAssetsByExtension"
12294
12318
  | "groupAssetsByPath"
12295
- | "groupModulesByAttributes"
12319
+ | "groupAssetsByExtension"
12320
+ | "assetsSpace"
12321
+ | "excludeAssets"
12322
+ | "excludeModules"
12323
+ | "warningsFilter"
12324
+ | "cachedModules"
12325
+ | "orphanModules"
12326
+ | "dependentModules"
12327
+ | "runtimeModules"
12296
12328
  | "groupModulesByCacheStatus"
12297
- | "groupModulesByExtension"
12298
12329
  | "groupModulesByLayer"
12330
+ | "groupModulesByAttributes"
12299
12331
  | "groupModulesByPath"
12332
+ | "groupModulesByExtension"
12300
12333
  | "groupModulesByType"
12301
- | "ids"
12334
+ | "entrypoints"
12335
+ | "chunkGroupAuxiliary"
12336
+ | "chunkGroupChildren"
12337
+ | "chunkGroupMaxAssets"
12338
+ | "modulesSpace"
12339
+ | "chunkModulesSpace"
12340
+ | "nestedModulesSpace"
12302
12341
  | "logging"
12303
12342
  | "loggingDebug"
12304
12343
  | "loggingTrace"
12305
- | "modulesSort"
12306
- | "modulesSpace"
12307
- | "nestedModulesSpace"
12308
- | "orphanModules"
12309
- | "runtimeModules"
12310
- | "warningsFilter"
12311
- | "requestShortener"
12312
- | "chunkModulesSort"
12313
- | "nestedModulesSort"
12314
12344
  | "_env"
12315
12345
  > &
12316
12346
  Record<string, any>;
@@ -14145,7 +14175,7 @@ declare class ProgressPlugin {
14145
14175
  showModules?: boolean;
14146
14176
  showDependencies?: boolean;
14147
14177
  showActiveModules?: boolean;
14148
- percentBy?: null | "modules" | "entries" | "dependencies";
14178
+ percentBy?: null | "entries" | "modules" | "dependencies";
14149
14179
  apply(compiler: MultiCompiler | Compiler): void;
14150
14180
  static getReporter(
14151
14181
  compiler: Compiler
@@ -14210,7 +14240,7 @@ declare interface ProgressPluginOptions {
14210
14240
  /**
14211
14241
  * Collect percent algorithm. By default it calculates by a median from modules, entries and dependencies percent.
14212
14242
  */
14213
- percentBy?: null | "modules" | "entries" | "dependencies";
14243
+ percentBy?: null | "entries" | "modules" | "dependencies";
14214
14244
 
14215
14245
  /**
14216
14246
  * Collect profile data for progress steps. Default: false.
@@ -17768,8 +17798,32 @@ declare class Stats {
17768
17798
  get endTime(): number;
17769
17799
  hasWarnings(): boolean;
17770
17800
  hasErrors(): boolean;
17771
- toJson(options?: string | boolean | StatsOptions): StatsCompilation;
17772
- toString(options?: string | boolean | StatsOptions): string;
17801
+ toJson(
17802
+ options?:
17803
+ | boolean
17804
+ | StatsOptions
17805
+ | "none"
17806
+ | "summary"
17807
+ | "errors-only"
17808
+ | "errors-warnings"
17809
+ | "minimal"
17810
+ | "normal"
17811
+ | "detailed"
17812
+ | "verbose"
17813
+ ): StatsCompilation;
17814
+ toString(
17815
+ options?:
17816
+ | boolean
17817
+ | StatsOptions
17818
+ | "none"
17819
+ | "summary"
17820
+ | "errors-only"
17821
+ | "errors-warnings"
17822
+ | "minimal"
17823
+ | "normal"
17824
+ | "detailed"
17825
+ | "verbose"
17826
+ ): string;
17773
17827
  }
17774
17828
  type StatsAsset = KnownStatsAsset & Record<string, any>;
17775
17829
  type StatsChunk = KnownStatsChunk & Record<string, any>;
@@ -18522,6 +18576,11 @@ declare interface TsconfigOptions {
18522
18576
  * References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths
18523
18577
  */
18524
18578
  references?: string[] | "auto";
18579
+
18580
+ /**
18581
+ * Override baseUrl from tsconfig.json. If provided, this value will be used instead of the baseUrl in the tsconfig file
18582
+ */
18583
+ baseUrl?: string;
18525
18584
  }
18526
18585
  declare interface TsconfigPathsData {
18527
18586
  /**
@@ -20110,7 +20169,7 @@ declare namespace exports {
20110
20169
  MultiCompilerOptions,
20111
20170
  MultiConfiguration,
20112
20171
  MultiStats,
20113
- MultiStatsOptions,
20172
+ StatsOptions as MultiStatsOptions,
20114
20173
  ResolveData,
20115
20174
  ParserState,
20116
20175
  ResolvePluginInstance,