webpack 5.40.0 → 5.42.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 (50) hide show
  1. package/README.md +3 -3
  2. package/bin/webpack.js +0 -0
  3. package/lib/Compiler.js +14 -1
  4. package/lib/ConditionalInitFragment.js +15 -12
  5. package/lib/DependencyTemplate.js +3 -2
  6. package/lib/ExternalModule.js +213 -33
  7. package/lib/ExternalModuleFactoryPlugin.js +2 -1
  8. package/lib/InitFragment.js +10 -7
  9. package/lib/MainTemplate.js +1 -1
  10. package/lib/ModuleTemplate.js +0 -9
  11. package/lib/NormalModuleFactory.js +13 -2
  12. package/lib/RuntimeTemplate.js +8 -0
  13. package/lib/Template.js +3 -2
  14. package/lib/TemplatedPathPlugin.js +24 -26
  15. package/lib/Watching.js +2 -1
  16. package/lib/WebpackOptionsApply.js +12 -8
  17. package/lib/asset/AssetGenerator.js +2 -2
  18. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -1
  19. package/lib/cache/IdleFileCachePlugin.js +60 -13
  20. package/lib/cache/PackFileCacheStrategy.js +26 -15
  21. package/lib/config/defaults.js +54 -12
  22. package/lib/config/normalization.js +2 -0
  23. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  24. package/lib/dependencies/WorkerPlugin.js +25 -10
  25. package/lib/electron/ElectronTargetPlugin.js +3 -3
  26. package/lib/esm/ModuleChunkFormatPlugin.js +97 -0
  27. package/lib/esm/ModuleChunkLoadingPlugin.js +63 -0
  28. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +208 -0
  29. package/lib/hmr/lazyCompilationBackend.js +17 -1
  30. package/lib/javascript/EnableChunkLoadingPlugin.js +5 -3
  31. package/lib/javascript/JavascriptModulesPlugin.js +80 -17
  32. package/lib/javascript/JavascriptParser.js +2 -1
  33. package/lib/json/JsonGenerator.js +2 -2
  34. package/lib/node/NodeTargetPlugin.js +1 -1
  35. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +44 -22
  36. package/lib/optimize/ModuleConcatenationPlugin.js +1 -1
  37. package/lib/runtime/AsyncModuleRuntimeModule.js +8 -4
  38. package/lib/serialization/BinaryMiddleware.js +50 -35
  39. package/lib/serialization/FileMiddleware.js +112 -12
  40. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -1
  41. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +1 -1
  42. package/package.json +15 -15
  43. package/schemas/WebpackOptions.check.js +1 -1
  44. package/schemas/WebpackOptions.json +22 -8
  45. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  46. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -1
  47. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  48. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  49. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -1
  50. package/types.d.ts +105 -151
@@ -133,6 +133,14 @@ class RuntimeTemplate {
133
133
  );
134
134
  }
135
135
 
136
+ destructureObject(items, value) {
137
+ return this.supportsDestructuring()
138
+ ? `var {${items.join(", ")}} = ${value};`
139
+ : Template.asString(
140
+ items.map(item => `var ${item} = ${value}${propertyAccess([item])};`)
141
+ );
142
+ }
143
+
136
144
  iife(args, body) {
137
145
  return `(${this.basicFunction(args, body)})()`;
138
146
  }
package/lib/Template.js CHANGED
@@ -18,9 +18,10 @@ const { ConcatSource, PrefixSource } = require("webpack-sources");
18
18
  /** @typedef {import("./Module")} Module */
19
19
  /** @typedef {import("./ModuleGraph")} ModuleGraph */
20
20
  /** @typedef {import("./ModuleTemplate")} ModuleTemplate */
21
- /** @typedef {import("./ModuleTemplate").RenderContext} RenderContext */
22
21
  /** @typedef {import("./RuntimeModule")} RuntimeModule */
23
22
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
23
+ /** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
24
+ /** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
24
25
 
25
26
  const START_LOWERCASE_ALPHABET_CODE = "a".charCodeAt(0);
26
27
  const START_UPPERCASE_ALPHABET_CODE = "A".charCodeAt(0);
@@ -283,7 +284,7 @@ class Template {
283
284
  }
284
285
 
285
286
  /**
286
- * @param {RenderContext} renderContext render context
287
+ * @param {ChunkRenderContext} renderContext render context
287
288
  * @param {Module[]} modules modules to render (should be ordered by identifier)
288
289
  * @param {function(Module): Source} renderModule function to render a module
289
290
  * @param {string=} prefix applying prefix strings
@@ -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
package/lib/Watching.js CHANGED
@@ -86,7 +86,7 @@ class Watching {
86
86
 
87
87
  _go(fileTimeInfoEntries, contextTimeInfoEntries, changedFiles, removedFiles) {
88
88
  this._initial = false;
89
- this.startTime = Date.now();
89
+ if (this.startTime === null) this.startTime = Date.now();
90
90
  this.running = true;
91
91
  if (this.watcher) {
92
92
  this.pausedWatcher = this.watcher;
@@ -252,6 +252,7 @@ class Watching {
252
252
  compilation.endTime = Date.now();
253
253
  stats = new Stats(compilation);
254
254
  }
255
+ this.startTime = null;
255
256
  if (err) return handleError(err);
256
257
 
257
258
  const cbs = this.callbacks;
@@ -113,7 +113,7 @@ class WebpackOptionsApply extends OptionsApply {
113
113
  if (options.externalsPresets.nwjs) {
114
114
  //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
115
115
  const ExternalsPlugin = require("./ExternalsPlugin");
116
- new ExternalsPlugin("commonjs", "nw.gui").apply(compiler);
116
+ new ExternalsPlugin("node-commonjs", "nw.gui").apply(compiler);
117
117
  }
118
118
  if (options.externalsPresets.webAsync) {
119
119
  //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
@@ -139,10 +139,11 @@ class WebpackOptionsApply extends OptionsApply {
139
139
  new CommonJsChunkFormatPlugin().apply(compiler);
140
140
  break;
141
141
  }
142
- case "module":
143
- throw new Error(
144
- "EcmaScript Module Chunk Format is not implemented yet"
145
- );
142
+ case "module": {
143
+ const ModuleChunkFormatPlugin = require("./esm/ModuleChunkFormatPlugin");
144
+ new ModuleChunkFormatPlugin().apply(compiler);
145
+ break;
146
+ }
146
147
  default:
147
148
  throw new Error(
148
149
  "Unsupported chunk format '" + options.output.chunkFormat + "'."
@@ -317,7 +318,8 @@ class WebpackOptionsApply extends OptionsApply {
317
318
  new URLPlugin().apply(compiler);
318
319
  new WorkerPlugin(
319
320
  options.output.workerChunkLoading,
320
- options.output.workerWasmLoading
321
+ options.output.workerWasmLoading,
322
+ options.output.module
321
323
  ).apply(compiler);
322
324
 
323
325
  new DefaultStatsFactoryPlugin().apply(compiler);
@@ -570,10 +572,12 @@ class WebpackOptionsApply extends OptionsApply {
570
572
  snapshot: options.snapshot,
571
573
  maxAge: cacheOptions.maxAge,
572
574
  profile: cacheOptions.profile,
573
- allowCollectingMemory: cacheOptions.allowCollectingMemory
575
+ allowCollectingMemory: cacheOptions.allowCollectingMemory,
576
+ compression: cacheOptions.compression
574
577
  }),
575
578
  cacheOptions.idleTimeout,
576
- cacheOptions.idleTimeoutForInitialStore
579
+ cacheOptions.idleTimeoutForInitialStore,
580
+ cacheOptions.idleTimeoutAfterLargeChanges
577
581
  ).apply(compiler);
578
582
  break;
579
583
  }
@@ -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) {
@@ -12,6 +12,9 @@ const Template = require("../Template");
12
12
  /** @typedef {import("webpack-sources").Source} Source */
13
13
  /** @typedef {import("../Generator").GenerateContext} GenerateContext */
14
14
 
15
+ /**
16
+ * @typedef {GenerateContext} Context
17
+ */
15
18
  class AwaitDependenciesInitFragment extends InitFragment {
16
19
  /**
17
20
  * @param {Set<string>} promises the promises that should be awaited
@@ -35,7 +38,7 @@ class AwaitDependenciesInitFragment extends InitFragment {
35
38
  }
36
39
 
37
40
  /**
38
- * @param {GenerateContext} generateContext context for generate
41
+ * @param {Context} context context
39
42
  * @returns {string|Source} the source code that will be included as initialization code
40
43
  */
41
44
  getContent({ runtimeRequirements }) {
@@ -17,11 +17,18 @@ class IdleFileCachePlugin {
17
17
  * @param {TODO} strategy cache strategy
18
18
  * @param {number} idleTimeout timeout
19
19
  * @param {number} idleTimeoutForInitialStore initial timeout
20
+ * @param {number} idleTimeoutAfterLargeChanges timeout after changes
20
21
  */
21
- constructor(strategy, idleTimeout, idleTimeoutForInitialStore) {
22
+ constructor(
23
+ strategy,
24
+ idleTimeout,
25
+ idleTimeoutForInitialStore,
26
+ idleTimeoutAfterLargeChanges
27
+ ) {
22
28
  this.strategy = strategy;
23
29
  this.idleTimeout = idleTimeout;
24
30
  this.idleTimeoutForInitialStore = idleTimeoutForInitialStore;
31
+ this.idleTimeoutAfterLargeChanges = idleTimeoutAfterLargeChanges;
25
32
  }
26
33
 
27
34
  /**
@@ -36,9 +43,13 @@ class IdleFileCachePlugin {
36
43
  idleTimeout,
37
44
  this.idleTimeoutForInitialStore
38
45
  );
39
-
46
+ const idleTimeoutAfterLargeChanges = this.idleTimeoutAfterLargeChanges;
40
47
  const resolvedPromise = Promise.resolve();
41
48
 
49
+ let timeSpendInBuild = 0;
50
+ let timeSpendInStore = 0;
51
+ let avgTimeSpendInStore = 0;
52
+
42
53
  /** @type {Map<string | typeof BUILD_DEPENDENCIES_KEY, () => Promise>} */
43
54
  const pendingIdleTasks = new Map();
44
55
 
@@ -121,9 +132,10 @@ class IdleFileCachePlugin {
121
132
  let isInitialStore = true;
122
133
  const processIdleTasks = () => {
123
134
  if (isIdle) {
135
+ const startTime = Date.now();
124
136
  if (pendingIdleTasks.size > 0) {
125
137
  const promises = [currentIdlePromise];
126
- const maxTime = Date.now() + 100;
138
+ const maxTime = startTime + 100;
127
139
  let maxCount = 100;
128
140
  for (const [filename, factory] of pendingIdleTasks) {
129
141
  pendingIdleTasks.delete(filename);
@@ -132,13 +144,23 @@ class IdleFileCachePlugin {
132
144
  }
133
145
  currentIdlePromise = Promise.all(promises);
134
146
  currentIdlePromise.then(() => {
147
+ timeSpendInStore += Date.now() - startTime;
135
148
  // Allow to exit the process between
136
- setTimeout(processIdleTasks, 0).unref();
149
+ idleTimer = setTimeout(processIdleTasks, 0);
150
+ idleTimer.unref();
137
151
  });
138
152
  return;
139
153
  }
140
154
  currentIdlePromise = currentIdlePromise
141
- .then(() => strategy.afterAllStored())
155
+ .then(async () => {
156
+ await strategy.afterAllStored();
157
+ timeSpendInStore += Date.now() - startTime;
158
+ avgTimeSpendInStore =
159
+ Math.max(avgTimeSpendInStore, timeSpendInStore) * 0.9 +
160
+ timeSpendInStore * 0.1;
161
+ timeSpendInStore = 0;
162
+ timeSpendInBuild = 0;
163
+ })
142
164
  .catch(err => {
143
165
  const logger = compiler.getInfrastructureLogger(
144
166
  "IdleFileCachePlugin"
@@ -153,14 +175,34 @@ class IdleFileCachePlugin {
153
175
  compiler.cache.hooks.beginIdle.tap(
154
176
  { name: "IdleFileCachePlugin", stage: Cache.STAGE_DISK },
155
177
  () => {
156
- idleTimer = setTimeout(
157
- () => {
158
- idleTimer = undefined;
159
- isIdle = true;
160
- resolvedPromise.then(processIdleTasks);
161
- },
162
- isInitialStore ? idleTimeoutForInitialStore : idleTimeout
163
- );
178
+ const isLargeChange = timeSpendInBuild > avgTimeSpendInStore * 2;
179
+ if (isInitialStore && idleTimeoutForInitialStore < idleTimeout) {
180
+ compiler
181
+ .getInfrastructureLogger("IdleFileCachePlugin")
182
+ .log(
183
+ `Initial cache was generated and cache will be persisted in ${
184
+ idleTimeoutForInitialStore / 1000
185
+ }s.`
186
+ );
187
+ } else if (
188
+ isLargeChange &&
189
+ idleTimeoutAfterLargeChanges < idleTimeout
190
+ ) {
191
+ compiler
192
+ .getInfrastructureLogger("IdleFileCachePlugin")
193
+ .log(
194
+ `Spend ${Math.round(timeSpendInBuild) / 1000}s in build and ${
195
+ Math.round(avgTimeSpendInStore) / 1000
196
+ }s in average in cache store. This is considered as large change and cache will be persisted in ${
197
+ idleTimeoutAfterLargeChanges / 1000
198
+ }s.`
199
+ );
200
+ }
201
+ idleTimer = setTimeout(() => {
202
+ idleTimer = undefined;
203
+ isIdle = true;
204
+ resolvedPromise.then(processIdleTasks);
205
+ }, Math.min(isInitialStore ? idleTimeoutForInitialStore : Infinity, isLargeChange ? idleTimeoutAfterLargeChanges : Infinity, idleTimeout));
164
206
  idleTimer.unref();
165
207
  }
166
208
  );
@@ -174,6 +216,11 @@ class IdleFileCachePlugin {
174
216
  isIdle = false;
175
217
  }
176
218
  );
219
+ compiler.hooks.done.tap("IdleFileCachePlugin", stats => {
220
+ // 10% build overhead is ignored, as it's not cacheable
221
+ timeSpendInBuild *= 0.9;
222
+ timeSpendInBuild += stats.endTime - stats.startTime;
223
+ });
177
224
  }
178
225
  }
179
226
 
@@ -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
  })
@@ -182,6 +182,11 @@ const applyWebpackOptionsDefaults = options => {
182
182
  applyOutputDefaults(options.output, {
183
183
  context: options.context,
184
184
  targetProperties,
185
+ isAffectedByBrowserslist:
186
+ target === undefined ||
187
+ (typeof target === "string" && target.startsWith("browserslist")) ||
188
+ (Array.isArray(target) &&
189
+ target.some(target => target.startsWith("browserslist"))),
185
190
  outputModule: options.experiments.outputModule,
186
191
  development,
187
192
  entry: options.entry,
@@ -293,9 +298,11 @@ const applyCacheDefaults = (cache, { name, mode, development }) => {
293
298
  );
294
299
  D(cache, "hashAlgorithm", "md4");
295
300
  D(cache, "store", "pack");
301
+ D(cache, "compression", development ? false : "gzip");
296
302
  D(cache, "profile", false);
297
303
  D(cache, "idleTimeout", 60000);
298
- D(cache, "idleTimeoutForInitialStore", 0);
304
+ D(cache, "idleTimeoutForInitialStore", 5000);
305
+ D(cache, "idleTimeoutAfterLargeChanges", 1000);
299
306
  D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
300
307
  D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
301
308
  D(cache, "allowCollectingMemory", development);
@@ -543,6 +550,7 @@ const applyModuleDefaults = (
543
550
  * @param {Object} options options
544
551
  * @param {string} options.context context
545
552
  * @param {TargetProperties | false} options.targetProperties target properties
553
+ * @param {boolean} options.isAffectedByBrowserslist is affected by browserslist
546
554
  * @param {boolean} options.outputModule is outputModule experiment enabled
547
555
  * @param {boolean} options.development is development mode
548
556
  * @param {Entry} options.entry entry option
@@ -551,7 +559,15 @@ const applyModuleDefaults = (
551
559
  */
552
560
  const applyOutputDefaults = (
553
561
  output,
554
- { context, targetProperties: tp, outputModule, development, entry, module }
562
+ {
563
+ context,
564
+ targetProperties: tp,
565
+ isAffectedByBrowserslist,
566
+ outputModule,
567
+ development,
568
+ entry,
569
+ module
570
+ }
555
571
  ) => {
556
572
  /**
557
573
  * @param {Library=} library the library option
@@ -591,8 +607,8 @@ const applyOutputDefaults = (
591
607
  }
592
608
  });
593
609
 
594
- D(output, "filename", "[name].js");
595
610
  F(output, "module", () => !!outputModule);
611
+ D(output, "filename", output.module ? "[name].mjs" : "[name].js");
596
612
  F(output, "iife", () => !output.module);
597
613
  D(output, "importFunctionName", "import");
598
614
  D(output, "importMetaName", "import.meta");
@@ -608,7 +624,7 @@ const applyOutputDefaults = (
608
624
  // Otherwise prefix "[id]." in front of the basename to make it changing
609
625
  return filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2");
610
626
  }
611
- return "[id].js";
627
+ return output.module ? "[id].mjs" : "[id].js";
612
628
  });
613
629
  D(output, "assetModuleFilename", "[hash][ext][query]");
614
630
  D(output, "webassemblyModuleFilename", "[hash].module.wasm");
@@ -633,13 +649,34 @@ const applyOutputDefaults = (
633
649
  });
634
650
  F(output, "chunkFormat", () => {
635
651
  if (tp) {
636
- if (tp.document) return "array-push";
637
- if (tp.require) return "commonjs";
638
- if (tp.nodeBuiltins) return "commonjs";
639
- if (tp.importScripts) return "array-push";
640
- if (tp.dynamicImport && output.module) return "module";
652
+ const helpMessage = isAffectedByBrowserslist
653
+ ? "Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly."
654
+ : "Select an appropriate 'target' to allow selecting one by default, or specify the 'output.chunkFormat' directly.";
655
+ if (output.module) {
656
+ if (tp.dynamicImport) return "module";
657
+ if (tp.document) return "array-push";
658
+ throw new Error(
659
+ "For the selected environment is no default ESM chunk format available:\n" +
660
+ "ESM exports can be chosen when 'import()' is available.\n" +
661
+ "JSONP Array push can be chosen when 'document' is available.\n" +
662
+ helpMessage
663
+ );
664
+ } else {
665
+ if (tp.document) return "array-push";
666
+ if (tp.require) return "commonjs";
667
+ if (tp.nodeBuiltins) return "commonjs";
668
+ if (tp.importScripts) return "array-push";
669
+ throw new Error(
670
+ "For the selected environment is no default script chunk format available:\n" +
671
+ "JSONP Array push can be chosen when 'document' or 'importScripts' is available.\n" +
672
+ "CommonJs exports can be chosen when 'require' or node builtins are available.\n" +
673
+ helpMessage
674
+ );
675
+ }
641
676
  }
642
- return false;
677
+ throw new Error(
678
+ "Chunk format can't be selected by default when no target is specified"
679
+ );
643
680
  });
644
681
  F(output, "chunkLoading", () => {
645
682
  if (tp) {
@@ -694,7 +731,8 @@ const applyOutputDefaults = (
694
731
  F(output, "wasmLoading", () => {
695
732
  if (tp) {
696
733
  if (tp.fetchWasm) return "fetch";
697
- if (tp.nodeBuiltins) return "async-node";
734
+ if (tp.nodeBuiltins)
735
+ return output.module ? "async-node-module" : "async-node";
698
736
  if (tp.nodeBuiltins === null || tp.fetchWasm === null) {
699
737
  return "universal";
700
738
  }
@@ -709,7 +747,11 @@ const applyOutputDefaults = (
709
747
  F(output, "path", () => path.join(process.cwd(), "dist"));
710
748
  F(output, "pathinfo", () => development);
711
749
  D(output, "sourceMapFilename", "[file].map[query]");
712
- D(output, "hotUpdateChunkFilename", "[id].[fullhash].hot-update.js");
750
+ D(
751
+ output,
752
+ "hotUpdateChunkFilename",
753
+ `[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}`
754
+ );
713
755
  D(output, "hotUpdateMainFilename", "[runtime].[fullhash].hot-update.json");
714
756
  D(output, "crossOriginLoading", false);
715
757
  F(output, "scriptType", () => (output.module ? "module" : false));
@@ -137,8 +137,10 @@ 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,
143
+ idleTimeoutAfterLargeChanges: cache.idleTimeoutAfterLargeChanges,
142
144
  name: cache.name,
143
145
  store: cache.store,
144
146
  version: cache.version
@@ -31,6 +31,9 @@ const joinIterableWithComma = iterable => {
31
31
  const EMPTY_MAP = new Map();
32
32
  const EMPTY_SET = new Set();
33
33
 
34
+ /**
35
+ * @typedef {GenerateContext} Context
36
+ */
34
37
  class HarmonyExportInitFragment extends InitFragment {
35
38
  /**
36
39
  * @param {string} exportsArgument the exports identifier
@@ -126,7 +129,7 @@ class HarmonyExportInitFragment extends InitFragment {
126
129
  }
127
130
 
128
131
  /**
129
- * @param {GenerateContext} generateContext context for generate
132
+ * @param {Context} context context
130
133
  * @returns {string|Source} the source code that will be included as initialization code
131
134
  */
132
135
  getContent({ runtimeTemplate, runtimeRequirements }) {