webpack 4.15.1 → 4.16.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.
Files changed (45) hide show
  1. package/hot/dev-server.js +2 -2
  2. package/hot/only-dev-server.js +2 -2
  3. package/hot/poll.js +5 -2
  4. package/hot/signal.js +2 -2
  5. package/lib/AutomaticPrefetchPlugin.js +1 -1
  6. package/lib/Chunk.js +3 -3
  7. package/lib/ChunkGroup.js +1 -1
  8. package/lib/CommentCompilationWarning.js +2 -2
  9. package/lib/CompatibilityPlugin.js +1 -1
  10. package/lib/Compilation.js +7 -4
  11. package/lib/ContextModule.js +20 -1
  12. package/lib/DelegatedModuleFactoryPlugin.js +7 -1
  13. package/lib/Dependency.js +10 -4
  14. package/lib/Entrypoint.js +1 -1
  15. package/lib/EnvironmentPlugin.js +8 -1
  16. package/lib/Generator.js +1 -1
  17. package/lib/HotModuleReplacementPlugin.js +1 -1
  18. package/lib/IgnorePlugin.js +1 -1
  19. package/lib/SingleEntryPlugin.js +6 -1
  20. package/lib/Stats.js +10 -4
  21. package/lib/UseStrictPlugin.js +1 -1
  22. package/lib/WebpackOptionsApply.js +92 -10
  23. package/lib/WebpackOptionsDefaulter.js +20 -6
  24. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +2 -1
  25. package/lib/dependencies/LoaderPlugin.js +18 -1
  26. package/lib/dependencies/SystemPlugin.js +1 -1
  27. package/lib/formatLocation.js +55 -41
  28. package/lib/node/NodeMainTemplatePlugin.js +2 -2
  29. package/lib/node/NodeSourcePlugin.js +1 -1
  30. package/lib/optimize/NaturalChunkOrderPlugin.js +41 -0
  31. package/lib/optimize/OccurrenceChunkOrderPlugin.js +61 -0
  32. package/lib/optimize/OccurrenceModuleOrderPlugin.js +103 -0
  33. package/lib/optimize/OccurrenceOrderPlugin.js +2 -0
  34. package/lib/optimize/SplitChunksPlugin.js +26 -16
  35. package/lib/util/cachedMerge.js +1 -1
  36. package/lib/util/deterministicGrouping.js +1 -1
  37. package/lib/wasm/WasmFinalizeExportsPlugin.js +1 -1
  38. package/lib/web/JsonpMainTemplatePlugin.js +1 -1
  39. package/lib/web/WebEnvironmentPlugin.js +18 -18
  40. package/lib/webpack.js +4 -0
  41. package/lib/webworker/WebWorkerMainTemplatePlugin.js +1 -1
  42. package/package.json +14 -5
  43. package/schemas/WebpackOptions.json +33 -3
  44. package/schemas/plugins/optimize/OccurrenceOrderChunkIdsPlugin.json +10 -0
  45. package/schemas/plugins/optimize/OccurrenceOrderModuleIdsPlugin.json +10 -0
package/hot/dev-server.js CHANGED
@@ -40,10 +40,10 @@ if (module.hot) {
40
40
  "warning",
41
41
  "[HMR] Cannot apply update. Need to do a full reload!"
42
42
  );
43
- log("warning", "[HMR] " + err.stack || err.message);
43
+ log("warning", "[HMR] " + (err.stack || err.message));
44
44
  window.location.reload();
45
45
  } else {
46
- log("warning", "[HMR] Update failed: " + err.stack || err.message);
46
+ log("warning", "[HMR] Update failed: " + (err.stack || err.message));
47
47
  }
48
48
  });
49
49
  };
@@ -72,11 +72,11 @@ if (module.hot) {
72
72
  "warning",
73
73
  "[HMR] Cannot check for update. Need to do a full reload!"
74
74
  );
75
- log("warning", "[HMR] " + err.stack || err.message);
75
+ log("warning", "[HMR] " + (err.stack || err.message));
76
76
  } else {
77
77
  log(
78
78
  "warning",
79
- "[HMR] Update check failed: " + err.stack || err.message
79
+ "[HMR] Update check failed: " + (err.stack || err.message)
80
80
  );
81
81
  }
82
82
  });
package/hot/poll.js CHANGED
@@ -23,10 +23,13 @@ if (module.hot) {
23
23
  var status = module.hot.status();
24
24
  if (["abort", "fail"].indexOf(status) >= 0) {
25
25
  log("warning", "[HMR] Cannot apply update.");
26
- log("warning", "[HMR] " + err.stack || err.message);
26
+ log("warning", "[HMR] " + (err.stack || err.message));
27
27
  log("warning", "[HMR] You need to restart the application!");
28
28
  } else {
29
- log("warning", "[HMR] Update failed: " + err.stack || err.message);
29
+ log(
30
+ "warning",
31
+ "[HMR] Update failed: " + (err.stack || err.message)
32
+ );
30
33
  }
31
34
  });
32
35
  }
package/hot/signal.js CHANGED
@@ -37,10 +37,10 @@ if (module.hot) {
37
37
  var status = module.hot.status();
38
38
  if (["abort", "fail"].indexOf(status) >= 0) {
39
39
  log("warning", "[HMR] Cannot apply update.");
40
- log("warning", "[HMR] " + err.stack || err.message);
40
+ log("warning", "[HMR] " + (err.stack || err.message));
41
41
  log("warning", "[HMR] You need to restart the application!");
42
42
  } else {
43
- log("warning", "[HMR] Update failed: " + err.stack || err.message);
43
+ log("warning", "[HMR] Update failed: " + (err.stack || err.message));
44
44
  }
45
45
  });
46
46
  };
@@ -8,7 +8,7 @@ const asyncLib = require("neo-async");
8
8
  const PrefetchDependency = require("./dependencies/PrefetchDependency");
9
9
  const NormalModule = require("./NormalModule");
10
10
 
11
- /** @typedef {import("./Compiler.js")} Compiler */
11
+ /** @typedef {import("./Compiler")} Compiler */
12
12
 
13
13
  class AutomaticPrefetchPlugin {
14
14
  /**
package/lib/Chunk.js CHANGED
@@ -13,9 +13,9 @@ const ERR_CHUNK_ENTRY = "Chunk.entry was removed. Use hasRuntime()";
13
13
  const ERR_CHUNK_INITIAL =
14
14
  "Chunk.initial was removed. Use canBeInitial/isOnlyInitial()";
15
15
 
16
- /** @typedef {import("./Module.js")} Module */
16
+ /** @typedef {import("./Module")} Module */
17
17
  /** @typedef {import("./ChunkGroup")} ChunkGroup */
18
- /** @typedef {import("./ModuleReason.js")} ModuleReason */
18
+ /** @typedef {import("./ModuleReason")} ModuleReason */
19
19
  /** @typedef {import("webpack-sources").Source} Source */
20
20
  /** @typedef {import("./util/createHash").Hash} Hash */
21
21
 
@@ -628,7 +628,7 @@ class Chunk {
628
628
  list.sort((a, b) => {
629
629
  const cmp = b.order - a.order;
630
630
  if (cmp !== 0) return cmp;
631
- // TOOD webpack 5 remove this check of compareTo
631
+ // TODO webpack 5 remove this check of compareTo
632
632
  if (a.group.compareTo) {
633
633
  return a.group.compareTo(b.group);
634
634
  }
package/lib/ChunkGroup.js CHANGED
@@ -442,7 +442,7 @@ class ChunkGroup {
442
442
  list.sort((a, b) => {
443
443
  const cmp = b.order - a.order;
444
444
  if (cmp !== 0) return cmp;
445
- // TOOD webpack 5 remove this check of compareTo
445
+ // TODO webpack 5 remove this check of compareTo
446
446
  if (a.group.compareTo) {
447
447
  return a.group.compareTo(b.group);
448
448
  }
@@ -6,9 +6,9 @@
6
6
 
7
7
  const WebpackError = require("./WebpackError");
8
8
 
9
- /** @typedef {import("./Module.js")} Module */
9
+ /** @typedef {import("./Module")} Module */
10
10
 
11
- /** @typedef {import("./Dependency.js").DependencyLocation} DependencyLocation */
11
+ /** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
12
12
 
13
13
  class CommentCompilationWarning extends WebpackError {
14
14
  /**
@@ -8,7 +8,7 @@ const ConstDependency = require("./dependencies/ConstDependency");
8
8
 
9
9
  const NullFactory = require("./NullFactory");
10
10
 
11
- /** @typedef {import("./Compiler.js")} Compiler */
11
+ /** @typedef {import("./Compiler")} Compiler */
12
12
 
13
13
  class CompatibilityPlugin {
14
14
  /**
@@ -26,7 +26,6 @@ const ChunkTemplate = require("./ChunkTemplate");
26
26
  const HotUpdateChunkTemplate = require("./HotUpdateChunkTemplate");
27
27
  const ModuleTemplate = require("./ModuleTemplate");
28
28
  const RuntimeTemplate = require("./RuntimeTemplate");
29
- const Dependency = require("./Dependency");
30
29
  const ChunkRenderError = require("./ChunkRenderError");
31
30
  const AsyncDependencyToInitialChunkError = require("./AsyncDependencyToInitialChunkError");
32
31
  const Stats = require("./Stats");
@@ -36,6 +35,7 @@ const Queue = require("./util/Queue");
36
35
  const SortableSet = require("./util/SortableSet");
37
36
  const GraphHelpers = require("./GraphHelpers");
38
37
  const ModuleDependency = require("./dependencies/ModuleDependency");
38
+ const compareLocations = require("./compareLocations");
39
39
 
40
40
  /** @typedef {import("./Module")} Module */
41
41
  /** @typedef {import("./Compiler")} Compiler */
@@ -642,7 +642,7 @@ class Compilation extends Tapable {
642
642
  war.dependencies = dependencies;
643
643
  this.warnings.push(war);
644
644
  }
645
- module.dependencies.sort(Dependency.compare);
645
+ module.dependencies.sort((a, b) => compareLocations(a.loc, b.loc));
646
646
  if (error) {
647
647
  this.hooks.failedModule.call(module, error);
648
648
  return callback(error);
@@ -1292,6 +1292,9 @@ class Compilation extends Tapable {
1292
1292
  * @returns {void}
1293
1293
  */
1294
1294
  sortModules(modules) {
1295
+ // TODO webpack 5: this should only be enabled when `moduleIds: "natural"`
1296
+ // TODO move it into a plugin (NaturalModuleIdsPlugin) and use this in WebpackOptionsApply
1297
+ // TODO remove this method
1295
1298
  modules.sort(byIndexOrIdentifier);
1296
1299
  }
1297
1300
 
@@ -1453,7 +1456,7 @@ class Compilation extends Tapable {
1453
1456
  * @returns {DependencyReference} a reference for the dependency
1454
1457
  */
1455
1458
  getDependencyReference(module, dependency) {
1456
- // TODO remove dep.getReference existance check in webpack 5
1459
+ // TODO remove dep.getReference existence check in webpack 5
1457
1460
  if (typeof dependency.getReference !== "function") return null;
1458
1461
  const ref = dependency.getReference();
1459
1462
  if (!ref) return null;
@@ -2113,7 +2116,7 @@ class Compilation extends Tapable {
2113
2116
 
2114
2117
  /**
2115
2118
  * Used to sort errors and warnings in compilation. this.warnings, and
2116
- * this.errors contribute to the compilation hash and therefore shoudl be
2119
+ * this.errors contribute to the compilation hash and therefore should be
2117
2120
  * updated whenever other references (having a chunk id) are sorted. This preserves the hash
2118
2121
  * integrity
2119
2122
  *
@@ -12,11 +12,28 @@ const contextify = require("./util/identifier").contextify;
12
12
 
13
13
  /** @typedef {import("./dependencies/ContextElementDependency")} ContextElementDependency */
14
14
 
15
+ /**
16
+ * @callback ResolveDependenciesCallback
17
+ * @param {Error=} err
18
+ * @param {ContextElementDependency[]} dependencies
19
+ */
20
+
21
+ /**
22
+ * @callback ResolveDependencies
23
+ * @param {TODO} fs
24
+ * @param {TODO} options
25
+ * @param {ResolveDependenciesCallback} callback
26
+ */
27
+
15
28
  class ContextModule extends Module {
16
29
  // type ContextMode = "sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"
17
30
  // type ContextOptions = { resource: string, recursive: boolean, regExp: RegExp, addon?: string, mode?: ContextMode, chunkName?: string, include?: RegExp, exclude?: RegExp, groupOptions?: Object }
18
31
  // resolveDependencies: (fs: FS, options: ContextOptions, (err: Error?, dependencies: Dependency[]) => void) => void
19
32
  // options: ContextOptions
33
+ /**
34
+ * @param {ResolveDependencies} resolveDependencies function to get dependencies in this context
35
+ * @param {TODO} options options object
36
+ */
20
37
  constructor(resolveDependencies, options) {
21
38
  let resource;
22
39
  let resourceQuery;
@@ -194,7 +211,9 @@ class ContextModule extends Module {
194
211
 
195
212
  // enhance dependencies with meta info
196
213
  for (const dep of dependencies) {
197
- dep.loc = dep.userRequest;
214
+ dep.loc = {
215
+ name: dep.userRequest
216
+ };
198
217
  dep.request = this.options.addon + dep.request;
199
218
  }
200
219
 
@@ -15,7 +15,13 @@ class DelegatedModuleFactoryPlugin {
15
15
  constructor(options) {
16
16
  this.options = options;
17
17
  options.type = options.type || "require";
18
- options.extensions = options.extensions || ["", ".js"];
18
+ options.extensions = options.extensions || [
19
+ "",
20
+ ".wasm",
21
+ ".mjs",
22
+ ".js",
23
+ ".json"
24
+ ];
19
25
  }
20
26
 
21
27
  apply(normalModuleFactory) {
package/lib/Dependency.js CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
+ const util = require("util");
7
8
  const compareLocations = require("./compareLocations");
8
9
  const DependencyReference = require("./dependencies/DependencyReference");
9
10
 
@@ -17,19 +18,19 @@ const DependencyReference = require("./dependencies/DependencyReference");
17
18
  */
18
19
 
19
20
  /** @typedef {Object} SourcePosition
20
- * @property {number} column
21
21
  * @property {number} line
22
+ * @property {number=} column
22
23
  */
23
24
 
24
25
  /** @typedef {Object} RealDependencyLocation
25
26
  * @property {SourcePosition} start
26
- * @property {SourcePosition} end
27
+ * @property {SourcePosition=} end
27
28
  * @property {number=} index
28
29
  */
29
30
 
30
31
  /** @typedef {Object} SynteticDependencyLocation
31
32
  * @property {string} name
32
- * @property {number} index
33
+ * @property {number=} index
33
34
  */
34
35
 
35
36
  /** @typedef {SynteticDependencyLocation|RealDependencyLocation} DependencyLocation */
@@ -78,6 +79,11 @@ class Dependency {
78
79
  this.module = null;
79
80
  }
80
81
  }
81
- Dependency.compare = (a, b) => compareLocations(a.loc, b.loc);
82
+
83
+ // TODO remove in webpack 5
84
+ Dependency.compare = util.deprecate(
85
+ (a, b) => compareLocations(a.loc, b.loc),
86
+ "Dependency.compare is deprecated and will be removed in the next major version"
87
+ );
82
88
 
83
89
  module.exports = Dependency;
package/lib/Entrypoint.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  const ChunkGroup = require("./ChunkGroup");
8
8
 
9
- /** @typedef {import("./Chunk.js")} Chunk */
9
+ /** @typedef {import("./Chunk")} Chunk */
10
10
 
11
11
  /**
12
12
  * Entrypoint serves as an encapsulation primitive for chunks that are
@@ -5,6 +5,9 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ /** @typedef {import("./Compiler")} Compiler */
9
+
10
+ const WebpackError = require("./WebpackError");
8
11
  const DefinePlugin = require("./DefinePlugin");
9
12
 
10
13
  const needsEnvVarFix =
@@ -25,6 +28,10 @@ class EnvironmentPlugin {
25
28
  }
26
29
  }
27
30
 
31
+ /**
32
+ * @param {Compiler} compiler webpack compiler instance
33
+ * @returns {void}
34
+ */
28
35
  apply(compiler) {
29
36
  const definitions = this.keys.reduce((defs, key) => {
30
37
  // TODO remove once the fix has made its way into Node 8.
@@ -41,7 +48,7 @@ class EnvironmentPlugin {
41
48
 
42
49
  if (value === undefined) {
43
50
  compiler.hooks.thisCompilation.tap("EnvironmentPlugin", compilation => {
44
- const error = new Error(
51
+ const error = new WebpackError(
45
52
  `EnvironmentPlugin - ${key} environment variable is undefined.\n\n` +
46
53
  "You can pass an object with default values to suppress this warning.\n" +
47
54
  "See https://webpack.js.org/plugins/environment-plugin for example."
package/lib/Generator.js CHANGED
@@ -25,7 +25,7 @@ class Generator {
25
25
  * @returns {Source} generated code
26
26
  */
27
27
  generate(module, dependencyTemplates, runtimeTemplate, type) {
28
- throw new Error("Generator.generate: must be overriden");
28
+ throw new Error("Generator.generate: must be overridden");
29
29
  }
30
30
  }
31
31
 
@@ -407,5 +407,5 @@ module.exports = class HotModuleReplacementPlugin {
407
407
  };
408
408
 
409
409
  const hotInitCode = Template.getFunctionContent(
410
- require("./HotModuleReplacement.runtime.js")
410
+ require("./HotModuleReplacement.runtime")
411
411
  );
@@ -4,7 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- /** @typedef {import("./Compiler.js")} Compiler */
7
+ /** @typedef {import("./Compiler")} Compiler */
8
8
 
9
9
  class IgnorePlugin {
10
10
  /**
@@ -48,9 +48,14 @@ class SingleEntryPlugin {
48
48
  );
49
49
  }
50
50
 
51
+ /**
52
+ * @param {string} entry entry request
53
+ * @param {string} name entry name
54
+ * @returns {SingleEntryDependency} the dependency
55
+ */
51
56
  static createDependency(entry, name) {
52
57
  const dep = new SingleEntryDependency(entry);
53
- dep.loc = name;
58
+ dep.loc = { name };
54
59
  return dep;
55
60
  }
56
61
  }
package/lib/Stats.js CHANGED
@@ -15,6 +15,12 @@ const optionsOrFallback = (...args) => {
15
15
  return optionValues.find(optionValue => typeof optionValue !== "undefined");
16
16
  };
17
17
 
18
+ const compareId = (a, b) => {
19
+ if (a < b) return -1;
20
+ if (a > b) return 1;
21
+ return 0;
22
+ };
23
+
18
24
  class Stats {
19
25
  constructor(compilation) {
20
26
  this.compilation = compilation;
@@ -543,7 +549,7 @@ class Stats {
543
549
  }
544
550
  return obj;
545
551
  })
546
- .sort((a, b) => a.moduleId - b.moduleId);
552
+ .sort(compareId);
547
553
  }
548
554
  if (showUsedExports) {
549
555
  if (module.used === true) {
@@ -614,9 +620,9 @@ class Stats {
614
620
  names: chunk.name ? [chunk.name] : [],
615
621
  files: chunk.files.slice(),
616
622
  hash: chunk.renderedHash,
617
- siblings: Array.from(siblings).sort(),
618
- parents: Array.from(parents).sort(),
619
- children: Array.from(children).sort(),
623
+ siblings: Array.from(siblings).sort(compareId),
624
+ parents: Array.from(parents).sort(compareId),
625
+ children: Array.from(children).sort(compareId),
620
626
  childrenByOrder: childIdByOrder
621
627
  };
622
628
  if (showChunkModules) {
@@ -6,7 +6,7 @@
6
6
 
7
7
  const ConstDependency = require("./dependencies/ConstDependency");
8
8
 
9
- /** @typedef {import("./Compiler.js")} Compiler */
9
+ /** @typedef {import("./Compiler")} Compiler */
10
10
 
11
11
  class UseStrictPlugin {
12
12
  /**
@@ -46,7 +46,9 @@ const RemoveParentModulesPlugin = require("./optimize/RemoveParentModulesPlugin"
46
46
  const RemoveEmptyChunksPlugin = require("./optimize/RemoveEmptyChunksPlugin");
47
47
  const MergeDuplicateChunksPlugin = require("./optimize/MergeDuplicateChunksPlugin");
48
48
  const FlagIncludedChunksPlugin = require("./optimize/FlagIncludedChunksPlugin");
49
- const OccurrenceOrderPlugin = require("./optimize/OccurrenceOrderPlugin");
49
+ const OccurrenceChunkOrderPlugin = require("./optimize/OccurrenceChunkOrderPlugin");
50
+ const OccurrenceModuleOrderPlugin = require("./optimize/OccurrenceModuleOrderPlugin");
51
+ const NaturalChunkOrderPlugin = require("./optimize/NaturalChunkOrderPlugin");
50
52
  const SideEffectsFlagPlugin = require("./optimize/SideEffectsFlagPlugin");
51
53
  const FlagDependencyUsagePlugin = require("./FlagDependencyUsagePlugin");
52
54
  const FlagDependencyExportsPlugin = require("./FlagDependencyExportsPlugin");
@@ -171,9 +173,13 @@ class WebpackOptionsApply extends OptionsApply {
171
173
  break;
172
174
  case "electron-renderer":
173
175
  JsonpTemplatePlugin = require("./web/JsonpTemplatePlugin");
176
+ FetchCompileWasmTemplatePlugin = require("./web/FetchCompileWasmTemplatePlugin");
174
177
  NodeTargetPlugin = require("./node/NodeTargetPlugin");
175
178
  ExternalsPlugin = require("./ExternalsPlugin");
176
179
  new JsonpTemplatePlugin().apply(compiler);
180
+ new FetchCompileWasmTemplatePlugin({
181
+ mangleImports: options.optimization.mangleWasmImports
182
+ }).apply(compiler);
177
183
  new FunctionModulePlugin().apply(compiler);
178
184
  new NodeTargetPlugin().apply(compiler);
179
185
  new ExternalsPlugin("commonjs", [
@@ -325,9 +331,6 @@ class WebpackOptionsApply extends OptionsApply {
325
331
  if (options.optimization.flagIncludedChunks) {
326
332
  new FlagIncludedChunksPlugin().apply(compiler);
327
333
  }
328
- if (options.optimization.occurrenceOrder) {
329
- new OccurrenceOrderPlugin(true).apply(compiler);
330
- }
331
334
  if (options.optimization.sideEffects) {
332
335
  new SideEffectsFlagPlugin().apply(compiler);
333
336
  }
@@ -352,14 +355,93 @@ class WebpackOptionsApply extends OptionsApply {
352
355
  if (options.optimization.checkWasmTypes) {
353
356
  new WasmFinalizeExportsPlugin().apply(compiler);
354
357
  }
355
- if (options.optimization.namedModules) {
356
- new NamedModulesPlugin().apply(compiler);
358
+ let moduleIds = options.optimization.moduleIds;
359
+ if (moduleIds === undefined) {
360
+ // TODO webpack 5 remove all these options
361
+ if (options.optimization.occurrenceOrder) {
362
+ moduleIds = "size";
363
+ }
364
+ if (options.optimization.namedModules) {
365
+ moduleIds = "named";
366
+ }
367
+ if (options.optimization.hashedModuleIds) {
368
+ moduleIds = "hashed";
369
+ }
370
+ if (moduleIds === undefined) {
371
+ moduleIds = "natural";
372
+ }
357
373
  }
358
- if (options.optimization.hashedModuleIds) {
359
- new HashedModuleIdsPlugin().apply(compiler);
374
+ if (moduleIds) {
375
+ switch (moduleIds) {
376
+ case "natural":
377
+ // TODO webpack 5: see hint in Compilation.sortModules
378
+ break;
379
+ case "named":
380
+ new NamedModulesPlugin().apply(compiler);
381
+ break;
382
+ case "hashed":
383
+ new HashedModuleIdsPlugin().apply(compiler);
384
+ break;
385
+ case "size":
386
+ new OccurrenceModuleOrderPlugin({
387
+ prioritiseInitial: true
388
+ }).apply(compiler);
389
+ break;
390
+ case "total-size":
391
+ new OccurrenceModuleOrderPlugin({
392
+ prioritiseInitial: false
393
+ }).apply(compiler);
394
+ break;
395
+ default:
396
+ throw new Error(
397
+ `webpack bug: moduleIds: ${moduleIds} is not implemented`
398
+ );
399
+ }
400
+ }
401
+ let chunkIds = options.optimization.chunkIds;
402
+ if (chunkIds === undefined) {
403
+ // TODO webpack 5 remove all these options
404
+ if (options.optimization.occurrenceOrder) {
405
+ // This looks weird but it's for backward-compat
406
+ // This bug already existed before adding this feature
407
+ chunkIds = "total-size";
408
+ }
409
+ if (options.optimization.namedChunks) {
410
+ chunkIds = "named";
411
+ }
412
+ if (chunkIds === undefined) {
413
+ chunkIds = "natural";
414
+ }
360
415
  }
361
- if (options.optimization.namedChunks) {
362
- new NamedChunksPlugin().apply(compiler);
416
+ if (chunkIds) {
417
+ switch (chunkIds) {
418
+ case "natural":
419
+ new NaturalChunkOrderPlugin().apply(compiler);
420
+ break;
421
+ case "named":
422
+ // TODO webapck 5: for backward-compat this need to have OccurrenceChunkOrderPlugin too
423
+ // The NamedChunksPlugin doesn't give every chunk a name
424
+ // This should be fixed, and the OccurrenceChunkOrderPlugin should be removed here.
425
+ new OccurrenceChunkOrderPlugin({
426
+ prioritiseInitial: false
427
+ }).apply(compiler);
428
+ new NamedChunksPlugin().apply(compiler);
429
+ break;
430
+ case "size":
431
+ new OccurrenceChunkOrderPlugin({
432
+ prioritiseInitial: true
433
+ }).apply(compiler);
434
+ break;
435
+ case "total-size":
436
+ new OccurrenceChunkOrderPlugin({
437
+ prioritiseInitial: false
438
+ }).apply(compiler);
439
+ break;
440
+ default:
441
+ throw new Error(
442
+ `webpack bug: chunkIds: ${chunkIds} is not implemented`
443
+ );
444
+ }
363
445
  }
364
446
  if (options.optimization.nodeEnv) {
365
447
  new DefinePlugin({
@@ -17,6 +17,16 @@ const isWebLikeTarget = options => {
17
17
  return options.target === "web" || options.target === "webworker";
18
18
  };
19
19
 
20
+ const getDevtoolNamespace = library => {
21
+ // if options.output.library is a string
22
+ if (Array.isArray(library)) {
23
+ return library.join(".");
24
+ } else if (typeof library === "object") {
25
+ return getDevtoolNamespace(library.root);
26
+ }
27
+ return library || "";
28
+ };
29
+
20
30
  class WebpackOptionsDefaulter extends OptionsDefaulter {
21
31
  constructor() {
22
32
  super();
@@ -136,12 +146,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
136
146
  }
137
147
  });
138
148
  this.set("output.devtoolNamespace", "make", options => {
139
- if (Array.isArray(options.output.library)) {
140
- return options.output.library.join(".");
141
- } else if (typeof options.output.library === "object") {
142
- return options.output.library.root || "";
143
- }
144
- return options.output.library || "";
149
+ return getDevtoolNamespace(options.output.library);
145
150
  });
146
151
  this.set("output.libraryTarget", "var");
147
152
  this.set("output.path", path.join(process.cwd(), "dist"));
@@ -201,6 +206,9 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
201
206
  this.set("optimization.flagIncludedChunks", "make", options =>
202
207
  isProductionLikeMode(options)
203
208
  );
209
+ // TODO webpack 5 add `moduleIds: "named"` default for development
210
+ // TODO webpack 5 add `moduleIds: "size"` default for production
211
+ // TODO webpack 5 remove optimization.occurrenceOrder
204
212
  this.set("optimization.occurrenceOrder", "make", options =>
205
213
  isProductionLikeMode(options)
206
214
  );
@@ -233,11 +241,13 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
233
241
  this.set("optimization.splitChunks.name", true);
234
242
  this.set("optimization.splitChunks.cacheGroups", {});
235
243
  this.set("optimization.splitChunks.cacheGroups.default", {
244
+ automaticNamePrefix: "",
236
245
  reuseExistingChunk: true,
237
246
  minChunks: 2,
238
247
  priority: -20
239
248
  });
240
249
  this.set("optimization.splitChunks.cacheGroups.vendors", {
250
+ automaticNamePrefix: "vendors",
241
251
  test: /[\\/]node_modules[\\/]/,
242
252
  priority: -10
243
253
  });
@@ -261,12 +271,16 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
261
271
  isProductionLikeMode(options)
262
272
  );
263
273
  this.set("optimization.mangleWasmImports", false);
274
+ // TODO webpack 5 remove optimization.namedModules
264
275
  this.set(
265
276
  "optimization.namedModules",
266
277
  "make",
267
278
  options => options.mode === "development"
268
279
  );
269
280
  this.set("optimization.hashedModuleIds", false);
281
+ // TODO webpack 5 add `chunkIds: "named"` default for development
282
+ // TODO webpack 5 add `chunkIds: "size"` default for production
283
+ // TODO webpack 5 remove optimization.namedChunks
270
284
  this.set(
271
285
  "optimization.namedChunks",
272
286
  "make",
@@ -244,7 +244,8 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
244
244
  return new DependencyReference(
245
245
  mode.module,
246
246
  Array.from(mode.map.values()),
247
- false
247
+ false,
248
+ this.sourceOrder
248
249
  );
249
250
 
250
251
  case "dynamic-reexport":
@@ -7,6 +7,16 @@
7
7
  const LoaderDependency = require("./LoaderDependency");
8
8
  const NormalModule = require("../NormalModule");
9
9
 
10
+ /** @typedef {import("../Module")} Module */
11
+
12
+ /**
13
+ * @callback LoadModuleCallback
14
+ * @param {Error=} err error object
15
+ * @param {string=} source source code
16
+ * @param {object=} map source map
17
+ * @param {Module=} module loaded module if successful
18
+ */
19
+
10
20
  class LoaderPlugin {
11
21
  apply(compiler) {
12
22
  compiler.hooks.compilation.tap(
@@ -23,9 +33,16 @@ class LoaderPlugin {
23
33
  compilation.hooks.normalModuleLoader.tap(
24
34
  "LoaderPlugin",
25
35
  (loaderContext, module) => {
36
+ /**
37
+ * @param {string} request the request string to load the module from
38
+ * @param {LoadModuleCallback} callback callback returning the loaded module or error
39
+ * @returns {void}
40
+ */
26
41
  loaderContext.loadModule = (request, callback) => {
27
42
  const dep = new LoaderDependency(request);
28
- dep.loc = request;
43
+ dep.loc = {
44
+ name: request
45
+ };
29
46
  const factory = compilation.dependencyFactories.get(
30
47
  dep.constructor
31
48
  );