webpack 5.69.1 → 5.72.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 (84) hide show
  1. package/hot/poll.js +1 -1
  2. package/hot/signal.js +1 -1
  3. package/lib/BannerPlugin.js +12 -4
  4. package/lib/Chunk.js +1 -1
  5. package/lib/ChunkGraph.js +93 -6
  6. package/lib/ChunkGroup.js +1 -1
  7. package/lib/CleanPlugin.js +64 -18
  8. package/lib/Compilation.js +51 -25
  9. package/lib/Compiler.js +16 -3
  10. package/lib/ConstPlugin.js +2 -2
  11. package/lib/ContextModule.js +121 -34
  12. package/lib/ContextModuleFactory.js +65 -25
  13. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  14. package/lib/Dependency.js +7 -0
  15. package/lib/EntryOptionPlugin.js +1 -0
  16. package/lib/ErrorHelpers.js +2 -2
  17. package/lib/ExportsInfo.js +1 -1
  18. package/lib/ExternalModuleFactoryPlugin.js +4 -4
  19. package/lib/FileSystemInfo.js +8 -0
  20. package/lib/Generator.js +1 -0
  21. package/lib/LoaderOptionsPlugin.js +1 -1
  22. package/lib/Module.js +3 -0
  23. package/lib/ModuleFilenameHelpers.js +3 -3
  24. package/lib/ModuleHashingError.js +29 -0
  25. package/lib/NodeStuffPlugin.js +10 -0
  26. package/lib/NormalModule.js +26 -20
  27. package/lib/NormalModuleFactory.js +17 -10
  28. package/lib/ProgressPlugin.js +3 -4
  29. package/lib/RuntimePlugin.js +18 -0
  30. package/lib/RuntimeTemplate.js +1 -0
  31. package/lib/WebpackOptionsApply.js +2 -0
  32. package/lib/asset/AssetGenerator.js +155 -40
  33. package/lib/asset/AssetParser.js +1 -0
  34. package/lib/asset/AssetSourceGenerator.js +31 -6
  35. package/lib/asset/AssetSourceParser.js +1 -0
  36. package/lib/cache/PackFileCacheStrategy.js +8 -4
  37. package/lib/cache/ResolverCachePlugin.js +89 -28
  38. package/lib/config/browserslistTargetHandler.js +3 -5
  39. package/lib/config/defaults.js +9 -1
  40. package/lib/config/normalization.js +1 -0
  41. package/lib/container/RemoteRuntimeModule.js +8 -7
  42. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  43. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  44. package/lib/dependencies/ContextElementDependency.js +33 -1
  45. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  46. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +95 -0
  47. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  48. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +127 -43
  49. package/lib/dependencies/HarmonyImportSpecifierDependency.js +22 -8
  50. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  51. package/lib/dependencies/ImportContextDependency.js +0 -2
  52. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  53. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  54. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  55. package/lib/dependencies/LoaderPlugin.js +2 -0
  56. package/lib/dependencies/RequireContextDependency.js +0 -16
  57. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  58. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +24 -8
  59. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  60. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  61. package/lib/ids/HashedModuleIdsPlugin.js +2 -2
  62. package/lib/ids/IdHelpers.js +1 -1
  63. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  64. package/lib/javascript/JavascriptParser.js +66 -40
  65. package/lib/library/UmdLibraryPlugin.js +5 -3
  66. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -7
  67. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -7
  68. package/lib/optimize/ConcatenatedModule.js +2 -1
  69. package/lib/optimize/ModuleConcatenationPlugin.js +20 -1
  70. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  71. package/lib/schemes/HttpUriPlugin.js +44 -3
  72. package/lib/stats/DefaultStatsFactoryPlugin.js +1 -1
  73. package/lib/util/internalSerializables.js +4 -0
  74. package/lib/web/JsonpChunkLoadingRuntimeModule.js +17 -6
  75. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -20
  76. package/module.d.ts +15 -0
  77. package/package.json +2 -2
  78. package/schemas/WebpackOptions.check.js +1 -1
  79. package/schemas/WebpackOptions.json +17 -1
  80. package/schemas/plugins/BannerPlugin.check.js +1 -1
  81. package/schemas/plugins/BannerPlugin.json +4 -0
  82. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  83. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  84. package/types.d.ts +202 -84
@@ -19,22 +19,6 @@ class RequireContextDependency extends ContextDependency {
19
19
  get type() {
20
20
  return "require.context";
21
21
  }
22
-
23
- serialize(context) {
24
- const { write } = context;
25
-
26
- write(this.range);
27
-
28
- super.serialize(context);
29
- }
30
-
31
- deserialize(context) {
32
- const { read } = context;
33
-
34
- this.range = read();
35
-
36
- super.deserialize(context);
37
- }
38
22
  }
39
23
 
40
24
  makeSerializable(
@@ -25,7 +25,9 @@ class ModuleChunkLoadingPlugin {
25
25
  const isEnabledForChunk = chunk => {
26
26
  const options = chunk.getEntryOptions();
27
27
  const chunkLoading =
28
- (options && options.chunkLoading) || globalChunkLoading;
28
+ options && options.chunkLoading !== undefined
29
+ ? options.chunkLoading
30
+ : globalChunkLoading;
29
31
  return chunkLoading === "import";
30
32
  };
31
33
  const onceForChunkSet = new WeakSet();
@@ -55,15 +55,35 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
55
55
  this._runtimeRequirements = runtimeRequirements;
56
56
  }
57
57
 
58
+ /**
59
+ * @private
60
+ * @param {Chunk} chunk chunk
61
+ * @param {string} rootOutputDir root output directory
62
+ * @returns {string} generated code
63
+ */
64
+ _generateBaseUri(chunk, rootOutputDir) {
65
+ const options = chunk.getEntryOptions();
66
+ if (options && options.baseUri) {
67
+ return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
68
+ }
69
+ const {
70
+ compilation: {
71
+ outputOptions: { importMetaName }
72
+ }
73
+ } = this;
74
+ return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
75
+ rootOutputDir
76
+ )}, ${importMetaName}.url);`;
77
+ }
78
+
58
79
  /**
59
80
  * @returns {string} runtime code
60
81
  */
61
82
  generate() {
62
- const { compilation, chunk } = this;
83
+ const { compilation, chunk, chunkGraph } = this;
63
84
  const {
64
85
  runtimeTemplate,
65
- chunkGraph,
66
- outputOptions: { importFunctionName, importMetaName }
86
+ outputOptions: { importFunctionName }
67
87
  } = compilation;
68
88
  const fn = RuntimeGlobals.ensureChunkHandlers;
69
89
  const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
@@ -102,11 +122,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
102
122
 
103
123
  return Template.asString([
104
124
  withBaseURI
105
- ? Template.asString([
106
- `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
107
- rootOutputDir
108
- )}, ${importMetaName}.url);`
109
- ])
125
+ ? this._generateBaseUri(chunk, rootOutputDir)
110
126
  : "// no baseURI",
111
127
  "",
112
128
  "// object to store loaded and loading chunks",
@@ -28,7 +28,8 @@ module.exports = function () {
28
28
  var currentStatus = "idle";
29
29
 
30
30
  // while downloading
31
- var blockingPromises;
31
+ var blockingPromises = 0;
32
+ var blockingPromisesWaiting = [];
32
33
 
33
34
  // The update info
34
35
  var currentUpdateApplyHandlers;
@@ -218,17 +219,28 @@ module.exports = function () {
218
219
  return Promise.all(results);
219
220
  }
220
221
 
222
+ function unblock() {
223
+ if (--blockingPromises === 0) {
224
+ setStatus("ready").then(function () {
225
+ if (blockingPromises === 0) {
226
+ var list = blockingPromisesWaiting;
227
+ blockingPromisesWaiting = [];
228
+ for (var i = 0; i < list.length; i++) {
229
+ list[i]();
230
+ }
231
+ }
232
+ });
233
+ }
234
+ }
235
+
221
236
  function trackBlockingPromise(promise) {
222
237
  switch (currentStatus) {
223
238
  case "ready":
224
239
  setStatus("prepare");
225
- blockingPromises.push(promise);
226
- waitForBlockingPromises(function () {
227
- return setStatus("ready");
228
- });
229
- return promise;
240
+ /* fallthrough */
230
241
  case "prepare":
231
- blockingPromises.push(promise);
242
+ blockingPromises++;
243
+ promise.then(unblock, unblock);
232
244
  return promise;
233
245
  default:
234
246
  return promise;
@@ -236,11 +248,11 @@ module.exports = function () {
236
248
  }
237
249
 
238
250
  function waitForBlockingPromises(fn) {
239
- if (blockingPromises.length === 0) return fn();
240
- var blocker = blockingPromises;
241
- blockingPromises = [];
242
- return Promise.all(blocker).then(function () {
243
- return waitForBlockingPromises(fn);
251
+ if (blockingPromises === 0) return fn();
252
+ return new Promise(function (resolve) {
253
+ blockingPromisesWaiting.push(function () {
254
+ resolve(fn());
255
+ });
244
256
  });
245
257
  }
246
258
 
@@ -261,7 +273,6 @@ module.exports = function () {
261
273
 
262
274
  return setStatus("prepare").then(function () {
263
275
  var updatedModules = [];
264
- blockingPromises = [];
265
276
  currentUpdateApplyHandlers = [];
266
277
 
267
278
  return Promise.all(
@@ -298,7 +309,11 @@ module.exports = function () {
298
309
  function hotApply(options) {
299
310
  if (currentStatus !== "ready") {
300
311
  return Promise.resolve().then(function () {
301
- throw new Error("apply() is only allowed in ready status");
312
+ throw new Error(
313
+ "apply() is only allowed in ready status (state: " +
314
+ currentStatus +
315
+ ")"
316
+ );
302
317
  });
303
318
  }
304
319
  return internalApply(options);
@@ -443,15 +443,16 @@ module.exports = function () {
443
443
  ) {
444
444
  promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
445
445
  currentUpdateChunks[chunkId] = true;
446
+ } else {
447
+ currentUpdateChunks[chunkId] = false;
446
448
  }
447
449
  });
448
450
  if ($ensureChunkHandlers$) {
449
451
  $ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
450
452
  if (
451
453
  currentUpdateChunks &&
452
- !$hasOwnProperty$(currentUpdateChunks, chunkId) &&
453
- $hasOwnProperty$($installedChunks$, chunkId) &&
454
- $installedChunks$[chunkId] !== undefined
454
+ $hasOwnProperty$(currentUpdateChunks, chunkId) &&
455
+ !currentUpdateChunks[chunkId]
455
456
  ) {
456
457
  promises.push($loadUpdateChunk$(chunkId));
457
458
  currentUpdateChunks[chunkId] = true;
@@ -64,8 +64,8 @@ class HashedModuleIdsPlugin {
64
64
  hash.digest(options.hashDigest)
65
65
  );
66
66
  let len = options.hashDigestLength;
67
- while (usedIds.has(hashId.substr(0, len))) len++;
68
- const moduleId = hashId.substr(0, len);
67
+ while (usedIds.has(hashId.slice(0, len))) len++;
68
+ const moduleId = hashId.slice(0, len);
69
69
  chunkGraph.setModuleId(module, moduleId);
70
70
  usedIds.add(moduleId);
71
71
  }
@@ -25,7 +25,7 @@ const getHash = (str, len, hashFunction) => {
25
25
  const hash = createHash(hashFunction);
26
26
  hash.update(str);
27
27
  const digest = /** @type {string} */ (hash.digest("hex"));
28
- return digest.substr(0, len);
28
+ return digest.slice(0, len);
29
29
  };
30
30
 
31
31
  /**
@@ -61,12 +61,14 @@ class BasicEvaluatedExpression {
61
61
  /** @type {BasicEvaluatedExpression | undefined} */
62
62
  this.postfix = undefined;
63
63
  this.wrappedInnerExpressions = undefined;
64
- /** @type {string | undefined} */
64
+ /** @type {string | VariableInfoInterface | undefined} */
65
65
  this.identifier = undefined;
66
66
  /** @type {VariableInfoInterface} */
67
67
  this.rootInfo = undefined;
68
68
  /** @type {() => string[]} */
69
69
  this.getMembers = undefined;
70
+ /** @type {() => boolean[]} */
71
+ this.getMembersOptionals = undefined;
70
72
  /** @type {EsTreeNode} */
71
73
  this.expression = undefined;
72
74
  }
@@ -342,11 +344,12 @@ class BasicEvaluatedExpression {
342
344
  return this;
343
345
  }
344
346
 
345
- setIdentifier(identifier, rootInfo, getMembers) {
347
+ setIdentifier(identifier, rootInfo, getMembers, getMembersOptionals) {
346
348
  this.type = TypeIdentifier;
347
349
  this.identifier = identifier;
348
350
  this.rootInfo = rootInfo;
349
351
  this.getMembers = getMembers;
352
+ this.getMembersOptionals = getMembersOptionals;
350
353
  this.sideEffects = true;
351
354
  return this;
352
355
  }
@@ -57,7 +57,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
57
57
  /** @typedef {import("../Parser").ParserState} ParserState */
58
58
  /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
59
59
  /** @typedef {{declaredScope: ScopeInfo, freeName: string | true, tagInfo: TagInfo | undefined}} VariableInfoInterface */
60
- /** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[] }} GetInfoResult */
60
+ /** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[], getMembersOptionals: () => boolean[] }} GetInfoResult */
61
61
 
62
62
  const EMPTY_ARRAY = [];
63
63
  const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
@@ -262,9 +262,9 @@ class JavascriptParser extends Parser {
262
262
  /** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
263
263
  call: new HookMap(() => new SyncBailHook(["expression"])),
264
264
  /** Something like "a.b()" */
265
- /** @type {HookMap<SyncBailHook<[CallExpressionNode, string[]], boolean | void>>} */
265
+ /** @type {HookMap<SyncBailHook<[CallExpressionNode, string[], boolean[]], boolean | void>>} */
266
266
  callMemberChain: new HookMap(
267
- () => new SyncBailHook(["expression", "members"])
267
+ () => new SyncBailHook(["expression", "members", "membersOptionals"])
268
268
  ),
269
269
  /** Something like "a.b().c.d" */
270
270
  /** @type {HookMap<SyncBailHook<[ExpressionNode, string[], CallExpressionNode, string[]], boolean | void>>} */
@@ -292,11 +292,13 @@ class JavascriptParser extends Parser {
292
292
  optionalChaining: new SyncBailHook(["optionalChaining"]),
293
293
  /** @type {HookMap<SyncBailHook<[NewExpressionNode], boolean | void>>} */
294
294
  new: new HookMap(() => new SyncBailHook(["expression"])),
295
+ /** @type {SyncBailHook<[BinaryExpressionNode], boolean | void>} */
296
+ binaryExpression: new SyncBailHook(["binaryExpression"]),
295
297
  /** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
296
298
  expression: new HookMap(() => new SyncBailHook(["expression"])),
297
- /** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
299
+ /** @type {HookMap<SyncBailHook<[ExpressionNode, string[], boolean[]], boolean | void>>} */
298
300
  expressionMemberChain: new HookMap(
299
- () => new SyncBailHook(["expression", "members"])
301
+ () => new SyncBailHook(["expression", "members", "membersOptionals"])
300
302
  ),
301
303
  /** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
302
304
  unhandledExpressionMemberChain: new HookMap(
@@ -416,7 +418,6 @@ class JavascriptParser extends Parser {
416
418
  const expr = /** @type {LogicalExpressionNode} */ (_expr);
417
419
 
418
420
  const left = this.evaluateExpression(expr.left);
419
- if (!left) return;
420
421
  let returnRight = false;
421
422
  /** @type {boolean|undefined} */
422
423
  let allowedRight;
@@ -437,7 +438,6 @@ class JavascriptParser extends Parser {
437
438
  returnRight = true;
438
439
  } else return;
439
440
  const right = this.evaluateExpression(expr.right);
440
- if (!right) return;
441
441
  if (returnRight) {
442
442
  if (left.couldHaveSideEffects()) right.setSideEffects();
443
443
  return right.setRange(expr.range);
@@ -486,10 +486,10 @@ class JavascriptParser extends Parser {
486
486
 
487
487
  const handleConstOperation = fn => {
488
488
  const left = this.evaluateExpression(expr.left);
489
- if (!left || !left.isCompileTimeValue()) return;
489
+ if (!left.isCompileTimeValue()) return;
490
490
 
491
491
  const right = this.evaluateExpression(expr.right);
492
- if (!right || !right.isCompileTimeValue()) return;
492
+ if (!right.isCompileTimeValue()) return;
493
493
 
494
494
  const result = fn(
495
495
  left.asCompileTimeValue(),
@@ -545,9 +545,7 @@ class JavascriptParser extends Parser {
545
545
 
546
546
  const handleStrictEqualityComparison = eql => {
547
547
  const left = this.evaluateExpression(expr.left);
548
- if (!left) return;
549
548
  const right = this.evaluateExpression(expr.right);
550
- if (!right) return;
551
549
  const res = new BasicEvaluatedExpression();
552
550
  res.setRange(expr.range);
553
551
 
@@ -600,9 +598,7 @@ class JavascriptParser extends Parser {
600
598
 
601
599
  const handleAbstractEqualityComparison = eql => {
602
600
  const left = this.evaluateExpression(expr.left);
603
- if (!left) return;
604
601
  const right = this.evaluateExpression(expr.right);
605
- if (!right) return;
606
602
  const res = new BasicEvaluatedExpression();
607
603
  res.setRange(expr.range);
608
604
 
@@ -635,9 +631,7 @@ class JavascriptParser extends Parser {
635
631
 
636
632
  if (expr.operator === "+") {
637
633
  const left = this.evaluateExpression(expr.left);
638
- if (!left) return;
639
634
  const right = this.evaluateExpression(expr.right);
640
- if (!right) return;
641
635
  const res = new BasicEvaluatedExpression();
642
636
  if (left.isString()) {
643
637
  if (right.isString()) {
@@ -816,7 +810,7 @@ class JavascriptParser extends Parser {
816
810
 
817
811
  const handleConstOperation = fn => {
818
812
  const argument = this.evaluateExpression(expr.argument);
819
- if (!argument || !argument.isCompileTimeValue()) return;
813
+ if (!argument.isCompileTimeValue()) return;
820
814
  const result = fn(argument.asCompileTimeValue());
821
815
  return valueAsExpression(
822
816
  result,
@@ -915,7 +909,6 @@ class JavascriptParser extends Parser {
915
909
  }
916
910
  } else if (expr.operator === "!") {
917
911
  const argument = this.evaluateExpression(expr.argument);
918
- if (!argument) return;
919
912
  const bool = argument.asBool();
920
913
  if (typeof bool !== "boolean") return;
921
914
  return new BasicEvaluatedExpression()
@@ -980,7 +973,12 @@ class JavascriptParser extends Parser {
980
973
  const info = cachedExpression === expr ? cachedInfo : getInfo(expr);
981
974
  if (info !== undefined) {
982
975
  return new BasicEvaluatedExpression()
983
- .setIdentifier(info.name, info.rootInfo, info.getMembers)
976
+ .setIdentifier(
977
+ info.name,
978
+ info.rootInfo,
979
+ info.getMembers,
980
+ info.getMembersOptionals
981
+ )
984
982
  .setRange(expr.range);
985
983
  }
986
984
  });
@@ -997,7 +995,12 @@ class JavascriptParser extends Parser {
997
995
  typeof info === "string" ||
998
996
  (info instanceof VariableInfo && typeof info.freeName === "string")
999
997
  ) {
1000
- return { name: info, rootInfo: info, getMembers: () => [] };
998
+ return {
999
+ name: info,
1000
+ rootInfo: info,
1001
+ getMembers: () => [],
1002
+ getMembersOptionals: () => []
1003
+ };
1001
1004
  }
1002
1005
  });
1003
1006
  tapEvaluateWithVariableInfo("ThisExpression", expr => {
@@ -1006,7 +1009,12 @@ class JavascriptParser extends Parser {
1006
1009
  typeof info === "string" ||
1007
1010
  (info instanceof VariableInfo && typeof info.freeName === "string")
1008
1011
  ) {
1009
- return { name: info, rootInfo: info, getMembers: () => [] };
1012
+ return {
1013
+ name: info,
1014
+ rootInfo: info,
1015
+ getMembers: () => [],
1016
+ getMembersOptionals: () => []
1017
+ };
1010
1018
  }
1011
1019
  });
1012
1020
  this.hooks.evaluate.for("MetaProperty").tap("JavascriptParser", expr => {
@@ -1039,7 +1047,6 @@ class JavascriptParser extends Parser {
1039
1047
  const param = this.evaluateExpression(
1040
1048
  /** @type {ExpressionNode} */ (expr.callee.object)
1041
1049
  );
1042
- if (!param) return;
1043
1050
  const property =
1044
1051
  expr.callee.property.type === "Literal"
1045
1052
  ? `${expr.callee.property.value}`
@@ -1306,7 +1313,6 @@ class JavascriptParser extends Parser {
1306
1313
  if (conditionValue === undefined) {
1307
1314
  const consequent = this.evaluateExpression(expr.consequent);
1308
1315
  const alternate = this.evaluateExpression(expr.alternate);
1309
- if (!consequent || !alternate) return;
1310
1316
  res = new BasicEvaluatedExpression();
1311
1317
  if (consequent.isConditional()) {
1312
1318
  res.setOptions(consequent.options);
@@ -1380,7 +1386,7 @@ class JavascriptParser extends Parser {
1380
1386
  const expression = optionalExpressionsStack.pop();
1381
1387
  const evaluated = this.evaluateExpression(expression);
1382
1388
 
1383
- if (evaluated && evaluated.asNullish()) {
1389
+ if (evaluated.asNullish()) {
1384
1390
  return evaluated.setRange(_expr.range);
1385
1391
  }
1386
1392
  }
@@ -1390,7 +1396,7 @@ class JavascriptParser extends Parser {
1390
1396
 
1391
1397
  getRenameIdentifier(expr) {
1392
1398
  const result = this.evaluateExpression(expr);
1393
- if (result && result.isIdentifier()) {
1399
+ if (result.isIdentifier()) {
1394
1400
  return result.identifier;
1395
1401
  }
1396
1402
  }
@@ -2457,7 +2463,9 @@ class JavascriptParser extends Parser {
2457
2463
  }
2458
2464
 
2459
2465
  walkBinaryExpression(expression) {
2460
- this.walkLeftRightExpression(expression);
2466
+ if (this.hooks.binaryExpression.call(expression) === undefined) {
2467
+ this.walkLeftRightExpression(expression);
2468
+ }
2461
2469
  }
2462
2470
 
2463
2471
  walkLogicalExpression(expression) {
@@ -2492,7 +2500,9 @@ class JavascriptParser extends Parser {
2492
2500
  ) {
2493
2501
  this.setVariable(
2494
2502
  expression.left.name,
2495
- this.getVariableInfo(renameIdentifier)
2503
+ typeof renameIdentifier === "string"
2504
+ ? this.getVariableInfo(renameIdentifier)
2505
+ : renameIdentifier
2496
2506
  );
2497
2507
  }
2498
2508
  return;
@@ -2627,7 +2637,9 @@ class JavascriptParser extends Parser {
2627
2637
  argOrThis
2628
2638
  )
2629
2639
  ) {
2630
- return this.getVariableInfo(renameIdentifier);
2640
+ return typeof renameIdentifier === "string"
2641
+ ? this.getVariableInfo(renameIdentifier)
2642
+ : renameIdentifier;
2631
2643
  }
2632
2644
  }
2633
2645
  }
@@ -2727,7 +2739,10 @@ class JavascriptParser extends Parser {
2727
2739
  this.hooks.callMemberChain,
2728
2740
  callee.rootInfo,
2729
2741
  expression,
2730
- callee.getMembers()
2742
+ callee.getMembers(),
2743
+ callee.getMembersOptionals
2744
+ ? callee.getMembersOptionals()
2745
+ : callee.getMembers().map(() => false)
2731
2746
  );
2732
2747
  if (result1 === true) return;
2733
2748
  const result2 = this.callHooksForInfo(
@@ -2767,11 +2782,13 @@ class JavascriptParser extends Parser {
2767
2782
  );
2768
2783
  if (result1 === true) return;
2769
2784
  const members = exprInfo.getMembers();
2785
+ const membersOptionals = exprInfo.getMembersOptionals();
2770
2786
  const result2 = this.callHooksForInfo(
2771
2787
  this.hooks.expressionMemberChain,
2772
2788
  exprInfo.rootInfo,
2773
2789
  expression,
2774
- members
2790
+ members,
2791
+ membersOptionals
2775
2792
  );
2776
2793
  if (result2 === true) return;
2777
2794
  this.walkMemberExpressionWithExpressionName(
@@ -3167,17 +3184,15 @@ class JavascriptParser extends Parser {
3167
3184
 
3168
3185
  /**
3169
3186
  * @param {ExpressionNode} expression expression node
3170
- * @returns {BasicEvaluatedExpression | undefined} evaluation result
3187
+ * @returns {BasicEvaluatedExpression} evaluation result
3171
3188
  */
3172
3189
  evaluateExpression(expression) {
3173
3190
  try {
3174
3191
  const hook = this.hooks.evaluate.get(expression.type);
3175
3192
  if (hook !== undefined) {
3176
3193
  const result = hook.call(expression);
3177
- if (result !== undefined) {
3178
- if (result) {
3179
- result.setExpression(expression);
3180
- }
3194
+ if (result !== undefined && result !== null) {
3195
+ result.setExpression(expression);
3181
3196
  return result;
3182
3197
  }
3183
3198
  }
@@ -3348,6 +3363,10 @@ class JavascriptParser extends Parser {
3348
3363
  return state;
3349
3364
  }
3350
3365
 
3366
+ /**
3367
+ * @param {string} source source code
3368
+ * @returns {BasicEvaluatedExpression} evaluation result
3369
+ */
3351
3370
  evaluate(source) {
3352
3371
  const ast = JavascriptParser._parse("(" + source + ")", {
3353
3372
  sourceType: this.sourceType,
@@ -3609,12 +3628,13 @@ class JavascriptParser extends Parser {
3609
3628
 
3610
3629
  /**
3611
3630
  * @param {MemberExpressionNode} expression a member expression
3612
- * @returns {{ members: string[], object: ExpressionNode | SuperNode }} member names (reverse order) and remaining object
3631
+ * @returns {{ members: string[], object: ExpressionNode | SuperNode, membersOptionals: boolean[] }} member names (reverse order) and remaining object
3613
3632
  */
3614
3633
  extractMemberExpressionChain(expression) {
3615
3634
  /** @type {AnyNode} */
3616
3635
  let expr = expression;
3617
3636
  const members = [];
3637
+ const membersOptionals = [];
3618
3638
  while (expr.type === "MemberExpression") {
3619
3639
  if (expr.computed) {
3620
3640
  if (expr.property.type !== "Literal") break;
@@ -3623,10 +3643,13 @@ class JavascriptParser extends Parser {
3623
3643
  if (expr.property.type !== "Identifier") break;
3624
3644
  members.push(expr.property.name);
3625
3645
  }
3646
+ membersOptionals.push(expr.optional);
3626
3647
  expr = expr.object;
3627
3648
  }
3649
+
3628
3650
  return {
3629
3651
  members,
3652
+ membersOptionals,
3630
3653
  object: expr
3631
3654
  };
3632
3655
  }
@@ -3649,8 +3672,8 @@ class JavascriptParser extends Parser {
3649
3672
  return { info, name };
3650
3673
  }
3651
3674
 
3652
- /** @typedef {{ type: "call", call: CallExpressionNode, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[]}} CallExpressionInfo */
3653
- /** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[]}} ExpressionExpressionInfo */
3675
+ /** @typedef {{ type: "call", call: CallExpressionNode, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[], getMembersOptionals: () => boolean[]}} CallExpressionInfo */
3676
+ /** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[], getMembersOptionals: () => boolean[]}} ExpressionExpressionInfo */
3654
3677
 
3655
3678
  /**
3656
3679
  * @param {MemberExpressionNode} expression a member expression
@@ -3658,7 +3681,8 @@ class JavascriptParser extends Parser {
3658
3681
  * @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
3659
3682
  */
3660
3683
  getMemberExpressionInfo(expression, allowedTypes) {
3661
- const { object, members } = this.extractMemberExpressionChain(expression);
3684
+ const { object, members, membersOptionals } =
3685
+ this.extractMemberExpressionChain(expression);
3662
3686
  switch (object.type) {
3663
3687
  case "CallExpression": {
3664
3688
  if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0)
@@ -3682,7 +3706,8 @@ class JavascriptParser extends Parser {
3682
3706
  rootInfo,
3683
3707
  getCalleeMembers: memoize(() => rootMembers.reverse()),
3684
3708
  name: objectAndMembersToName(`${calleeName}()`, members),
3685
- getMembers: memoize(() => members.reverse())
3709
+ getMembers: memoize(() => members.reverse()),
3710
+ getMembersOptionals: memoize(() => membersOptionals.reverse())
3686
3711
  };
3687
3712
  }
3688
3713
  case "Identifier":
@@ -3700,7 +3725,8 @@ class JavascriptParser extends Parser {
3700
3725
  type: "expression",
3701
3726
  name: objectAndMembersToName(resolvedRoot, members),
3702
3727
  rootInfo,
3703
- getMembers: memoize(() => members.reverse())
3728
+ getMembers: memoize(() => members.reverse()),
3729
+ getMembersOptionals: memoize(() => membersOptionals.reverse())
3704
3730
  };
3705
3731
  }
3706
3732
  }
@@ -310,9 +310,11 @@ class UmdLibraryPlugin extends AbstractLibraryPlugin {
310
310
  : " var a = factory();\n") +
311
311
  " for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n" +
312
312
  " }\n") +
313
- `})(${
314
- runtimeTemplate.outputOptions.globalObject
315
- }, function(${externalsArguments(externals)}) {\nreturn `,
313
+ `})(${runtimeTemplate.outputOptions.globalObject}, ${
314
+ runtimeTemplate.supportsArrowFunction()
315
+ ? `(${externalsArguments(externals)}) =>`
316
+ : `function(${externalsArguments(externals)})`
317
+ } {\nreturn `,
316
318
  "webpack/universalModuleDefinition"
317
319
  ),
318
320
  source,
@@ -15,12 +15,33 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers");
15
15
  const compileBooleanMatcher = require("../util/compileBooleanMatcher");
16
16
  const { getUndoPath } = require("../util/identifier");
17
17
 
18
+ /** @typedef {import("../Chunk")} Chunk */
19
+
18
20
  class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
19
21
  constructor(runtimeRequirements) {
20
22
  super("readFile chunk loading", RuntimeModule.STAGE_ATTACH);
21
23
  this.runtimeRequirements = runtimeRequirements;
22
24
  }
23
25
 
26
+ /**
27
+ * @private
28
+ * @param {Chunk} chunk chunk
29
+ * @param {string} rootOutputDir root output directory
30
+ * @returns {string} generated code
31
+ */
32
+ _generateBaseUri(chunk, rootOutputDir) {
33
+ const options = chunk.getEntryOptions();
34
+ if (options && options.baseUri) {
35
+ return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
36
+ }
37
+
38
+ return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
39
+ rootOutputDir
40
+ ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}`
41
+ : "__filename"
42
+ });`;
43
+ }
44
+
24
45
  /**
25
46
  * @returns {string} runtime code
26
47
  */
@@ -67,13 +88,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
67
88
 
68
89
  return Template.asString([
69
90
  withBaseURI
70
- ? Template.asString([
71
- `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
72
- rootOutputDir
73
- ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}`
74
- : "__filename"
75
- });`
76
- ])
91
+ ? this._generateBaseUri(chunk, rootOutputDir)
77
92
  : "// no baseURI",
78
93
  "",
79
94
  "// object to store loaded chunks",