webpack 4.16.0 → 4.16.4

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 (71) hide show
  1. package/README.md +5 -2
  2. package/SECURITY.md +9 -9
  3. package/buildin/global.js +20 -20
  4. package/buildin/module.js +22 -22
  5. package/hot/log-apply-result.js +44 -44
  6. package/hot/log.js +2 -0
  7. package/lib/BasicEvaluatedExpression.js +211 -211
  8. package/lib/Chunk.js +32 -10
  9. package/lib/ChunkGroup.js +3 -3
  10. package/lib/Compilation.js +47 -11
  11. package/lib/ContextExclusionPlugin.js +11 -0
  12. package/lib/ContextModule.js +116 -30
  13. package/lib/ContextModuleFactory.js +6 -0
  14. package/lib/DefinePlugin.js +49 -0
  15. package/lib/DelegatedModule.js +5 -0
  16. package/lib/DependenciesBlock.js +1 -1
  17. package/lib/DllModule.js +6 -0
  18. package/lib/DllReferencePlugin.js +51 -3
  19. package/lib/ExternalModule.js +6 -0
  20. package/lib/Generator.js +11 -3
  21. package/lib/HotModuleReplacementPlugin.js +1 -5
  22. package/lib/MemoryOutputFileSystem.js +5 -5
  23. package/lib/Module.js +52 -12
  24. package/lib/MultiModule.js +6 -0
  25. package/lib/NodeStuffPlugin.js +18 -0
  26. package/lib/NormalModule.js +6 -0
  27. package/lib/NullFactory.js +12 -12
  28. package/lib/OptionsApply.js +10 -10
  29. package/lib/Parser.js +12 -3
  30. package/lib/RuntimeTemplate.js +12 -0
  31. package/lib/Stats.js +19 -2
  32. package/lib/Template.js +44 -43
  33. package/lib/WatchIgnorePlugin.js +18 -18
  34. package/lib/debug/ProfilingPlugin.js +1 -1
  35. package/lib/dependencies/AMDRequireItemDependency.js +22 -22
  36. package/lib/dependencies/CommonJsRequireDependency.js +22 -22
  37. package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +6 -0
  38. package/lib/dependencies/CriticalDependencyWarning.js +20 -20
  39. package/lib/dependencies/DelegatedSourceDependency.js +18 -18
  40. package/lib/dependencies/DllEntryDependency.js +20 -20
  41. package/lib/dependencies/LocalModule.js +23 -23
  42. package/lib/dependencies/ModuleHotAcceptDependency.js +23 -23
  43. package/lib/dependencies/ModuleHotDeclineDependency.js +23 -23
  44. package/lib/dependencies/PrefetchDependency.js +18 -18
  45. package/lib/dependencies/RequireEnsureItemDependency.js +21 -21
  46. package/lib/dependencies/RequireResolveDependency.js +22 -22
  47. package/lib/node/NodeOutputFileSystem.js +22 -22
  48. package/lib/node/NodeTargetPlugin.js +1 -0
  49. package/lib/optimize/ConcatenatedModule.js +5 -0
  50. package/lib/optimize/OccurrenceChunkOrderPlugin.js +1 -1
  51. package/lib/optimize/OccurrenceModuleOrderPlugin.js +1 -1
  52. package/lib/optimize/OccurrenceOrderPlugin.js +2 -2
  53. package/lib/util/SortableSet.js +1 -0
  54. package/lib/util/StackedSetMap.js +12 -3
  55. package/lib/wasm/WebAssemblyGenerator.js +22 -5
  56. package/lib/wasm/WebAssemblyJavascriptGenerator.js +16 -2
  57. package/lib/webpack.js +1 -0
  58. package/package.json +12 -20
  59. package/schemas/WebpackOptions.json +2 -6
  60. package/schemas/ajv.absolutePath.js +55 -55
  61. package/schemas/plugins/BannerPlugin.json +96 -96
  62. package/schemas/plugins/DllPlugin.json +32 -32
  63. package/schemas/plugins/DllReferencePlugin.json +99 -99
  64. package/schemas/plugins/HashedModuleIdsPlugin.json +24 -24
  65. package/schemas/plugins/LoaderOptionsPlugin.json +26 -26
  66. package/schemas/plugins/SourceMapDevToolPlugin.json +187 -187
  67. package/schemas/plugins/WatchIgnorePlugin.json +16 -16
  68. package/schemas/plugins/debug/ProfilingPlugin.json +12 -12
  69. package/schemas/plugins/optimize/AggressiveSplittingPlugin.json +22 -22
  70. package/schemas/plugins/optimize/LimitChunkCountPlugin.json +15 -15
  71. package/schemas/plugins/optimize/MinChunkSizePlugin.json +13 -13
package/lib/Chunk.js CHANGED
@@ -8,6 +8,7 @@ const util = require("util");
8
8
  const SortableSet = require("./util/SortableSet");
9
9
  const intersect = require("./util/SetHelpers").intersect;
10
10
  const GraphHelpers = require("./GraphHelpers");
11
+ const Entrypoint = require("./Entrypoint");
11
12
  let debugId = 1000;
12
13
  const ERR_CHUNK_ENTRY = "Chunk.entry was removed. Use hasRuntime()";
13
14
  const ERR_CHUNK_INITIAL =
@@ -123,9 +124,6 @@ class Chunk {
123
124
  this._modules = new SortableSet(undefined, sortByIdentifier);
124
125
  /** @type {string?} */
125
126
  this.filenameTemplate = undefined;
126
-
127
- /** @private */
128
- this._groups = new SortableSet(undefined, sortChunkGroupById);
129
127
  /** @private @type {SortableSet<ChunkGroup>} */
130
128
  this._groups = new SortableSet(undefined, sortChunkGroupById);
131
129
  /** @type {string[]} */
@@ -185,7 +183,11 @@ class Chunk {
185
183
  hasRuntime() {
186
184
  for (const chunkGroup of this._groups) {
187
185
  // We only need to check the first one
188
- return chunkGroup.isInitial() && chunkGroup.getRuntimeChunk() === this;
186
+ return (
187
+ chunkGroup.isInitial() &&
188
+ chunkGroup instanceof Entrypoint &&
189
+ chunkGroup.getRuntimeChunk() === this
190
+ );
189
191
  }
190
192
  return false;
191
193
  }
@@ -749,17 +751,37 @@ class Chunk {
749
751
  // TODO remove in webpack 5
750
752
  Object.defineProperty(Chunk.prototype, "forEachModule", {
751
753
  configurable: false,
752
- value: util.deprecate(function(fn) {
753
- this._modules.forEach(fn);
754
- }, "Chunk.forEachModule: Use for(const module of chunk.modulesIterable) instead")
754
+ value: util.deprecate(
755
+ /**
756
+ * @deprecated
757
+ * @this {Chunk}
758
+ * @typedef {function(any, any, Set<any>): void} ForEachModuleCallback
759
+ * @param {ForEachModuleCallback} fn Callback function
760
+ * @returns {void}
761
+ */
762
+ function(fn) {
763
+ this._modules.forEach(fn);
764
+ },
765
+ "Chunk.forEachModule: Use for(const module of chunk.modulesIterable) instead"
766
+ )
755
767
  });
756
768
 
757
769
  // TODO remove in webpack 5
758
770
  Object.defineProperty(Chunk.prototype, "mapModules", {
759
771
  configurable: false,
760
- value: util.deprecate(function(fn) {
761
- return Array.from(this._modules, fn);
762
- }, "Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead")
772
+ value: util.deprecate(
773
+ /**
774
+ * @deprecated
775
+ * @this {Chunk}
776
+ * @typedef {function(any, number): any} MapModulesCallback
777
+ * @param {MapModulesCallback} fn Callback function
778
+ * @returns {TODO[]} result of mapped modules
779
+ */
780
+ function(fn) {
781
+ return Array.from(this._modules, fn);
782
+ },
783
+ "Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead"
784
+ )
763
785
  });
764
786
 
765
787
  // TODO remove in webpack 5
package/lib/ChunkGroup.js CHANGED
@@ -11,7 +11,6 @@ const compareLocations = require("./compareLocations");
11
11
  /** @typedef {import("./Module")} Module */
12
12
  /** @typedef {import("./ModuleReason")} ModuleReason */
13
13
 
14
- /** @typedef {{id: number}} HasId */
15
14
  /** @typedef {{module: Module, loc: TODO, request: string}} OriginRecord */
16
15
  /** @typedef {string|{name: string}} ChunkGroupOptions */
17
16
 
@@ -26,8 +25,8 @@ const getArray = set => Array.from(set);
26
25
 
27
26
  /**
28
27
  * A convenience method used to sort chunks based on their id's
29
- * @param {HasId} a first sorting comparator
30
- * @param {HasId} b second sorting comparator
28
+ * @param {ChunkGroup} a first sorting comparator
29
+ * @param {ChunkGroup} b second sorting comparator
31
30
  * @returns {1|0|-1} a sorting index to determine order
32
31
  */
33
32
  const sortById = (a, b) => {
@@ -63,6 +62,7 @@ class ChunkGroup {
63
62
  /** @type {number} */
64
63
  this.groupDebugId = debugId++;
65
64
  this.options = options;
65
+ /** @type {SortableSet<ChunkGroup>} */
66
66
  this._children = new SortableSet(undefined, sortById);
67
67
  this._parents = new SortableSet(undefined, sortById);
68
68
  this._blocks = new SortableSet();
@@ -888,6 +888,7 @@ class Compilation extends Tapable {
888
888
  // leaking the Compilation object.
889
889
 
890
890
  if (err) {
891
+ // eslint-disable-next-line no-self-assign
891
892
  err.stack = err.stack;
892
893
  return callback(err);
893
894
  }
@@ -1571,6 +1572,9 @@ class Compilation extends Tapable {
1571
1572
  /** @type {Map<DependenciesBlock, ChunkGroup>} */
1572
1573
  const blockChunkGroups = new Map();
1573
1574
 
1575
+ /** @type {Set<DependenciesBlock>} */
1576
+ const blocksWithNestedBlocks = new Set();
1577
+
1574
1578
  const ADD_AND_ENTER_MODULE = 0;
1575
1579
  const ENTER_MODULE = 1;
1576
1580
  const PROCESS_BLOCK = 2;
@@ -1730,6 +1734,10 @@ class Compilation extends Tapable {
1730
1734
 
1731
1735
  // Traverse all Blocks
1732
1736
  iterationOfArrayCallback(blockInfo.blocks, iteratorBlock);
1737
+
1738
+ if (blockInfo.blocks.length > 0 && module !== block) {
1739
+ blocksWithNestedBlocks.add(block);
1740
+ }
1733
1741
  break;
1734
1742
  }
1735
1743
  case LEAVE_MODULE: {
@@ -1791,6 +1799,7 @@ class Compilation extends Tapable {
1791
1799
  */
1792
1800
  const filterFn = dep => {
1793
1801
  const depChunkGroup = dep.chunkGroup;
1802
+ if (blocksWithNestedBlocks.has(dep.block)) return true;
1794
1803
  if (areModulesAvailable(depChunkGroup, newAvailableModules)) return false; // break all modules are already available
1795
1804
  return true;
1796
1805
  };
@@ -2441,21 +2450,48 @@ class Compilation extends Tapable {
2441
2450
  }
2442
2451
 
2443
2452
  // TODO remove in webpack 5
2444
- Compilation.prototype.applyPlugins = util.deprecate(function(name, ...args) {
2445
- this.hooks[
2446
- name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())
2447
- ].call(...args);
2448
- }, "Compilation.applyPlugins is deprecated. Use new API on `.hooks` instead");
2453
+ Compilation.prototype.applyPlugins = util.deprecate(
2454
+ /**
2455
+ * @deprecated
2456
+ * @param {string} name Name
2457
+ * @param {any[]} args Other arguments
2458
+ * @returns {void}
2459
+ * @this {Compilation}
2460
+ */
2461
+ function(name, ...args) {
2462
+ this.hooks[
2463
+ name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())
2464
+ ].call(...args);
2465
+ },
2466
+ "Compilation.applyPlugins is deprecated. Use new API on `.hooks` instead"
2467
+ );
2449
2468
 
2450
2469
  // TODO remove in webpack 5
2451
2470
  Object.defineProperty(Compilation.prototype, "moduleTemplate", {
2452
2471
  configurable: false,
2453
- get: util.deprecate(function() {
2454
- return this.moduleTemplates.javascript;
2455
- }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"),
2456
- set: util.deprecate(function(value) {
2457
- this.moduleTemplates.javascript = value;
2458
- }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead.")
2472
+ get: util.deprecate(
2473
+ /**
2474
+ * @deprecated
2475
+ * @this {Compilation}
2476
+ * @returns {TODO} module template
2477
+ */
2478
+ function() {
2479
+ return this.moduleTemplates.javascript;
2480
+ },
2481
+ "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"
2482
+ ),
2483
+ set: util.deprecate(
2484
+ /**
2485
+ * @deprecated
2486
+ * @param {ModuleTemplate} value Template value
2487
+ * @this {Compilation}
2488
+ * @returns {void}
2489
+ */
2490
+ function(value) {
2491
+ this.moduleTemplates.javascript = value;
2492
+ },
2493
+ "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead."
2494
+ )
2459
2495
  });
2460
2496
 
2461
2497
  module.exports = Compilation;
@@ -1,10 +1,21 @@
1
1
  "use strict";
2
2
 
3
+ /** @typedef {import("./Compiler")} Compiler */
4
+ /** @typedef {import("./ContextModuleFactory")} ContextModuleFactory */
5
+
3
6
  class ContextExclusionPlugin {
7
+ /**
8
+ * @param {RegExp} negativeMatcher Matcher regular expression
9
+ */
4
10
  constructor(negativeMatcher) {
5
11
  this.negativeMatcher = negativeMatcher;
6
12
  }
7
13
 
14
+ /**
15
+ * Apply the plugin
16
+ * @param {Compiler} compiler Webpack Compiler
17
+ * @returns {void}
18
+ */
8
19
  apply(compiler) {
9
20
  compiler.hooks.contextModuleFactory.tap("ContextExclusionPlugin", cmf => {
10
21
  cmf.hooks.contextModuleFiles.tap("ContextExclusionPlugin", files => {
@@ -10,6 +10,7 @@ const AsyncDependenciesBlock = require("./AsyncDependenciesBlock");
10
10
  const Template = require("./Template");
11
11
  const contextify = require("./util/identifier").contextify;
12
12
 
13
+ /** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */
13
14
  /** @typedef {import("./dependencies/ContextElementDependency")} ContextElementDependency */
14
15
 
15
16
  /**
@@ -703,56 +704,141 @@ webpackEmptyAsyncContext.id = ${JSON.stringify(id)};`;
703
704
  // TODO remove in webpack 5
704
705
  Object.defineProperty(ContextModule.prototype, "recursive", {
705
706
  configurable: false,
706
- get: util.deprecate(function() {
707
- return this.options.recursive;
708
- }, "ContextModule.recursive has been moved to ContextModule.options.recursive"),
709
- set: util.deprecate(function(value) {
710
- this.options.recursive = value;
711
- }, "ContextModule.recursive has been moved to ContextModule.options.recursive")
707
+ get: util.deprecate(
708
+ /**
709
+ * @deprecated
710
+ * @this {ContextModule}
711
+ * @returns {boolean} is recursive
712
+ */
713
+ function() {
714
+ return this.options.recursive;
715
+ },
716
+ "ContextModule.recursive has been moved to ContextModule.options.recursive"
717
+ ),
718
+ set: util.deprecate(
719
+ /**
720
+ * @deprecated
721
+ * @this {ContextModule}
722
+ * @param {boolean} value is recursive
723
+ * @returns {void}
724
+ */
725
+ function(value) {
726
+ this.options.recursive = value;
727
+ },
728
+ "ContextModule.recursive has been moved to ContextModule.options.recursive"
729
+ )
712
730
  });
713
731
 
714
732
  // TODO remove in webpack 5
715
733
  Object.defineProperty(ContextModule.prototype, "regExp", {
716
734
  configurable: false,
717
- get: util.deprecate(function() {
718
- return this.options.regExp;
719
- }, "ContextModule.regExp has been moved to ContextModule.options.regExp"),
720
- set: util.deprecate(function(value) {
721
- this.options.regExp = value;
722
- }, "ContextModule.regExp has been moved to ContextModule.options.regExp")
735
+ get: util.deprecate(
736
+ /**
737
+ * @deprecated
738
+ * @this {ContextModule}
739
+ * @returns {RegExp} regular expression
740
+ */
741
+ function() {
742
+ return this.options.regExp;
743
+ },
744
+ "ContextModule.regExp has been moved to ContextModule.options.regExp"
745
+ ),
746
+ set: util.deprecate(
747
+ /**
748
+ * @deprecated
749
+ * @this {ContextModule}
750
+ * @param {RegExp} value Regular expression
751
+ * @returns {void}
752
+ */
753
+ function(value) {
754
+ this.options.regExp = value;
755
+ },
756
+ "ContextModule.regExp has been moved to ContextModule.options.regExp"
757
+ )
723
758
  });
724
759
 
725
760
  // TODO remove in webpack 5
726
761
  Object.defineProperty(ContextModule.prototype, "addon", {
727
762
  configurable: false,
728
- get: util.deprecate(function() {
729
- return this.options.addon;
730
- }, "ContextModule.addon has been moved to ContextModule.options.addon"),
731
- set: util.deprecate(function(value) {
732
- this.options.addon = value;
733
- }, "ContextModule.addon has been moved to ContextModule.options.addon")
763
+ get: util.deprecate(
764
+ /**
765
+ * @deprecated
766
+ * @this {ContextModule}
767
+ * @returns {string} addon
768
+ */
769
+ function() {
770
+ return this.options.addon;
771
+ },
772
+ "ContextModule.addon has been moved to ContextModule.options.addon"
773
+ ),
774
+ set: util.deprecate(
775
+ /**
776
+ * @deprecated
777
+ * @this {ContextModule}
778
+ * @param {string} value addon
779
+ * @returns {void}
780
+ */
781
+ function(value) {
782
+ this.options.addon = value;
783
+ },
784
+ "ContextModule.addon has been moved to ContextModule.options.addon"
785
+ )
734
786
  });
735
787
 
736
788
  // TODO remove in webpack 5
737
789
  Object.defineProperty(ContextModule.prototype, "async", {
738
790
  configurable: false,
739
- get: util.deprecate(function() {
740
- return this.options.mode;
741
- }, "ContextModule.async has been moved to ContextModule.options.mode"),
742
- set: util.deprecate(function(value) {
743
- this.options.mode = value;
744
- }, "ContextModule.async has been moved to ContextModule.options.mode")
791
+ get: util.deprecate(
792
+ /**
793
+ * @deprecated
794
+ * @this {ContextModule}
795
+ * @returns {boolean} is async
796
+ */
797
+ function() {
798
+ return this.options.mode;
799
+ },
800
+ "ContextModule.async has been moved to ContextModule.options.mode"
801
+ ),
802
+ set: util.deprecate(
803
+ /**
804
+ * @deprecated
805
+ * @this {ContextModule}
806
+ * @param {ContextMode} value Context mode
807
+ * @returns {void}
808
+ */
809
+ function(value) {
810
+ this.options.mode = value;
811
+ },
812
+ "ContextModule.async has been moved to ContextModule.options.mode"
813
+ )
745
814
  });
746
815
 
747
816
  // TODO remove in webpack 5
748
817
  Object.defineProperty(ContextModule.prototype, "chunkName", {
749
818
  configurable: false,
750
- get: util.deprecate(function() {
751
- return this.options.chunkName;
752
- }, "ContextModule.chunkName has been moved to ContextModule.options.chunkName"),
753
- set: util.deprecate(function(value) {
754
- this.options.chunkName = value;
755
- }, "ContextModule.chunkName has been moved to ContextModule.options.chunkName")
819
+ get: util.deprecate(
820
+ /**
821
+ * @deprecated
822
+ * @this {ContextModule}
823
+ * @returns {string} chunk name
824
+ */
825
+ function() {
826
+ return this.options.chunkName;
827
+ },
828
+ "ContextModule.chunkName has been moved to ContextModule.options.chunkName"
829
+ ),
830
+ set: util.deprecate(
831
+ /**
832
+ * @deprecated
833
+ * @this {ContextModule}
834
+ * @param {string} value chunk name
835
+ * @returns {void}
836
+ */
837
+ function(value) {
838
+ this.options.chunkName = value;
839
+ },
840
+ "ContextModule.chunkName has been moved to ContextModule.options.chunkName"
841
+ )
756
842
  });
757
843
 
758
844
  module.exports = ContextModule;
@@ -15,15 +15,21 @@ const {
15
15
  const ContextModule = require("./ContextModule");
16
16
  const ContextElementDependency = require("./dependencies/ContextElementDependency");
17
17
 
18
+ /** @typedef {import("./Module")} Module */
19
+
18
20
  const EMPTY_RESOLVE_OPTIONS = {};
19
21
 
20
22
  module.exports = class ContextModuleFactory extends Tapable {
21
23
  constructor(resolverFactory) {
22
24
  super();
23
25
  this.hooks = {
26
+ /** @type {AsyncSeriesWaterfallHook<TODO>} */
24
27
  beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
28
+ /** @type {AsyncSeriesWaterfallHook<TODO>} */
25
29
  afterResolve: new AsyncSeriesWaterfallHook(["data"]),
30
+ /** @type {SyncWaterfallHook<string[]>} */
26
31
  contextModuleFiles: new SyncWaterfallHook(["files"]),
32
+ /** @type {SyncWaterfallHook<TODO[]>} */
27
33
  alternatives: new AsyncSeriesWaterfallHook(["modules"])
28
34
  };
29
35
  this._pluginCompat.tap("ContextModuleFactory", options => {
@@ -9,6 +9,11 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
9
9
  const ParserHelpers = require("./ParserHelpers");
10
10
  const NullFactory = require("./NullFactory");
11
11
 
12
+ /** @typedef {import("./Compiler")} Compiler */
13
+ /** @typedef {import("./Parser")} Parser */
14
+ /** @typedef {null|undefined|RegExp|Function|string|number} CodeValuePrimitive */
15
+ /** @typedef {CodeValuePrimitive|Record<string, CodeValuePrimitive>|RuntimeValue} CodeValue */
16
+
12
17
  class RuntimeValue {
13
18
  constructor(fn, fileDependencies) {
14
19
  this.fn = fn;
@@ -37,6 +42,12 @@ const stringifyObj = (obj, parser) => {
37
42
  );
38
43
  };
39
44
 
45
+ /**
46
+ * Convert code to a string that evaluates
47
+ * @param {CodeValue} code Code to evaluate
48
+ * @param {Parser} parser Parser
49
+ * @returns {string} code converted to string that evaluates
50
+ */
40
51
  const toCode = (code, parser) => {
41
52
  if (code === null) {
42
53
  return "null";
@@ -60,6 +71,10 @@ const toCode = (code, parser) => {
60
71
  };
61
72
 
62
73
  class DefinePlugin {
74
+ /**
75
+ * Create a new define plugin
76
+ * @param {Record<string, CodeValue>} definitions A map of global object definitions
77
+ */
63
78
  constructor(definitions) {
64
79
  this.definitions = definitions;
65
80
  }
@@ -68,6 +83,11 @@ class DefinePlugin {
68
83
  return new RuntimeValue(fn, fileDependencies);
69
84
  }
70
85
 
86
+ /**
87
+ * Apply the plugin
88
+ * @param {Compiler} compiler Webpack compiler
89
+ * @returns {void}
90
+ */
71
91
  apply(compiler) {
72
92
  const definitions = this.definitions;
73
93
  compiler.hooks.compilation.tap(
@@ -79,7 +99,18 @@ class DefinePlugin {
79
99
  new ConstDependency.Template()
80
100
  );
81
101
 
102
+ /**
103
+ * Handler
104
+ * @param {Parser} parser Parser
105
+ * @returns {void}
106
+ */
82
107
  const handler = parser => {
108
+ /**
109
+ * Walk definitions
110
+ * @param {Object} definitions Definitions map
111
+ * @param {string} prefix Prefix string
112
+ * @returns {void}
113
+ */
83
114
  const walkDefinitions = (definitions, prefix) => {
84
115
  Object.keys(definitions).forEach(key => {
85
116
  const code = definitions[key];
@@ -98,6 +129,12 @@ class DefinePlugin {
98
129
  });
99
130
  };
100
131
 
132
+ /**
133
+ * Apply define key
134
+ * @param {string} prefix Prefix
135
+ * @param {string} key Key
136
+ * @returns {void}
137
+ */
101
138
  const applyDefineKey = (prefix, key) => {
102
139
  const splittedKey = key.split(".");
103
140
  splittedKey.slice(1).forEach((_, i) => {
@@ -108,6 +145,12 @@ class DefinePlugin {
108
145
  });
109
146
  };
110
147
 
148
+ /**
149
+ * Apply Code
150
+ * @param {string} key Key
151
+ * @param {CodeValue} code Code
152
+ * @returns {void}
153
+ */
111
154
  const applyDefine = (key, code) => {
112
155
  const isTypeof = /^typeof\s+/.test(key);
113
156
  if (isTypeof) key = key.replace(/^typeof\s+/, "");
@@ -181,6 +224,12 @@ class DefinePlugin {
181
224
  });
182
225
  };
183
226
 
227
+ /**
228
+ * Apply Object
229
+ * @param {string} key Key
230
+ * @param {Object} obj Object
231
+ * @returns {void}
232
+ */
184
233
  const applyObjectDefine = (key, obj) => {
185
234
  parser.hooks.canRename
186
235
  .for(key)
@@ -12,6 +12,7 @@ const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDepende
12
12
  const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency");
13
13
 
14
14
  /** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
15
+ /** @typedef {import("./util/createHash").Hash} Hash */
15
16
 
16
17
  class DelegatedModule extends Module {
17
18
  constructor(sourceRequest, data, type, userRequest, originalRequest) {
@@ -99,6 +100,10 @@ class DelegatedModule extends Module {
99
100
  return 42;
100
101
  }
101
102
 
103
+ /**
104
+ * @param {Hash} hash the hash used to track dependencies
105
+ * @returns {void}
106
+ */
102
107
  updateHash(hash) {
103
108
  hash.update(this.type);
104
109
  hash.update(JSON.stringify(this.request));
@@ -73,7 +73,7 @@ class DependenciesBlock {
73
73
  }
74
74
 
75
75
  /**
76
- * @param {Hash} hash the hash used to track dependencies, from "crypto" module
76
+ * @param {Hash} hash the hash used to track dependencies
77
77
  * @returns {void}
78
78
  */
79
79
  updateHash(hash) {
package/lib/DllModule.js CHANGED
@@ -7,6 +7,8 @@
7
7
  const { RawSource } = require("webpack-sources");
8
8
  const Module = require("./Module");
9
9
 
10
+ /** @typedef {import("./util/createHash").Hash} Hash */
11
+
10
12
  class DllModule extends Module {
11
13
  constructor(context, dependencies, name, type) {
12
14
  super("javascript/dynamic", context);
@@ -44,6 +46,10 @@ class DllModule extends Module {
44
46
  return 12;
45
47
  }
46
48
 
49
+ /**
50
+ * @param {Hash} hash the hash used to track dependencies
51
+ * @returns {void}
52
+ */
47
53
  updateHash(hash) {
48
54
  hash.update("dll module");
49
55
  hash.update(this.name || "");
@@ -10,6 +10,8 @@ const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin");
10
10
  const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin");
11
11
  const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency");
12
12
  const NullFactory = require("./NullFactory");
13
+ const makePathsRelative = require("./util/identifier").makePathsRelative;
14
+ const WebpackError = require("./WebpackError");
13
15
 
14
16
  const validateOptions = require("schema-utils");
15
17
  const schema = require("../schemas/plugins/DllReferencePlugin.json");
@@ -43,9 +45,23 @@ class DllReferencePlugin {
43
45
  params.compilationDependencies.add(manifest);
44
46
  compiler.inputFileSystem.readFile(manifest, (err, result) => {
45
47
  if (err) return callback(err);
46
- params["dll reference " + manifest] = parseJson(
47
- result.toString("utf-8")
48
- );
48
+ // Catch errors parsing the manifest so that blank
49
+ // or malformed manifest files don't kill the process.
50
+ try {
51
+ params["dll reference " + manifest] = parseJson(
52
+ result.toString("utf-8")
53
+ );
54
+ } catch (e) {
55
+ // Store the error in the params so that it can
56
+ // be added as a compilation error later on.
57
+ const manifestPath = makePathsRelative(
58
+ compiler.options.context,
59
+ manifest
60
+ );
61
+ params[
62
+ "dll reference parse error " + manifest
63
+ ] = new DllManifestError(manifestPath, e.message);
64
+ }
49
65
  return callback();
50
66
  });
51
67
  } else {
@@ -57,6 +73,12 @@ class DllReferencePlugin {
57
73
  compiler.hooks.compile.tap("DllReferencePlugin", params => {
58
74
  let manifest = this.options.manifest;
59
75
  if (typeof manifest === "string") {
76
+ // If there was an error parsing the manifest
77
+ // file, exit now because the error will be added
78
+ // as a compilation error in the "compilation" hook.
79
+ if (params["dll reference parse error " + manifest]) {
80
+ return;
81
+ }
60
82
  manifest = params["dll reference " + manifest];
61
83
  }
62
84
  const name = this.options.name || manifest.name;
@@ -78,6 +100,32 @@ class DllReferencePlugin {
78
100
  extensions: this.options.extensions
79
101
  }).apply(normalModuleFactory);
80
102
  });
103
+
104
+ compiler.hooks.compilation.tap(
105
+ "DllReferencePlugin",
106
+ (compilation, params) => {
107
+ let manifest = this.options.manifest;
108
+ if (typeof manifest === "string") {
109
+ // If there was an error parsing the manifest file, add the
110
+ // error as a compilation error to make the compilation fail.
111
+ let e = params["dll reference parse error " + manifest];
112
+ if (e) {
113
+ compilation.errors.push(e);
114
+ }
115
+ }
116
+ }
117
+ );
118
+ }
119
+ }
120
+
121
+ class DllManifestError extends WebpackError {
122
+ constructor(filename, message) {
123
+ super();
124
+
125
+ this.name = "DllManifestError";
126
+ this.message = `Dll manifest ${filename}\n${message}`;
127
+
128
+ Error.captureStackTrace(this, this.constructor);
81
129
  }
82
130
  }
83
131
 
@@ -9,6 +9,8 @@ const Module = require("./Module");
9
9
  const WebpackMissingModule = require("./dependencies/WebpackMissingModule");
10
10
  const Template = require("./Template");
11
11
 
12
+ /** @typedef {import("./util/createHash").Hash} Hash */
13
+
12
14
  class ExternalModule extends Module {
13
15
  constructor(request, type, userRequest) {
14
16
  super("javascript/dynamic", null);
@@ -148,6 +150,10 @@ class ExternalModule extends Module {
148
150
  return 42;
149
151
  }
150
152
 
153
+ /**
154
+ * @param {Hash} hash the hash used to track dependencies
155
+ * @returns {void}
156
+ */
151
157
  updateHash(hash) {
152
158
  hash.update(this.externalType);
153
159
  hash.update(JSON.stringify(this.request));