webpack 5.41.0 → 5.43.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 (36) hide show
  1. package/bin/webpack.js +0 -0
  2. package/lib/Compiler.js +14 -1
  3. package/lib/ExternalModule.js +23 -0
  4. package/lib/FlagDependencyUsagePlugin.js +5 -1
  5. package/lib/NormalModuleFactory.js +13 -2
  6. package/lib/TemplatedPathPlugin.js +24 -26
  7. package/lib/WebpackOptionsApply.js +2 -1
  8. package/lib/asset/AssetGenerator.js +2 -2
  9. package/lib/cache/PackFileCacheStrategy.js +26 -15
  10. package/lib/config/defaults.js +1 -0
  11. package/lib/config/normalization.js +1 -0
  12. package/lib/container/ContainerPlugin.js +4 -1
  13. package/lib/container/ModuleFederationPlugin.js +1 -0
  14. package/lib/dependencies/WorkerPlugin.js +1 -1
  15. package/lib/json/JsonData.js +41 -0
  16. package/lib/json/JsonGenerator.js +8 -2
  17. package/lib/json/JsonParser.js +2 -1
  18. package/lib/optimize/ConcatenatedModule.js +16 -0
  19. package/lib/optimize/RuntimeChunkPlugin.js +1 -1
  20. package/lib/rules/RuleSetCompiler.js +2 -2
  21. package/lib/runtime/AsyncModuleRuntimeModule.js +8 -4
  22. package/lib/serialization/BinaryMiddleware.js +50 -35
  23. package/lib/serialization/FileMiddleware.js +112 -12
  24. package/lib/util/internalSerializables.js +1 -0
  25. package/lib/util/makeSerializable.js +0 -1
  26. package/package.json +7 -7
  27. package/schemas/WebpackOptions.check.js +1 -1
  28. package/schemas/WebpackOptions.json +20 -8
  29. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  30. package/schemas/plugins/container/ContainerPlugin.json +15 -0
  31. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  32. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -1
  33. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  34. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  35. package/schemas/plugins/container/ModuleFederationPlugin.json +17 -1
  36. package/types.d.ts +34 -14
package/bin/webpack.js CHANGED
File without changes
package/lib/Compiler.js CHANGED
@@ -260,6 +260,8 @@ class Compiler {
260
260
 
261
261
  /** @type {Compilation} */
262
262
  this._lastCompilation = undefined;
263
+ /** @type {NormalModuleFactory} */
264
+ this._lastNormalModuleFactory = undefined;
263
265
 
264
266
  /** @private @type {WeakMap<Source, { sizeOnlySource: SizeOnlySource, writtenTo: Map<string, number> }>} */
265
267
  this._assetEmittingSourceCache = new WeakMap();
@@ -375,6 +377,14 @@ class Compiler {
375
377
  }
376
378
  }
377
379
 
380
+ // TODO webpack 6: solve this in a better way
381
+ _cleanupLastNormalModuleFactory() {
382
+ if (this._lastNormalModuleFactory !== undefined) {
383
+ this._lastNormalModuleFactory.cleanupForCache();
384
+ this._lastNormalModuleFactory = undefined;
385
+ }
386
+ }
387
+
378
388
  /**
379
389
  * @param {WatchOptions} watchOptions the watcher's options
380
390
  * @param {Callback<Stats>} handler signals when the call finishes
@@ -1036,6 +1046,7 @@ ${other}`);
1036
1046
  }
1037
1047
 
1038
1048
  createNormalModuleFactory() {
1049
+ this._cleanupLastNormalModuleFactory();
1039
1050
  const normalModuleFactory = new NormalModuleFactory({
1040
1051
  context: this.options.context,
1041
1052
  fs: this.inputFileSystem,
@@ -1044,6 +1055,7 @@ ${other}`);
1044
1055
  associatedObjectForCache: this.root,
1045
1056
  layers: this.options.experiments.layers
1046
1057
  });
1058
+ this._lastNormalModuleFactory = normalModuleFactory;
1047
1059
  this.hooks.normalModuleFactory.call(normalModuleFactory);
1048
1060
  return normalModuleFactory;
1049
1061
  }
@@ -1122,8 +1134,9 @@ ${other}`);
1122
1134
  if (err) return callback(err);
1123
1135
  // Get rid of reference to last compilation to avoid leaking memory
1124
1136
  // We can't run this._cleanupLastCompilation() as the Stats to this compilation
1125
- // might be still in use. We try to get rid for the reference to the cache instead.
1137
+ // might be still in use. We try to get rid of the reference to the cache instead.
1126
1138
  this._lastCompilation = undefined;
1139
+ this._lastNormalModuleFactory = undefined;
1127
1140
  this.cache.shutdown(callback);
1128
1141
  });
1129
1142
  }
@@ -16,6 +16,7 @@ const StaticExportsDependency = require("./dependencies/StaticExportsDependency"
16
16
  const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
17
17
  const makeSerializable = require("./util/makeSerializable");
18
18
  const propertyAccess = require("./util/propertyAccess");
19
+ const { register } = require("./util/serialization");
19
20
 
20
21
  /** @typedef {import("webpack-sources").Source} Source */
21
22
  /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
@@ -169,6 +170,8 @@ class ModuleExternalInitFragment extends InitFragment {
169
170
  `external module import ${id}`
170
171
  );
171
172
  this._identifier = identifier;
173
+ this._id = id;
174
+ this._request = request;
172
175
  }
173
176
 
174
177
  getNamespaceIdentifier() {
@@ -176,6 +179,21 @@ class ModuleExternalInitFragment extends InitFragment {
176
179
  }
177
180
  }
178
181
 
182
+ register(
183
+ ModuleExternalInitFragment,
184
+ "webpack/lib/ExternalModule",
185
+ "ModuleExternalInitFragment",
186
+ {
187
+ serialize(obj, { write }) {
188
+ write(obj._id);
189
+ write(obj._request);
190
+ },
191
+ deserialize({ read }) {
192
+ return new ModuleExternalInitFragment(read(), read());
193
+ }
194
+ }
195
+ );
196
+
179
197
  const generateModuleRemapping = (input, exportsInfo, runtime) => {
180
198
  if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
181
199
  const properties = [];
@@ -429,6 +447,11 @@ class ExternalModule extends Module {
429
447
  this.buildInfo.strict = false;
430
448
  break;
431
449
  case "system":
450
+ if (!Array.isArray(request) || request.length === 1) {
451
+ this.buildMeta.exportsType = "namespace";
452
+ canMangle = true;
453
+ }
454
+ break;
432
455
  case "module":
433
456
  if (this.buildInfo.module) {
434
457
  if (!Array.isArray(request) || request.length === 1) {
@@ -180,7 +180,11 @@ class FlagDependencyUsagePlugin {
180
180
  b.groupOptions &&
181
181
  b.groupOptions.entryOptions
182
182
  ) {
183
- processModule(b, b.groupOptions.entryOptions.runtime, true);
183
+ processModule(
184
+ b,
185
+ b.groupOptions.entryOptions.runtime || undefined,
186
+ true
187
+ );
184
188
  } else {
185
189
  queue.enqueue(b);
186
190
  }
@@ -13,8 +13,10 @@ const {
13
13
  SyncHook,
14
14
  HookMap
15
15
  } = require("tapable");
16
+ const ChunkGraph = require("./ChunkGraph");
16
17
  const Module = require("./Module");
17
18
  const ModuleFactory = require("./ModuleFactory");
19
+ const ModuleGraph = require("./ModuleGraph");
18
20
  const NormalModule = require("./NormalModule");
19
21
  const BasicEffectRulePlugin = require("./rules/BasicEffectRulePlugin");
20
22
  const BasicMatcherRulePlugin = require("./rules/BasicMatcherRulePlugin");
@@ -257,8 +259,8 @@ class NormalModuleFactory extends ModuleFactory {
257
259
  this.parserCache = new Map();
258
260
  /** @type {Map<string, WeakMap<Object, Generator>>} */
259
261
  this.generatorCache = new Map();
260
- /** @type {WeakSet<Module>} */
261
- this._restoredUnsafeCacheEntries = new WeakSet();
262
+ /** @type {Set<Module>} */
263
+ this._restoredUnsafeCacheEntries = new Set();
262
264
 
263
265
  const cacheParseResource = parseResource.bindCache(
264
266
  associatedObjectForCache
@@ -661,6 +663,14 @@ class NormalModuleFactory extends ModuleFactory {
661
663
  );
662
664
  }
663
665
 
666
+ cleanupForCache() {
667
+ for (const module of this._restoredUnsafeCacheEntries) {
668
+ ChunkGraph.clearChunkGraphForModule(module);
669
+ ModuleGraph.clearModuleGraphForModule(module);
670
+ module.cleanupForCache();
671
+ }
672
+ }
673
+
664
674
  /**
665
675
  * @param {ModuleFactoryCreateData} data data object
666
676
  * @param {function(Error=, ModuleFactoryResult=): void} callback callback
@@ -756,6 +766,7 @@ class NormalModuleFactory extends ModuleFactory {
756
766
  if (!unsafeCacheData.has(module)) {
757
767
  unsafeCacheData.set(module, module.getUnsafeCacheData());
758
768
  }
769
+ this._restoredUnsafeCacheEntries.add(module);
759
770
  }
760
771
 
761
772
  callback(null, factoryResult);
@@ -116,32 +116,30 @@ const replacePathVariables = (path, data, assetInfo) => {
116
116
  // [path] - /some/path/
117
117
  // [name] - file
118
118
  // [ext] - .js
119
- if (data.filename) {
120
- if (typeof data.filename === "string") {
121
- const { path: file, query, fragment } = parseResource(data.filename);
122
-
123
- const ext = extname(file);
124
- const base = basename(file);
125
- const name = base.slice(0, base.length - ext.length);
126
- const path = file.slice(0, file.length - base.length);
127
-
128
- replacements.set("file", replacer(file));
129
- replacements.set("query", replacer(query, true));
130
- replacements.set("fragment", replacer(fragment, true));
131
- replacements.set("path", replacer(path, true));
132
- replacements.set("base", replacer(base));
133
- replacements.set("name", replacer(name));
134
- replacements.set("ext", replacer(ext, true));
135
- // Legacy
136
- replacements.set(
137
- "filebase",
138
- deprecated(
139
- replacer(base),
140
- "[filebase] is now [base]",
141
- "DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME"
142
- )
143
- );
144
- }
119
+ if (typeof data.filename === "string") {
120
+ const { path: file, query, fragment } = parseResource(data.filename);
121
+
122
+ const ext = extname(file);
123
+ const base = basename(file);
124
+ const name = base.slice(0, base.length - ext.length);
125
+ const path = file.slice(0, file.length - base.length);
126
+
127
+ replacements.set("file", replacer(file));
128
+ replacements.set("query", replacer(query, true));
129
+ replacements.set("fragment", replacer(fragment, true));
130
+ replacements.set("path", replacer(path, true));
131
+ replacements.set("base", replacer(base));
132
+ replacements.set("name", replacer(name));
133
+ replacements.set("ext", replacer(ext, true));
134
+ // Legacy
135
+ replacements.set(
136
+ "filebase",
137
+ deprecated(
138
+ replacer(base),
139
+ "[filebase] is now [base]",
140
+ "DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME"
141
+ )
142
+ );
145
143
  }
146
144
 
147
145
  // Compilation context
@@ -572,7 +572,8 @@ class WebpackOptionsApply extends OptionsApply {
572
572
  snapshot: options.snapshot,
573
573
  maxAge: cacheOptions.maxAge,
574
574
  profile: cacheOptions.profile,
575
- allowCollectingMemory: cacheOptions.allowCollectingMemory
575
+ allowCollectingMemory: cacheOptions.allowCollectingMemory,
576
+ compression: cacheOptions.compression
576
577
  }),
577
578
  cacheOptions.idleTimeout,
578
579
  cacheOptions.idleTimeoutForInitialStore,
@@ -265,7 +265,7 @@ class AssetGenerator extends Generator {
265
265
  * @returns {Set<string>} available types (do not mutate)
266
266
  */
267
267
  getTypes(module) {
268
- if (module.buildInfo.dataUrl || this.emit === false) {
268
+ if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) {
269
269
  return JS_TYPES;
270
270
  } else {
271
271
  return JS_AND_ASSET_TYPES;
@@ -289,7 +289,7 @@ class AssetGenerator extends Generator {
289
289
  return originalSource.size();
290
290
  }
291
291
  default:
292
- if (module.buildInfo.dataUrl) {
292
+ if (module.buildInfo && module.buildInfo.dataUrl) {
293
293
  const originalSource = module.originalSource();
294
294
 
295
295
  if (!originalSource) {
@@ -848,6 +848,7 @@ class PackFileCacheStrategy {
848
848
  * @param {number} options.maxAge max age of cache items
849
849
  * @param {boolean} options.profile track and log detailed timing information for individual cache items
850
850
  * @param {boolean} options.allowCollectingMemory allow to collect unused memory created during deserialization
851
+ * @param {false | "gzip" | "brotli"} options.compression compression used
851
852
  */
852
853
  constructor({
853
854
  compiler,
@@ -859,7 +860,8 @@ class PackFileCacheStrategy {
859
860
  snapshot,
860
861
  maxAge,
861
862
  profile,
862
- allowCollectingMemory
863
+ allowCollectingMemory,
864
+ compression
863
865
  }) {
864
866
  this.fileSerializer = createFileSerializer(fs);
865
867
  this.fileSystemInfo = new FileSystemInfo(fs, {
@@ -875,6 +877,13 @@ class PackFileCacheStrategy {
875
877
  this.maxAge = maxAge;
876
878
  this.profile = profile;
877
879
  this.allowCollectingMemory = allowCollectingMemory;
880
+ this.compression = compression;
881
+ this._extension =
882
+ compression === "brotli"
883
+ ? ".pack.br"
884
+ : compression === "gzip"
885
+ ? ".pack.gz"
886
+ : ".pack";
878
887
  this.snapshot = snapshot;
879
888
  /** @type {Set<string>} */
880
889
  this.buildDependencies = new Set();
@@ -916,8 +925,8 @@ class PackFileCacheStrategy {
916
925
  logger.time("restore cache container");
917
926
  return this.fileSerializer
918
927
  .deserialize(null, {
919
- filename: `${cacheLocation}/index.pack`,
920
- extension: ".pack",
928
+ filename: `${cacheLocation}/index${this._extension}`,
929
+ extension: `${this._extension}`,
921
930
  logger,
922
931
  profile,
923
932
  retainedBuffer: this.allowCollectingMemory
@@ -927,11 +936,13 @@ class PackFileCacheStrategy {
927
936
  .catch(err => {
928
937
  if (err.code !== "ENOENT") {
929
938
  logger.warn(
930
- `Restoring pack failed from ${cacheLocation}.pack: ${err}`
939
+ `Restoring pack failed from ${cacheLocation}${this._extension}: ${err}`
931
940
  );
932
941
  logger.debug(err.stack);
933
942
  } else {
934
- logger.debug(`No pack exists at ${cacheLocation}.pack: ${err}`);
943
+ logger.debug(
944
+ `No pack exists at ${cacheLocation}${this._extension}: ${err}`
945
+ );
935
946
  }
936
947
  return undefined;
937
948
  })
@@ -940,14 +951,14 @@ class PackFileCacheStrategy {
940
951
  if (!packContainer) return undefined;
941
952
  if (!(packContainer instanceof PackContainer)) {
942
953
  logger.warn(
943
- `Restored pack from ${cacheLocation}.pack, but contained content is unexpected.`,
954
+ `Restored pack from ${cacheLocation}${this._extension}, but contained content is unexpected.`,
944
955
  packContainer
945
956
  );
946
957
  return undefined;
947
958
  }
948
959
  if (packContainer.version !== version) {
949
960
  logger.log(
950
- `Restored pack from ${cacheLocation}.pack, but version doesn't match.`
961
+ `Restored pack from ${cacheLocation}${this._extension}, but version doesn't match.`
951
962
  );
952
963
  return undefined;
953
964
  }
@@ -959,14 +970,14 @@ class PackFileCacheStrategy {
959
970
  (err, valid) => {
960
971
  if (err) {
961
972
  logger.log(
962
- `Restored pack from ${cacheLocation}.pack, but checking snapshot of build dependencies errored: ${err}.`
973
+ `Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of build dependencies errored: ${err}.`
963
974
  );
964
975
  logger.debug(err.stack);
965
976
  return resolve(false);
966
977
  }
967
978
  if (!valid) {
968
979
  logger.log(
969
- `Restored pack from ${cacheLocation}.pack, but build dependencies have changed.`
980
+ `Restored pack from ${cacheLocation}${this._extension}, but build dependencies have changed.`
970
981
  );
971
982
  return resolve(false);
972
983
  }
@@ -981,7 +992,7 @@ class PackFileCacheStrategy {
981
992
  (err, valid) => {
982
993
  if (err) {
983
994
  logger.log(
984
- `Restored pack from ${cacheLocation}.pack, but checking snapshot of resolving of build dependencies errored: ${err}.`
995
+ `Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of resolving of build dependencies errored: ${err}.`
985
996
  );
986
997
  logger.debug(err.stack);
987
998
  return resolve(false);
@@ -1001,7 +1012,7 @@ class PackFileCacheStrategy {
1001
1012
  (err, valid) => {
1002
1013
  if (err) {
1003
1014
  logger.log(
1004
- `Restored pack from ${cacheLocation}.pack, but resolving of build dependencies errored: ${err}.`
1015
+ `Restored pack from ${cacheLocation}${this._extension}, but resolving of build dependencies errored: ${err}.`
1005
1016
  );
1006
1017
  logger.debug(err.stack);
1007
1018
  return resolve(false);
@@ -1012,7 +1023,7 @@ class PackFileCacheStrategy {
1012
1023
  return resolve(true);
1013
1024
  }
1014
1025
  logger.log(
1015
- `Restored pack from ${cacheLocation}.pack, but build dependencies resolve to different locations.`
1026
+ `Restored pack from ${cacheLocation}${this._extension}, but build dependencies resolve to different locations.`
1016
1027
  );
1017
1028
  return resolve(false);
1018
1029
  }
@@ -1052,7 +1063,7 @@ class PackFileCacheStrategy {
1052
1063
  })
1053
1064
  .catch(err => {
1054
1065
  this.logger.warn(
1055
- `Restoring pack from ${cacheLocation}.pack failed: ${err}`
1066
+ `Restoring pack from ${cacheLocation}${this._extension} failed: ${err}`
1056
1067
  );
1057
1068
  this.logger.debug(err.stack);
1058
1069
  return new Pack(logger, this.maxAge);
@@ -1236,8 +1247,8 @@ class PackFileCacheStrategy {
1236
1247
  );
1237
1248
  return this.fileSerializer
1238
1249
  .serialize(content, {
1239
- filename: `${this.cacheLocation}/index.pack`,
1240
- extension: ".pack",
1250
+ filename: `${this.cacheLocation}/index${this._extension}`,
1251
+ extension: `${this._extension}`,
1241
1252
  logger: this.logger,
1242
1253
  profile: this.profile
1243
1254
  })
@@ -298,6 +298,7 @@ const applyCacheDefaults = (cache, { name, mode, development }) => {
298
298
  );
299
299
  D(cache, "hashAlgorithm", "md4");
300
300
  D(cache, "store", "pack");
301
+ D(cache, "compression", development ? false : "gzip");
301
302
  D(cache, "profile", false);
302
303
  D(cache, "idleTimeout", 60000);
303
304
  D(cache, "idleTimeoutForInitialStore", 5000);
@@ -137,6 +137,7 @@ const getNormalizedWebpackOptions = config => {
137
137
  cacheDirectory: cache.cacheDirectory,
138
138
  cacheLocation: cache.cacheLocation,
139
139
  hashAlgorithm: cache.hashAlgorithm,
140
+ compression: cache.compression,
140
141
  idleTimeout: cache.idleTimeout,
141
142
  idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore,
142
143
  idleTimeoutAfterLargeChanges: cache.idleTimeoutAfterLargeChanges,
@@ -39,6 +39,7 @@ class ContainerPlugin {
39
39
  type: "var",
40
40
  name: options.name
41
41
  },
42
+ runtime: options.runtime,
42
43
  filename: options.filename || undefined,
43
44
  exposes: parseOptions(
44
45
  options.exposes,
@@ -60,7 +61,8 @@ class ContainerPlugin {
60
61
  * @returns {void}
61
62
  */
62
63
  apply(compiler) {
63
- const { name, exposes, shareScope, filename, library } = this._options;
64
+ const { name, exposes, shareScope, filename, library, runtime } =
65
+ this._options;
64
66
 
65
67
  compiler.options.output.enabledLibraryTypes.push(library.type);
66
68
 
@@ -73,6 +75,7 @@ class ContainerPlugin {
73
75
  {
74
76
  name,
75
77
  filename,
78
+ runtime,
76
79
  library
77
80
  },
78
81
  error => {
@@ -64,6 +64,7 @@ class ModuleFederationPlugin {
64
64
  name: options.name,
65
65
  library,
66
66
  filename: options.filename,
67
+ runtime: options.runtime,
67
68
  exposes: options.exposes
68
69
  }).apply(compiler);
69
70
  }
@@ -270,7 +270,7 @@ class WorkerPlugin {
270
270
  entryOptions.name = options.name;
271
271
  }
272
272
 
273
- if (!entryOptions.runtime) {
273
+ if (entryOptions.runtime === undefined) {
274
274
  let i = workerIndexMap.get(parser.state) || 0;
275
275
  workerIndexMap.set(parser.state, i + 1);
276
276
  let name = `${cachedContextify(
@@ -0,0 +1,41 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { register } = require("../util/serialization");
9
+
10
+ class JsonData {
11
+ constructor(data) {
12
+ this._buffer = undefined;
13
+ this._data = undefined;
14
+ if (Buffer.isBuffer(data)) {
15
+ this._buffer = data;
16
+ } else {
17
+ this._data = data;
18
+ }
19
+ }
20
+
21
+ get() {
22
+ if (this._data === undefined && this._buffer !== undefined) {
23
+ this._data = JSON.parse(this._buffer.toString());
24
+ }
25
+ return this._data;
26
+ }
27
+ }
28
+
29
+ register(JsonData, "webpack/lib/json/JsonData", null, {
30
+ serialize(obj, { write }) {
31
+ if (obj._buffer === undefined && obj._data !== undefined) {
32
+ obj._buffer = Buffer.from(JSON.stringify(obj._data));
33
+ }
34
+ write(obj._buffer);
35
+ },
36
+ deserialize({ read }) {
37
+ return new JsonData(read());
38
+ }
39
+ });
40
+
41
+ module.exports = JsonData;
@@ -116,7 +116,10 @@ class JsonGenerator extends Generator {
116
116
  * @returns {number} estimate size of the module
117
117
  */
118
118
  getSize(module, type) {
119
- let data = module.buildInfo.jsonData;
119
+ let data =
120
+ module.buildInfo &&
121
+ module.buildInfo.jsonData &&
122
+ module.buildInfo.jsonData.get();
120
123
  if (!data) return 0;
121
124
  return stringifySafe(data).length + 10;
122
125
  }
@@ -145,7 +148,10 @@ class JsonGenerator extends Generator {
145
148
  concatenationScope
146
149
  }
147
150
  ) {
148
- const data = module.buildInfo.jsonData;
151
+ const data =
152
+ module.buildInfo &&
153
+ module.buildInfo.jsonData &&
154
+ module.buildInfo.jsonData.get();
149
155
  if (data === undefined) {
150
156
  return new RawSource(
151
157
  runtimeTemplate.missingModuleStatement({
@@ -8,6 +8,7 @@
8
8
  const parseJson = require("json-parse-better-errors");
9
9
  const Parser = require("../Parser");
10
10
  const JsonExportsDependency = require("../dependencies/JsonExportsDependency");
11
+ const JsonData = require("./JsonData");
11
12
 
12
13
  /** @typedef {import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions} JsonModulesPluginParserOptions */
13
14
  /** @typedef {import("../Parser").ParserState} ParserState */
@@ -41,7 +42,7 @@ class JsonParser extends Parser {
41
42
  ? source
42
43
  : parseFn(source[0] === "\ufeff" ? source.slice(1) : source);
43
44
 
44
- state.module.buildInfo.jsonData = data;
45
+ state.module.buildInfo.jsonData = new JsonData(data);
45
46
  state.module.buildInfo.strict = true;
46
47
  state.module.buildMeta.exportsType = "default";
47
48
  state.module.buildMeta.defaultObject =
@@ -45,6 +45,7 @@ const {
45
45
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
46
46
  /** @typedef {import("../DependencyTemplates")} DependencyTemplates */
47
47
  /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
48
+ /** @template T @typedef {import("../InitFragment")<T>} InitFragment */
48
49
  /** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
49
50
  /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
50
51
  /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
@@ -55,6 +56,7 @@ const {
55
56
  /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
56
57
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
57
58
  /** @typedef {import("../WebpackError")} WebpackError */
59
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
58
60
  /** @typedef {import("../util/Hash")} Hash */
59
61
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
60
62
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
@@ -104,6 +106,7 @@ if (!ReferencerClass.prototype.PropertyDefinition) {
104
106
  * @property {Object} ast
105
107
  * @property {Source} internalSource
106
108
  * @property {ReplaceSource} source
109
+ * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
107
110
  * @property {Iterable<string>} runtimeRequirements
108
111
  * @property {Scope} globalScope
109
112
  * @property {Scope} moduleScope
@@ -1508,6 +1511,8 @@ ${defineGetters}`
1508
1511
  }
1509
1512
  }
1510
1513
 
1514
+ const chunkInitFragments = [];
1515
+
1511
1516
  // evaluate modules in order
1512
1517
  for (const rawInfo of modulesWithInfo) {
1513
1518
  let name;
@@ -1521,6 +1526,9 @@ ${defineGetters}`
1521
1526
  )}\n`
1522
1527
  );
1523
1528
  result.add(info.source);
1529
+ if (info.chunkInitFragments) {
1530
+ for (const f of info.chunkInitFragments) chunkInitFragments.push(f);
1531
+ }
1524
1532
  if (info.runtimeRequirements) {
1525
1533
  for (const r of info.runtimeRequirements) {
1526
1534
  runtimeRequirements.add(r);
@@ -1583,9 +1591,14 @@ ${defineGetters}`
1583
1591
  }
1584
1592
  }
1585
1593
 
1594
+ const data = new Map();
1595
+ if (chunkInitFragments.length > 0)
1596
+ data.set("chunkInitFragments", chunkInitFragments);
1597
+
1586
1598
  /** @type {CodeGenerationResult} */
1587
1599
  const resultEntry = {
1588
1600
  sources: new Map([["javascript", new CachedSource(result)]]),
1601
+ data,
1589
1602
  runtimeRequirements
1590
1603
  };
1591
1604
 
@@ -1626,6 +1639,8 @@ ${defineGetters}`
1626
1639
  concatenationScope
1627
1640
  });
1628
1641
  const source = codeGenResult.sources.get("javascript");
1642
+ const data = codeGenResult.data;
1643
+ const chunkInitFragments = data && data.get("chunkInitFragments");
1629
1644
  const code = source.source().toString();
1630
1645
  let ast;
1631
1646
  try {
@@ -1662,6 +1677,7 @@ ${defineGetters}`
1662
1677
  info.ast = ast;
1663
1678
  info.internalSource = source;
1664
1679
  info.source = resultSource;
1680
+ info.chunkInitFragments = chunkInitFragments;
1665
1681
  info.globalScope = globalScope;
1666
1682
  info.moduleScope = moduleScope;
1667
1683
  } catch (err) {
@@ -27,7 +27,7 @@ class RuntimeChunkPlugin {
27
27
  (_, { name: entryName }) => {
28
28
  if (entryName === undefined) return;
29
29
  const data = compilation.entries.get(entryName);
30
- if (!data.options.runtime && !data.options.dependOn) {
30
+ if (data.options.runtime === undefined && !data.options.dependOn) {
31
31
  // Determine runtime chunk name
32
32
  let name = this.options.name;
33
33
  if (typeof name === "function") {
@@ -225,7 +225,7 @@ class RuleSetCompiler {
225
225
  if (typeof condition === "string") {
226
226
  return {
227
227
  matchWhenEmpty: condition.length === 0,
228
- fn: str => str.startsWith(condition)
228
+ fn: str => typeof str === "string" && str.startsWith(condition)
229
229
  };
230
230
  }
231
231
  if (typeof condition === "function") {
@@ -245,7 +245,7 @@ class RuleSetCompiler {
245
245
  if (condition instanceof RegExp) {
246
246
  return {
247
247
  matchWhenEmpty: condition.test(""),
248
- fn: v => condition.test(v)
248
+ fn: v => typeof v === "string" && condition.test(v)
249
249
  };
250
250
  }
251
251
  if (Array.isArray(condition)) {
@@ -57,19 +57,23 @@ class AsyncModuleRuntimeModule extends HelperRuntimeModule {
57
57
  "completeQueue(queue);",
58
58
  "queue = 0;"
59
59
  ])});`,
60
- `var obj = { [webpackThen]: ${runtimeTemplate.expressionFunction(
60
+ `var obj = {};
61
+ obj[webpackThen] = ${runtimeTemplate.expressionFunction(
61
62
  "queueFunction(queue, fn), dep.catch(reject)",
62
63
  "fn, reject"
63
- )} };`,
64
+ )};`,
64
65
  "return obj;"
65
66
  ]),
66
67
  "}"
67
68
  ]),
68
69
  "}",
69
- `return { [webpackThen]: ${runtimeTemplate.expressionFunction(
70
+ `var ret = {};
71
+ ret[webpackThen] = ${runtimeTemplate.expressionFunction(
70
72
  "completeFunction(fn)",
71
73
  "fn"
72
- )}, [webpackExports]: dep };`
74
+ )};
75
+ ret[webpackExports] = dep;
76
+ return ret;`
73
77
  ])})`,
74
78
  "deps"
75
79
  )};`,