webpack 5.84.1 → 5.85.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.

Potentially problematic release.


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

Files changed (121) hide show
  1. package/lib/AsyncDependenciesBlock.js +2 -2
  2. package/lib/AutomaticPrefetchPlugin.js +1 -0
  3. package/lib/BannerPlugin.js +4 -0
  4. package/lib/CacheFacade.js +4 -0
  5. package/lib/ChunkGroup.js +5 -1
  6. package/lib/CleanPlugin.js +30 -7
  7. package/lib/CompatibilityPlugin.js +1 -1
  8. package/lib/Compilation.js +1 -1
  9. package/lib/Compiler.js +1 -1
  10. package/lib/ContextModuleFactory.js +1 -1
  11. package/lib/DllModuleFactory.js +1 -1
  12. package/lib/HookWebpackError.js +1 -1
  13. package/lib/IgnoreErrorModuleFactory.js +1 -1
  14. package/lib/Module.js +21 -9
  15. package/lib/ModuleFactory.js +1 -1
  16. package/lib/ModuleTypeConstants.js +2 -1
  17. package/lib/NormalModuleFactory.js +1 -1
  18. package/lib/NormalModuleReplacementPlugin.js +4 -2
  19. package/lib/NullFactory.js +1 -1
  20. package/lib/RecordIdsPlugin.js +4 -4
  21. package/lib/RuntimeModule.js +5 -5
  22. package/lib/RuntimePlugin.js +4 -0
  23. package/lib/RuntimeTemplate.js +2 -2
  24. package/lib/SelfModuleFactory.js +1 -1
  25. package/lib/Template.js +1 -1
  26. package/lib/UseStrictPlugin.js +4 -0
  27. package/lib/WarnDeprecatedOptionPlugin.js +7 -0
  28. package/lib/WatchIgnorePlugin.js +4 -0
  29. package/lib/WebpackOptionsApply.js +2 -1
  30. package/lib/asset/AssetGenerator.js +7 -2
  31. package/lib/asset/AssetModulesPlugin.js +7 -1
  32. package/lib/asset/AssetParser.js +4 -1
  33. package/lib/asset/RawDataUrlModule.js +5 -3
  34. package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
  35. package/lib/cache/PackFileCacheStrategy.js +7 -1
  36. package/lib/config/defaults.js +38 -10
  37. package/lib/config/normalization.js +2 -1
  38. package/lib/container/ContainerEntryModule.js +4 -0
  39. package/lib/container/ContainerEntryModuleFactory.js +1 -1
  40. package/lib/container/FallbackDependency.js +7 -0
  41. package/lib/container/FallbackItemDependency.js +3 -0
  42. package/lib/container/FallbackModule.js +4 -0
  43. package/lib/container/FallbackModuleFactory.js +1 -1
  44. package/lib/container/RemoteModule.js +4 -0
  45. package/lib/container/RemoteRuntimeModule.js +1 -0
  46. package/lib/container/RemoteToExternalDependency.js +3 -0
  47. package/lib/dependencies/CommonJsPlugin.js +14 -12
  48. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +1 -1
  49. package/lib/dependencies/HarmonyExports.js +3 -1
  50. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +16 -5
  51. package/lib/dependencies/HarmonyImportSpecifierDependency.js +75 -6
  52. package/lib/dependencies/WorkerPlugin.js +25 -1
  53. package/lib/esm/ModuleChunkFormatPlugin.js +13 -5
  54. package/lib/esm/ModuleChunkLoadingPlugin.js +9 -0
  55. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +10 -8
  56. package/lib/hmr/LazyCompilationPlugin.js +1 -1
  57. package/lib/ids/ChunkModuleIdRangePlugin.js +11 -0
  58. package/lib/ids/DeterministicChunkIdsPlugin.js +11 -2
  59. package/lib/ids/DeterministicModuleIdsPlugin.js +11 -7
  60. package/lib/ids/HashedModuleIdsPlugin.js +8 -1
  61. package/lib/ids/IdHelpers.js +6 -0
  62. package/lib/ids/NamedChunkIdsPlugin.js +13 -1
  63. package/lib/ids/NamedModuleIdsPlugin.js +14 -3
  64. package/lib/ids/OccurrenceChunkIdsPlugin.js +6 -2
  65. package/lib/ids/SyncModuleIdsPlugin.js +2 -2
  66. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +1 -1
  67. package/lib/javascript/BasicEvaluatedExpression.js +12 -1
  68. package/lib/javascript/ChunkHelpers.js +2 -2
  69. package/lib/javascript/EnableChunkLoadingPlugin.js +4 -0
  70. package/lib/javascript/JavascriptModulesPlugin.js +24 -19
  71. package/lib/javascript/JavascriptParser.js +42 -18
  72. package/lib/javascript/StartupHelpers.js +1 -1
  73. package/lib/json/JsonGenerator.js +7 -5
  74. package/lib/json/JsonParser.js +1 -1
  75. package/lib/library/AbstractLibraryPlugin.js +4 -0
  76. package/lib/library/AssignLibraryPlugin.js +6 -4
  77. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  78. package/lib/library/ModuleLibraryPlugin.js +6 -3
  79. package/lib/library/SystemLibraryPlugin.js +1 -0
  80. package/lib/library/UmdLibraryPlugin.js +4 -0
  81. package/lib/node/CommonJsChunkLoadingPlugin.js +17 -2
  82. package/lib/node/NodeTemplatePlugin.js +10 -2
  83. package/lib/node/NodeWatchFileSystem.js +1 -1
  84. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +4 -1
  85. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +8 -0
  86. package/lib/node/ReadFileCompileWasmPlugin.js +19 -2
  87. package/lib/node/RequireChunkLoadingRuntimeModule.js +4 -1
  88. package/lib/runtime/AsyncModuleRuntimeModule.js +1 -1
  89. package/lib/runtime/AutoPublicPathRuntimeModule.js +5 -1
  90. package/lib/runtime/BaseUriRuntimeModule.js +5 -1
  91. package/lib/runtime/EnsureChunkRuntimeModule.js +3 -0
  92. package/lib/runtime/GetChunkFilenameRuntimeModule.js +35 -16
  93. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -1
  94. package/lib/runtime/LoadScriptRuntimeModule.js +1 -1
  95. package/lib/runtime/PublicPathRuntimeModule.js +5 -0
  96. package/lib/runtime/StartupChunkDependenciesPlugin.js +15 -0
  97. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +3 -0
  98. package/lib/runtime/StartupEntrypointRuntimeModule.js +3 -0
  99. package/lib/sharing/ProvideSharedModuleFactory.js +1 -1
  100. package/lib/util/createHash.js +1 -1
  101. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  102. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +9 -1
  103. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +13 -3
  104. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +19 -2
  105. package/lib/wasm-async/AsyncWebAssemblyParser.js +3 -0
  106. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +25 -1
  107. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +14 -5
  108. package/lib/wasm-sync/WebAssemblyGenerator.js +18 -5
  109. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +1 -1
  110. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +12 -1
  111. package/lib/wasm-sync/WebAssemblyParser.js +9 -2
  112. package/lib/wasm-sync/WebAssemblyUtils.js +1 -1
  113. package/lib/web/FetchCompileAsyncWasmPlugin.js +9 -0
  114. package/lib/web/FetchCompileWasmPlugin.js +19 -2
  115. package/lib/web/JsonpChunkLoadingPlugin.js +9 -0
  116. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +9 -0
  117. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  118. package/package.json +1 -1
  119. package/schemas/WebpackOptions.check.js +1 -1
  120. package/schemas/WebpackOptions.json +12 -0
  121. package/types.d.ts +189 -141
@@ -60,7 +60,8 @@ class RawDataUrlModule extends Module {
60
60
  * @returns {number} the estimated size of the module (must be non-zero)
61
61
  */
62
62
  size(type) {
63
- if (this.url === undefined) this.url = this.urlBuffer.toString();
63
+ if (this.url === undefined)
64
+ this.url = /** @type {Buffer} */ (this.urlBuffer).toString();
64
65
  return Math.max(1, this.url.length);
65
66
  }
66
67
 
@@ -102,7 +103,8 @@ class RawDataUrlModule extends Module {
102
103
  * @returns {CodeGenerationResult} result
103
104
  */
104
105
  codeGeneration(context) {
105
- if (this.url === undefined) this.url = this.urlBuffer.toString();
106
+ if (this.url === undefined)
107
+ this.url = /** @type {Buffer} */ (this.urlBuffer).toString();
106
108
  const sources = new Map();
107
109
  sources.set(
108
110
  "javascript",
@@ -121,7 +123,7 @@ class RawDataUrlModule extends Module {
121
123
  * @returns {void}
122
124
  */
123
125
  updateHash(hash, context) {
124
- hash.update(this.urlBuffer);
126
+ hash.update(/** @type {Buffer} */ (this.urlBuffer));
125
127
  super.updateHash(hash, context);
126
128
  }
127
129
 
@@ -42,7 +42,7 @@ class InferAsyncModulesPlugin {
42
42
  c.isTargetActive(undefined)
43
43
  )
44
44
  ) {
45
- queue.add(originModule);
45
+ queue.add(/** @type {Module} */ (originModule));
46
46
  }
47
47
  }
48
48
  }
@@ -981,6 +981,7 @@ class PackFileCacheStrategy {
981
981
  * @param {boolean} options.profile track and log detailed timing information for individual cache items
982
982
  * @param {boolean} options.allowCollectingMemory allow to collect unused memory created during deserialization
983
983
  * @param {false | "gzip" | "brotli"} options.compression compression used
984
+ * @param {boolean} options.readonly disable storing cache into filesystem
984
985
  */
985
986
  constructor({
986
987
  compiler,
@@ -993,7 +994,8 @@ class PackFileCacheStrategy {
993
994
  maxAge,
994
995
  profile,
995
996
  allowCollectingMemory,
996
- compression
997
+ compression,
998
+ readonly
997
999
  }) {
998
1000
  this.fileSerializer = createFileSerializer(
999
1001
  fs,
@@ -1012,6 +1014,7 @@ class PackFileCacheStrategy {
1012
1014
  this.logger = logger;
1013
1015
  this.maxAge = maxAge;
1014
1016
  this.profile = profile;
1017
+ this.readonly = readonly;
1015
1018
  this.allowCollectingMemory = allowCollectingMemory;
1016
1019
  this.compression = compression;
1017
1020
  this._extension =
@@ -1213,6 +1216,8 @@ class PackFileCacheStrategy {
1213
1216
  * @returns {Promise<void>} promise
1214
1217
  */
1215
1218
  store(identifier, etag, data) {
1219
+ if (this.readonly) return Promise.resolve();
1220
+
1216
1221
  return this._getPack().then(pack => {
1217
1222
  pack.set(identifier, etag === null ? null : etag.toString(), data);
1218
1223
  });
@@ -1239,6 +1244,7 @@ class PackFileCacheStrategy {
1239
1244
  }
1240
1245
 
1241
1246
  storeBuildDependencies(dependencies) {
1247
+ if (this.readonly) return;
1242
1248
  this.newBuildDependencies.addAll(dependencies);
1243
1249
  }
1244
1250
 
@@ -14,7 +14,8 @@ const {
14
14
  JAVASCRIPT_MODULE_TYPE_ESM,
15
15
  JAVASCRIPT_MODULE_TYPE_DYNAMIC,
16
16
  WEBASSEMBLY_MODULE_TYPE_SYNC,
17
- ASSET_MODULE_TYPE
17
+ ASSET_MODULE_TYPE,
18
+ CSS_MODULE_TYPE
18
19
  } = require("../ModuleTypeConstants");
19
20
  const Template = require("../Template");
20
21
  const { cleverMerge } = require("../util/cleverMerge");
@@ -247,7 +248,7 @@ const applyWebpackOptionsDefaults = options => {
247
248
 
248
249
  applyLoaderDefaults(
249
250
  /** @type {NonNullable<WebpackOptions["loader"]>} */ (options.loader),
250
- { targetProperties }
251
+ { targetProperties, environment: options.output.environment }
251
252
  );
252
253
 
253
254
  F(options, "externalsType", () => {
@@ -414,6 +415,7 @@ const applyCacheDefaults = (
414
415
  D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
415
416
  D(cache, "allowCollectingMemory", development);
416
417
  D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
418
+ D(cache, "readonly", false);
417
419
  D(
418
420
  /** @type {NonNullable<FileCacheOptions["buildDependencies"]>} */
419
421
  (cache.buildDependencies),
@@ -703,7 +705,7 @@ const applyModuleDefaults = (
703
705
  }
704
706
  if (css) {
705
707
  const cssRule = {
706
- type: "css",
708
+ type: CSS_MODULE_TYPE,
707
709
  resolve: {
708
710
  fullySpecified: true,
709
711
  preferRelative: true
@@ -1034,6 +1036,22 @@ const applyOutputDefaults = (
1034
1036
  * @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy
1035
1037
  */
1036
1038
  const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
1039
+
1040
+ F(
1041
+ environment,
1042
+ "globalThis",
1043
+ () => /** @type {boolean | undefined} */ (tp && tp.globalThis)
1044
+ );
1045
+ F(
1046
+ environment,
1047
+ "bigIntLiteral",
1048
+ () => /** @type {boolean | undefined} */ (tp && tp.bigIntLiteral)
1049
+ );
1050
+ F(
1051
+ environment,
1052
+ "const",
1053
+ () => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
1054
+ );
1037
1055
  F(
1038
1056
  environment,
1039
1057
  "arrowFunction",
@@ -1042,8 +1060,8 @@ const applyOutputDefaults = (
1042
1060
  );
1043
1061
  F(
1044
1062
  environment,
1045
- "const",
1046
- () => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
1063
+ "forOf",
1064
+ () => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
1047
1065
  );
1048
1066
  F(
1049
1067
  environment,
@@ -1053,13 +1071,15 @@ const applyOutputDefaults = (
1053
1071
  );
1054
1072
  F(
1055
1073
  environment,
1056
- "forOf",
1057
- () => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
1074
+ "optionalChaining",
1075
+ () =>
1076
+ tp && optimistic(/** @type {boolean | undefined} */ (tp.optionalChaining))
1058
1077
  );
1059
1078
  F(
1060
1079
  environment,
1061
- "bigIntLiteral",
1062
- () => /** @type {boolean | undefined} */ (tp && tp.bigIntLiteral)
1080
+ "templateLiteral",
1081
+ () =>
1082
+ tp && optimistic(/** @type {boolean | undefined} */ (tp.templateLiteral))
1063
1083
  );
1064
1084
  F(environment, "dynamicImport", () =>
1065
1085
  conditionallyOptimistic(
@@ -1067,6 +1087,12 @@ const applyOutputDefaults = (
1067
1087
  output.module
1068
1088
  )
1069
1089
  );
1090
+ F(environment, "dynamicImportInWorker", () =>
1091
+ conditionallyOptimistic(
1092
+ /** @type {boolean | undefined} */ (tp && tp.dynamicImportInWorker),
1093
+ output.module
1094
+ )
1095
+ );
1070
1096
  F(environment, "module", () =>
1071
1097
  conditionallyOptimistic(
1072
1098
  /** @type {boolean | undefined} */ (tp && tp.module),
@@ -1213,9 +1239,10 @@ const applyExternalsPresetsDefaults = (
1213
1239
  * @param {Loader} loader options
1214
1240
  * @param {Object} options options
1215
1241
  * @param {TargetProperties | false} options.targetProperties target properties
1242
+ * @param {Environment} options.environment environment
1216
1243
  * @returns {void}
1217
1244
  */
1218
- const applyLoaderDefaults = (loader, { targetProperties }) => {
1245
+ const applyLoaderDefaults = (loader, { targetProperties, environment }) => {
1219
1246
  F(loader, "target", () => {
1220
1247
  if (targetProperties) {
1221
1248
  if (targetProperties.electron) {
@@ -1229,6 +1256,7 @@ const applyLoaderDefaults = (loader, { targetProperties }) => {
1229
1256
  if (targetProperties.web) return "web";
1230
1257
  }
1231
1258
  });
1259
+ D(loader, "environment", environment);
1232
1260
  };
1233
1261
 
1234
1262
  /**
@@ -158,7 +158,8 @@ const getNormalizedWebpackOptions = config => {
158
158
  cache.idleTimeoutAfterLargeChanges,
159
159
  name: cache.name,
160
160
  store: cache.store,
161
- version: cache.version
161
+ version: cache.version,
162
+ readonly: cache.readonly
162
163
  };
163
164
  case undefined:
164
165
  case "memory":
@@ -273,6 +273,10 @@ class ContainerEntryModule extends Module {
273
273
  super.serialize(context);
274
274
  }
275
275
 
276
+ /**
277
+ * @param {ObjectDeserializerContext} context context
278
+ * @returns {ContainerEntryModule} deserialized container entry module
279
+ */
276
280
  static deserialize(context) {
277
281
  const { read } = context;
278
282
  const obj = new ContainerEntryModule(read(), read(), read());
@@ -15,7 +15,7 @@ const ContainerEntryModule = require("./ContainerEntryModule");
15
15
  module.exports = class ContainerEntryModuleFactory extends ModuleFactory {
16
16
  /**
17
17
  * @param {ModuleFactoryCreateData} data data object
18
- * @param {function(Error=, ModuleFactoryResult=): void} callback callback
18
+ * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback
19
19
  * @returns {void}
20
20
  */
21
21
  create({ dependencies: [dependency] }, callback) {
@@ -12,6 +12,9 @@ const makeSerializable = require("../util/makeSerializable");
12
12
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
13
13
 
14
14
  class FallbackDependency extends Dependency {
15
+ /**
16
+ * @param {string[]} requests requests
17
+ */
15
18
  constructor(requests) {
16
19
  super();
17
20
  this.requests = requests;
@@ -41,6 +44,10 @@ class FallbackDependency extends Dependency {
41
44
  super.serialize(context);
42
45
  }
43
46
 
47
+ /**
48
+ * @param {ObjectDeserializerContext} context context
49
+ * @returns {FallbackDependency} deserialize fallback dependency
50
+ */
44
51
  static deserialize(context) {
45
52
  const { read } = context;
46
53
  const obj = new FallbackDependency(read());
@@ -9,6 +9,9 @@ const ModuleDependency = require("../dependencies/ModuleDependency");
9
9
  const makeSerializable = require("../util/makeSerializable");
10
10
 
11
11
  class FallbackItemDependency extends ModuleDependency {
12
+ /**
13
+ * @param {string} request request
14
+ */
12
15
  constructor(request) {
13
16
  super(request);
14
17
  }
@@ -166,6 +166,10 @@ class FallbackModule extends Module {
166
166
  super.serialize(context);
167
167
  }
168
168
 
169
+ /**
170
+ * @param {ObjectDeserializerContext} context context
171
+ * @returns {FallbackModule} deserialized fallback module
172
+ */
169
173
  static deserialize(context) {
170
174
  const { read } = context;
171
175
  const obj = new FallbackModule(read());
@@ -15,7 +15,7 @@ const FallbackModule = require("./FallbackModule");
15
15
  module.exports = class FallbackModuleFactory extends ModuleFactory {
16
16
  /**
17
17
  * @param {ModuleFactoryCreateData} data data object
18
- * @param {function(Error=, ModuleFactoryResult=): void} callback callback
18
+ * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback
19
19
  * @returns {void}
20
20
  */
21
21
  create({ dependencies: [dependency] }, callback) {
@@ -164,6 +164,10 @@ class RemoteModule extends Module {
164
164
  super.serialize(context);
165
165
  }
166
166
 
167
+ /**
168
+ * @param {ObjectDeserializerContext} context context
169
+ * @returns {RemoteModule} deserialized module
170
+ */
167
171
  static deserialize(context) {
168
172
  const { read } = context;
169
173
  const obj = new RemoteModule(read(), read(), read(), read());
@@ -9,6 +9,7 @@ const RuntimeGlobals = require("../RuntimeGlobals");
9
9
  const RuntimeModule = require("../RuntimeModule");
10
10
  const Template = require("../Template");
11
11
 
12
+ /** @typedef {import("../Chunk")} Chunk */
12
13
  /** @typedef {import("./RemoteModule")} RemoteModule */
13
14
 
14
15
  class RemoteRuntimeModule extends RuntimeModule {
@@ -9,6 +9,9 @@ const ModuleDependency = require("../dependencies/ModuleDependency");
9
9
  const makeSerializable = require("../util/makeSerializable");
10
10
 
11
11
  class RemoteToExternalDependency extends ModuleDependency {
12
+ /**
13
+ * @param {string} request request
14
+ */
12
15
  constructor(request) {
13
16
  super(request);
14
17
  }
@@ -197,10 +197,10 @@ class CommonJsPlugin {
197
197
  )
198
198
  );
199
199
  parser.hooks.expression
200
- .for("module.loaded")
200
+ .for(RuntimeGlobals.moduleLoaded)
201
201
  .tap(PLUGIN_NAME, expr => {
202
202
  parser.state.module.buildInfo.moduleConcatenationBailout =
203
- "module.loaded";
203
+ RuntimeGlobals.moduleLoaded;
204
204
  const dep = new RuntimeRequirementsDependency([
205
205
  RuntimeGlobals.moduleLoaded
206
206
  ]);
@@ -209,16 +209,18 @@ class CommonJsPlugin {
209
209
  return true;
210
210
  });
211
211
 
212
- parser.hooks.expression.for("module.id").tap(PLUGIN_NAME, expr => {
213
- parser.state.module.buildInfo.moduleConcatenationBailout =
214
- "module.id";
215
- const dep = new RuntimeRequirementsDependency([
216
- RuntimeGlobals.moduleId
217
- ]);
218
- dep.loc = expr.loc;
219
- parser.state.module.addPresentationalDependency(dep);
220
- return true;
221
- });
212
+ parser.hooks.expression
213
+ .for(RuntimeGlobals.moduleId)
214
+ .tap(PLUGIN_NAME, expr => {
215
+ parser.state.module.buildInfo.moduleConcatenationBailout =
216
+ RuntimeGlobals.moduleId;
217
+ const dep = new RuntimeRequirementsDependency([
218
+ RuntimeGlobals.moduleId
219
+ ]);
220
+ dep.loc = expr.loc;
221
+ parser.state.module.addPresentationalDependency(dep);
222
+ return true;
223
+ });
222
224
 
223
225
  parser.hooks.evaluateIdentifier.for("module.hot").tap(
224
226
  PLUGIN_NAME,
@@ -35,7 +35,7 @@ class HarmonyEvaluatedImportSpecifierDependency extends HarmonyImportSpecifierDe
35
35
  * @param {string} operator operator
36
36
  */
37
37
  constructor(request, sourceOrder, ids, name, range, assertions, operator) {
38
- super(request, sourceOrder, ids, name, range, false, assertions);
38
+ super(request, sourceOrder, ids, name, range, false, assertions, []);
39
39
  this.operator = operator;
40
40
  }
41
41
 
@@ -5,6 +5,8 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const RuntimeGlobals = require("../RuntimeGlobals");
9
+
8
10
  /** @typedef {import("../Parser").ParserState} ParserState */
9
11
 
10
12
  /** @type {WeakMap<ParserState, boolean>} */
@@ -22,7 +24,7 @@ exports.enable = (parserState, isStrictHarmony) => {
22
24
  if (value !== true) {
23
25
  parserState.module.buildMeta.exportsType = "namespace";
24
26
  parserState.module.buildInfo.strict = true;
25
- parserState.module.buildInfo.exportsArgument = "__webpack_exports__";
27
+ parserState.module.buildInfo.exportsArgument = RuntimeGlobals.exports;
26
28
  if (isStrictHarmony) {
27
29
  parserState.module.buildMeta.strictHarmonyModule = true;
28
30
  parserState.module.buildInfo.moduleArgument = "__webpack_module__";
@@ -195,7 +195,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
195
195
  settings.name,
196
196
  expr.range,
197
197
  exportPresenceMode,
198
- settings.assertions
198
+ settings.assertions,
199
+ []
199
200
  );
200
201
  dep.referencedPropertiesInDestructuring =
201
202
  parser.destructuringAssignmentPropertiesFor(expr);
@@ -211,7 +212,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
211
212
  .for(harmonySpecifierTag)
212
213
  .tap(
213
214
  "HarmonyImportDependencyParserPlugin",
214
- (expression, members, membersOptionals) => {
215
+ (expression, members, membersOptionals, memberRanges) => {
215
216
  const settings = /** @type {HarmonySettings} */ (
216
217
  parser.currentTagData
217
218
  );
@@ -219,6 +220,10 @@ module.exports = class HarmonyImportDependencyParserPlugin {
219
220
  members,
220
221
  membersOptionals
221
222
  );
223
+ const ranges = memberRanges.slice(
224
+ 0,
225
+ memberRanges.length - (members.length - nonOptionalMembers.length)
226
+ );
222
227
  const expr =
223
228
  nonOptionalMembers !== members
224
229
  ? getNonOptionalMemberChain(
@@ -234,7 +239,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
234
239
  settings.name,
235
240
  expr.range,
236
241
  exportPresenceMode,
237
- settings.assertions
242
+ settings.assertions,
243
+ ranges
238
244
  );
239
245
  dep.referencedPropertiesInDestructuring =
240
246
  parser.destructuringAssignmentPropertiesFor(expr);
@@ -249,7 +255,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
249
255
  .for(harmonySpecifierTag)
250
256
  .tap(
251
257
  "HarmonyImportDependencyParserPlugin",
252
- (expression, members, membersOptionals) => {
258
+ (expression, members, membersOptionals, memberRanges) => {
253
259
  const { arguments: args, callee } = expression;
254
260
  const settings = /** @type {HarmonySettings} */ (
255
261
  parser.currentTagData
@@ -258,6 +264,10 @@ module.exports = class HarmonyImportDependencyParserPlugin {
258
264
  members,
259
265
  membersOptionals
260
266
  );
267
+ const ranges = memberRanges.slice(
268
+ 0,
269
+ memberRanges.length - (members.length - nonOptionalMembers.length)
270
+ );
261
271
  const expr =
262
272
  nonOptionalMembers !== members
263
273
  ? getNonOptionalMemberChain(
@@ -273,7 +283,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
273
283
  settings.name,
274
284
  expr.range,
275
285
  exportPresenceMode,
276
- settings.assertions
286
+ settings.assertions,
287
+ ranges
277
288
  );
278
289
  dep.directImport = members.length === 0;
279
290
  dep.call = true;
@@ -43,6 +43,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
43
43
  * @param {Range} range range
44
44
  * @param {TODO} exportPresenceMode export presence mode
45
45
  * @param {Assertions=} assertions assertions
46
+ * @param {Range[]=} idRanges ranges for members of ids; the two arrays are right-aligned
46
47
  */
47
48
  constructor(
48
49
  request,
@@ -51,12 +52,14 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
51
52
  name,
52
53
  range,
53
54
  exportPresenceMode,
54
- assertions
55
+ assertions,
56
+ idRanges // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
55
57
  ) {
56
58
  super(request, sourceOrder, assertions);
57
59
  this.ids = ids;
58
60
  this.name = name;
59
61
  this.range = range;
62
+ this.idRanges = idRanges;
60
63
  this.exportPresenceMode = exportPresenceMode;
61
64
  this.namespaceObjectAsContext = false;
62
65
  this.call = undefined;
@@ -258,6 +261,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
258
261
  write(this.ids);
259
262
  write(this.name);
260
263
  write(this.range);
264
+ write(this.idRanges);
261
265
  write(this.exportPresenceMode);
262
266
  write(this.namespaceObjectAsContext);
263
267
  write(this.call);
@@ -277,6 +281,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
277
281
  this.ids = read();
278
282
  this.name = read();
279
283
  this.range = read();
284
+ this.idRanges = read();
280
285
  this.exportPresenceMode = read();
281
286
  this.namespaceObjectAsContext = read();
282
287
  this.call = read();
@@ -310,14 +315,78 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
310
315
  // Skip rendering depending when dependency is conditional
311
316
  if (connection && !connection.isTargetActive(runtime)) return;
312
317
 
313
- const ids = dep.getIds(moduleGraph);
314
- const exportExpr = this._getCodeForIds(dep, source, templateContext, ids);
315
- const range = dep.range;
318
+ const ids = dep.getIds(moduleGraph); // determine minimal set of IDs.
319
+ let trimmedIds = this._trimIdsToThoseImported(ids, moduleGraph, dep);
320
+
321
+ let [rangeStart, rangeEnd] = dep.range;
322
+ if (trimmedIds.length !== ids.length) {
323
+ // The array returned from dep.idRanges is right-aligned with the array returned from dep.getIds.
324
+ // Meaning, the two arrays may not always have the same number of elements, but the last element of
325
+ // dep.idRanges corresponds to [the expression fragment to the left of] the last element of dep.getIds.
326
+ // Use this to find the correct replacement range based on the number of ids that were trimmed.
327
+ const idx =
328
+ dep.idRanges === undefined
329
+ ? -1 /* trigger failure case below */
330
+ : dep.idRanges.length + (trimmedIds.length - ids.length);
331
+ if (idx < 0 || idx >= dep.idRanges.length) {
332
+ // cspell:ignore minifiers
333
+ // Should not happen but we can't throw an error here because of backward compatibility with
334
+ // external plugins in wp5. Instead, we just disable trimming for now. This may break some minifiers.
335
+ trimmedIds = ids;
336
+ // TODO webpack 6 remove the "trimmedIds = ids" above and uncomment the following line instead.
337
+ // throw new Error("Missing range starts data for id replacement trimming.");
338
+ } else {
339
+ [rangeStart, rangeEnd] = dep.idRanges[idx];
340
+ }
341
+ }
342
+
343
+ const exportExpr = this._getCodeForIds(
344
+ dep,
345
+ source,
346
+ templateContext,
347
+ trimmedIds
348
+ );
316
349
  if (dep.shorthand) {
317
- source.insert(range[1], `: ${exportExpr}`);
350
+ source.insert(rangeEnd, `: ${exportExpr}`);
318
351
  } else {
319
- source.replace(range[0], range[1] - 1, exportExpr);
352
+ source.replace(rangeStart, rangeEnd - 1, exportExpr);
353
+ }
354
+ }
355
+
356
+ /**
357
+ * @summary Determine which IDs in the id chain are actually referring to namespaces or imports,
358
+ * and which are deeper member accessors on the imported object. Only the former should be re-rendered.
359
+ * @param {string[]} ids ids
360
+ * @param {ModuleGraph} moduleGraph moduleGraph
361
+ * @param {HarmonyImportSpecifierDependency} dependency dependency
362
+ * @returns {string[]} generated code
363
+ */
364
+ _trimIdsToThoseImported(ids, moduleGraph, dependency) {
365
+ let trimmedIds = [];
366
+ const exportsInfo = moduleGraph.getExportsInfo(
367
+ moduleGraph.getModule(dependency)
368
+ );
369
+ let currentExportsInfo = /** @type {ExportsInfo=} */ exportsInfo;
370
+ for (let i = 0; i < ids.length; i++) {
371
+ if (i === 0 && ids[i] === "default") {
372
+ continue; // ExportInfo for the next level under default is still at the root ExportsInfo, so don't advance currentExportsInfo
373
+ }
374
+ const exportInfo = currentExportsInfo.getExportInfo(ids[i]);
375
+ if (exportInfo.provided === false) {
376
+ // json imports have nested ExportInfo for elements that things that are not actually exported, so check .provided
377
+ trimmedIds = ids.slice(0, i);
378
+ break;
379
+ }
380
+ const nestedInfo = exportInfo.getNestedExportsInfo();
381
+ if (!nestedInfo) {
382
+ // once all nested exports are traversed, the next item is the actual import so stop there
383
+ trimmedIds = ids.slice(0, i + 1);
384
+ break;
385
+ }
386
+ currentExportsInfo = nestedInfo;
320
387
  }
388
+ // Never trim to nothing. This can happen for invalid imports (e.g. import { notThere } from "./module", or import { anything } from "./missingModule")
389
+ return trimmedIds.length ? trimmedIds : ids;
321
390
  }
322
391
 
323
392
  /**
@@ -43,6 +43,8 @@ const getUrl = module => {
43
43
  return pathToFileURL(module.resource).toString();
44
44
  };
45
45
 
46
+ const WorkerSpecifierTag = Symbol("worker specifier tag");
47
+
46
48
  const DEFAULT_SYNTAX = [
47
49
  "Worker",
48
50
  "SharedWorker",
@@ -381,7 +383,29 @@ class WorkerPlugin {
381
383
  return true;
382
384
  };
383
385
  const processItem = item => {
384
- if (item.endsWith("()")) {
386
+ if (
387
+ item.startsWith("*") &&
388
+ item.includes(".") &&
389
+ item.endsWith("()")
390
+ ) {
391
+ const firstDot = item.indexOf(".");
392
+ const pattern = item.slice(1, firstDot);
393
+ const itemMembers = item.slice(firstDot + 1, -2);
394
+
395
+ parser.hooks.pattern.for(pattern).tap(PLUGIN_NAME, pattern => {
396
+ parser.tagVariable(pattern.name, WorkerSpecifierTag);
397
+ return true;
398
+ });
399
+ parser.hooks.callMemberChain
400
+ .for(WorkerSpecifierTag)
401
+ .tap(PLUGIN_NAME, (expression, members) => {
402
+ if (itemMembers !== members.join(".")) {
403
+ return;
404
+ }
405
+
406
+ return handleNewWorker(expression);
407
+ });
408
+ } else if (item.endsWith("()")) {
385
409
  parser.hooks.call
386
410
  .for(item.slice(0, -2))
387
411
  .tap(PLUGIN_NAME, handleNewWorker);