webpack 4.16.1 → 4.16.2

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.
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();
@@ -2442,21 +2442,48 @@ class Compilation extends Tapable {
2442
2442
  }
2443
2443
 
2444
2444
  // TODO remove in webpack 5
2445
- Compilation.prototype.applyPlugins = util.deprecate(function(name, ...args) {
2446
- this.hooks[
2447
- name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())
2448
- ].call(...args);
2449
- }, "Compilation.applyPlugins is deprecated. Use new API on `.hooks` instead");
2445
+ Compilation.prototype.applyPlugins = util.deprecate(
2446
+ /**
2447
+ * @deprecated
2448
+ * @param {string} name Name
2449
+ * @param {any[]} args Other arguments
2450
+ * @returns {void}
2451
+ * @this {Compilation}
2452
+ */
2453
+ function(name, ...args) {
2454
+ this.hooks[
2455
+ name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())
2456
+ ].call(...args);
2457
+ },
2458
+ "Compilation.applyPlugins is deprecated. Use new API on `.hooks` instead"
2459
+ );
2450
2460
 
2451
2461
  // TODO remove in webpack 5
2452
2462
  Object.defineProperty(Compilation.prototype, "moduleTemplate", {
2453
2463
  configurable: false,
2454
- get: util.deprecate(function() {
2455
- return this.moduleTemplates.javascript;
2456
- }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"),
2457
- set: util.deprecate(function(value) {
2458
- this.moduleTemplates.javascript = value;
2459
- }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead.")
2464
+ get: util.deprecate(
2465
+ /**
2466
+ * @deprecated
2467
+ * @this {Compilation}
2468
+ * @returns {TODO} module template
2469
+ */
2470
+ function() {
2471
+ return this.moduleTemplates.javascript;
2472
+ },
2473
+ "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"
2474
+ ),
2475
+ set: util.deprecate(
2476
+ /**
2477
+ * @deprecated
2478
+ * @param {ModuleTemplate} value Template value
2479
+ * @this {Compilation}
2480
+ * @returns {void}
2481
+ */
2482
+ function(value) {
2483
+ this.moduleTemplates.javascript = value;
2484
+ },
2485
+ "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead."
2486
+ )
2460
2487
  });
2461
2488
 
2462
2489
  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 => {
@@ -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));
package/lib/Generator.js CHANGED
@@ -4,9 +4,10 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- /** @typedef {import("./Module")} Module */
7
+ /** @typedef {import("./NormalModule")} NormalModule */
8
8
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
9
9
  /** @typedef {import("webpack-sources").Source} Source */
10
+ /** @typedef {import("./Dependency").DependencyTemplate} DependencyTemplate */
10
11
 
11
12
  /**
12
13
  *
@@ -18,8 +19,8 @@ class Generator {
18
19
 
19
20
  /**
20
21
  * @abstract
21
- * @param {Module} module module for which the code should be generated
22
- * @param {Map<Function, TODO>} dependencyTemplates mapping from dependencies to templates
22
+ * @param {NormalModule} module module for which the code should be generated
23
+ * @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
23
24
  * @param {RuntimeTemplate} runtimeTemplate the runtime template
24
25
  * @param {string} type which kind of code should be generated
25
26
  * @returns {Source} generated code
@@ -35,6 +36,13 @@ class ByTypeGenerator extends Generator {
35
36
  this.map = map;
36
37
  }
37
38
 
39
+ /**
40
+ * @param {NormalModule} module module for which the code should be generated
41
+ * @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
42
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
43
+ * @param {string} type which kind of code should be generated
44
+ * @returns {Source} generated code
45
+ */
38
46
  generate(module, dependencyTemplates, runtimeTemplate, type) {
39
47
  const generator = this.map[type];
40
48
  if (!generator) {
package/lib/Module.js CHANGED
@@ -14,6 +14,7 @@ const Template = require("./Template");
14
14
  /** @typedef {import("./Chunk")} Chunk */
15
15
  /** @typedef {import("./RequestShortener")} RequestShortener */
16
16
  /** @typedef {import("./WebpackError")} WebpackError */
17
+ /** @typedef {import("./util/createHash").Hash} Hash */
17
18
 
18
19
  const EMPTY_RESOLVE_OPTIONS = {};
19
20
 
@@ -298,6 +299,10 @@ class Module extends DependenciesBlock {
298
299
  return true;
299
300
  }
300
301
 
302
+ /**
303
+ * @param {Hash} hash the hash used to track dependencies
304
+ * @returns {void}
305
+ */
301
306
  updateHash(hash) {
302
307
  hash.update(`${this.id}`);
303
308
  hash.update(JSON.stringify(this.usedExports));
@@ -339,17 +344,35 @@ class Module extends DependenciesBlock {
339
344
  // TODO remove in webpack 5
340
345
  Object.defineProperty(Module.prototype, "forEachChunk", {
341
346
  configurable: false,
342
- value: util.deprecate(function(fn) {
343
- this._chunks.forEach(fn);
344
- }, "Module.forEachChunk: Use for(const chunk of module.chunksIterable) instead")
347
+ value: util.deprecate(
348
+ /**
349
+ * @deprecated
350
+ * @param {function(any, any, Set<any>): void} fn callback function
351
+ * @returns {void}
352
+ * @this {Module}
353
+ */
354
+ function(fn) {
355
+ this._chunks.forEach(fn);
356
+ },
357
+ "Module.forEachChunk: Use for(const chunk of module.chunksIterable) instead"
358
+ )
345
359
  });
346
360
 
347
361
  // TODO remove in webpack 5
348
362
  Object.defineProperty(Module.prototype, "mapChunks", {
349
363
  configurable: false,
350
- value: util.deprecate(function(fn) {
351
- return Array.from(this._chunks, fn);
352
- }, "Module.mapChunks: Use Array.from(module.chunksIterable, fn) instead")
364
+ value: util.deprecate(
365
+ /**
366
+ * @deprecated
367
+ * @param {function(any, any): void} fn Mapper function
368
+ * @returns {Array<TODO>} Array of chunks mapped
369
+ * @this {Module}
370
+ */
371
+ function(fn) {
372
+ return Array.from(this._chunks, fn);
373
+ },
374
+ "Module.mapChunks: Use Array.from(module.chunksIterable, fn) instead"
375
+ )
353
376
  });
354
377
 
355
378
  // TODO remove in webpack 5
@@ -366,12 +389,29 @@ Object.defineProperty(Module.prototype, "entry", {
366
389
  // TODO remove in webpack 5
367
390
  Object.defineProperty(Module.prototype, "meta", {
368
391
  configurable: false,
369
- get: util.deprecate(function() {
370
- return this.buildMeta;
371
- }, "Module.meta was renamed to Module.buildMeta"),
372
- set: util.deprecate(function(value) {
373
- this.buildMeta = value;
374
- }, "Module.meta was renamed to Module.buildMeta")
392
+ get: util.deprecate(
393
+ /**
394
+ * @deprecated
395
+ * @returns {void}
396
+ * @this {Module}
397
+ */
398
+ function() {
399
+ return this.buildMeta;
400
+ },
401
+ "Module.meta was renamed to Module.buildMeta"
402
+ ),
403
+ set: util.deprecate(
404
+ /**
405
+ * @deprecated
406
+ * @param {TODO} value Value
407
+ * @returns {void}
408
+ * @this {Module}
409
+ */
410
+ function(value) {
411
+ this.buildMeta = value;
412
+ },
413
+ "Module.meta was renamed to Module.buildMeta"
414
+ )
375
415
  });
376
416
 
377
417
  /** @type {function(): string} */
@@ -8,6 +8,8 @@ const Module = require("./Module");
8
8
  const Template = require("./Template");
9
9
  const { RawSource } = require("webpack-sources");
10
10
 
11
+ /** @typedef {import("./util/createHash").Hash} Hash */
12
+
11
13
  class MultiModule extends Module {
12
14
  constructor(context, dependencies, name) {
13
15
  super("javascript/dynamic", context);
@@ -45,6 +47,10 @@ class MultiModule extends Module {
45
47
  return 16 + this.dependencies.length * 12;
46
48
  }
47
49
 
50
+ /**
51
+ * @param {Hash} hash the hash used to track dependencies
52
+ * @returns {void}
53
+ */
48
54
  updateHash(hash) {
49
55
  hash.update("multi module");
50
56
  hash.update(this.name || "");
@@ -108,6 +108,24 @@ class NodeStuffPlugin {
108
108
  "require.extensions is not supported by webpack. Use a loader instead."
109
109
  )
110
110
  );
111
+ parser.hooks.expression
112
+ .for("require.main.require")
113
+ .tap(
114
+ "NodeStuffPlugin",
115
+ ParserHelpers.expressionIsUnsupported(
116
+ parser,
117
+ "require.main.require is not supported by webpack."
118
+ )
119
+ );
120
+ parser.hooks.expression
121
+ .for("module.parent.require")
122
+ .tap(
123
+ "NodeStuffPlugin",
124
+ ParserHelpers.expressionIsUnsupported(
125
+ parser,
126
+ "module.parent.require is not supported by webpack."
127
+ )
128
+ );
111
129
  parser.hooks.expression
112
130
  .for("module.loaded")
113
131
  .tap("NodeStuffPlugin", expr => {
@@ -24,6 +24,8 @@ const ModuleWarning = require("./ModuleWarning");
24
24
  const createHash = require("./util/createHash");
25
25
  const contextify = require("./util/identifier").contextify;
26
26
 
27
+ /** @typedef {import("./util/createHash").Hash} Hash */
28
+
27
29
  const asString = buf => {
28
30
  if (Buffer.isBuffer(buf)) {
29
31
  return buf.toString("utf-8");
@@ -527,6 +529,10 @@ class NormalModule extends Module {
527
529
  return this._source ? this._source.size() : -1;
528
530
  }
529
531
 
532
+ /**
533
+ * @param {Hash} hash the hash used to track dependencies
534
+ * @returns {void}
535
+ */
530
536
  updateHash(hash) {
531
537
  hash.update(this._buildHash);
532
538
  super.updateHash(hash);
package/lib/Parser.js CHANGED
@@ -2185,9 +2185,18 @@ class Parser extends Tapable {
2185
2185
  // TODO remove in webpack 5
2186
2186
  Object.defineProperty(Parser.prototype, "getCommentOptions", {
2187
2187
  configurable: false,
2188
- value: util.deprecate(function(range) {
2189
- return this.parseCommentOptions(range).options;
2190
- }, "Parser.getCommentOptions: Use Parser.parseCommentOptions(range) instead")
2188
+ value: util.deprecate(
2189
+ /**
2190
+ * @deprecated
2191
+ * @param {TODO} range Range
2192
+ * @returns {void}
2193
+ * @this {Parser}
2194
+ */
2195
+ function(range) {
2196
+ return this.parseCommentOptions(range).options;
2197
+ },
2198
+ "Parser.getCommentOptions: Use Parser.parseCommentOptions(range) instead"
2199
+ )
2191
2200
  });
2192
2201
 
2193
2202
  module.exports = Parser;
@@ -6,6 +6,8 @@
6
6
 
7
7
  const Template = require("./Template");
8
8
 
9
+ /** @typedef {import("./Module")} Module */
10
+
9
11
  module.exports = class RuntimeTemplate {
10
12
  constructor(outputOptions, requestShortener) {
11
13
  this.outputOptions = outputOptions || {};
@@ -188,6 +190,16 @@ module.exports = class RuntimeTemplate {
188
190
  return `${promise || "Promise.resolve()"}.then(${getModuleFunction})`;
189
191
  }
190
192
 
193
+ /**
194
+ *
195
+ * @param {Object} options options object
196
+ * @param {boolean=} options.update whether a new variable should be created or the existing one updated
197
+ * @param {Module} options.module the module
198
+ * @param {string} options.request the request that should be printed as comment
199
+ * @param {string} options.importVar name of the import variable
200
+ * @param {Module} options.originModule module in which the statement is emitted
201
+ * @returns {string} the import statement
202
+ */
191
203
  importStatement({ update, module, request, importVar, originModule }) {
192
204
  if (!module) {
193
205
  return this.missingModuleStatement({
package/lib/Stats.js CHANGED
@@ -8,6 +8,7 @@ const RequestShortener = require("./RequestShortener");
8
8
  const SizeFormatHelpers = require("./SizeFormatHelpers");
9
9
  const formatLocation = require("./formatLocation");
10
10
  const identifierUtils = require("./util/identifier");
11
+ const compareLocations = require("./compareLocations");
11
12
 
12
13
  const optionsOrFallback = (...args) => {
13
14
  let optionValues = [];
@@ -523,6 +524,23 @@ class Stats {
523
524
  }
524
525
  if (showReasons) {
525
526
  obj.reasons = module.reasons
527
+ .sort((a, b) => {
528
+ if (a.module && !b.module) return -1;
529
+ if (!a.module && b.module) return 1;
530
+ if (a.module && b.module) {
531
+ const cmp = compareId(a.module.id, b.module.id);
532
+ if (cmp) return cmp;
533
+ }
534
+ if (a.dependency && !b.dependency) return -1;
535
+ if (!a.dependency && b.dependency) return 1;
536
+ if (a.dependency && b.dependency) {
537
+ const cmp = compareLocations(a.dependency.loc, b.dependency.loc);
538
+ if (cmp) return cmp;
539
+ if (a.dependency.type < b.dependency.type) return -1;
540
+ if (a.dependency.type > b.dependency.type) return 1;
541
+ }
542
+ return 0;
543
+ })
526
544
  .map(reason => {
527
545
  const obj = {
528
546
  moduleId: reason.module ? reason.module.id : null,
@@ -548,8 +566,7 @@ class Stats {
548
566
  }
549
567
  }
550
568
  return obj;
551
- })
552
- .sort(compareId);
569
+ });
553
570
  }
554
571
  if (showUsedExports) {
555
572
  if (module.used === true) {
@@ -125,6 +125,12 @@ class CommonJsRequireDependencyParserPlugin {
125
125
  parser.hooks.new
126
126
  .for("require")
127
127
  .tap("CommonJsRequireDependencyParserPlugin", createHandler(true));
128
+ parser.hooks.call
129
+ .for("module.require")
130
+ .tap("CommonJsRequireDependencyParserPlugin", createHandler(false));
131
+ parser.hooks.new
132
+ .for("module.require")
133
+ .tap("CommonJsRequireDependencyParserPlugin", createHandler(true));
128
134
  }
129
135
  }
130
136
  module.exports = CommonJsRequireDependencyParserPlugin;
@@ -21,6 +21,7 @@ const createHash = require("../util/createHash");
21
21
 
22
22
  /** @typedef {import("../Dependency")} Dependency */
23
23
  /** @typedef {import("../Compilation")} Compilation */
24
+ /** @typedef {import("../util/createHash").Hash} Hash */
24
25
 
25
26
  /**
26
27
  * @typedef {Object} ConcatenationEntry
@@ -1180,6 +1181,10 @@ class ConcatenatedModule extends Module {
1180
1181
  return nameWithNumber;
1181
1182
  }
1182
1183
 
1184
+ /**
1185
+ * @param {Hash} hash the hash used to track dependencies
1186
+ * @returns {void}
1187
+ */
1183
1188
  updateHash(hash) {
1184
1189
  for (const info of this._orderedConcatenationList) {
1185
1190
  switch (info.type) {
@@ -3,6 +3,7 @@
3
3
  /**
4
4
  * A subset of Set that offers sorting functionality
5
5
  * @template T item type in set
6
+ * @extends {Set<T>}
6
7
  */
7
8
  class SortableSet extends Set {
8
9
  /**
@@ -128,8 +128,17 @@ class StackedSetMap {
128
128
  }
129
129
 
130
130
  // TODO remove in webpack 5
131
- StackedSetMap.prototype.push = util.deprecate(function(item) {
132
- this.add(item);
133
- }, "This is no longer an Array: Use add instead.");
131
+ StackedSetMap.prototype.push = util.deprecate(
132
+ /**
133
+ * @deprecated
134
+ * @this {StackedSetMap}
135
+ * @param {any} item Item to add
136
+ * @returns {void}
137
+ */
138
+ function(item) {
139
+ this.add(item);
140
+ },
141
+ "This is no longer an Array: Use add instead."
142
+ );
134
143
 
135
144
  module.exports = StackedSetMap;
@@ -21,6 +21,10 @@ const WebAssemblyExportImportedDependency = require("../dependencies/WebAssembly
21
21
 
22
22
  /** @typedef {import("../Module")} Module */
23
23
  /** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */
24
+ /** @typedef {import("../NormalModule")} NormalModule */
25
+ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
26
+ /** @typedef {import("webpack-sources").Source} Source */
27
+ /** @typedef {import("../Dependency").DependencyTemplate} DependencyTemplate */
24
28
 
25
29
  /**
26
30
  * @typedef {(ArrayBuffer) => ArrayBuffer} ArrayBufferTransform
@@ -366,7 +370,14 @@ class WebAssemblyGenerator extends Generator {
366
370
  this.options = options;
367
371
  }
368
372
 
369
- generate(module) {
373
+ /**
374
+ * @param {NormalModule} module module for which the code should be generated
375
+ * @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
376
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
377
+ * @param {string} type which kind of code should be generated
378
+ * @returns {Source} generated code
379
+ */
380
+ generate(module, dependencyTemplates, runtimeTemplate, type) {
370
381
  let bin = module.originalSource().source();
371
382
  bin = preprocess(bin);
372
383
 
@@ -398,7 +409,10 @@ class WebAssemblyGenerator extends Generator {
398
409
  const externalExports = new Set(
399
410
  module.dependencies
400
411
  .filter(d => d instanceof WebAssemblyExportImportedDependency)
401
- .map(d => d.exportName)
412
+ .map(d => {
413
+ const wasmDep = /** @type {WebAssemblyExportImportedDependency} */ (d);
414
+ return wasmDep.exportName;
415
+ })
402
416
  );
403
417
 
404
418
  /** @type {t.Instruction[]} */
@@ -10,8 +10,20 @@ const { RawSource } = require("webpack-sources");
10
10
  const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
11
11
  const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
12
12
 
13
+ /** @typedef {import("../NormalModule")} NormalModule */
14
+ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
15
+ /** @typedef {import("webpack-sources").Source} Source */
16
+ /** @typedef {import("../Dependency").DependencyTemplate} DependencyTemplate */
17
+
13
18
  class WebAssemblyJavascriptGenerator extends Generator {
14
- generate(module, dependencyTemplates, runtimeTemplate) {
19
+ /**
20
+ * @param {NormalModule} module module for which the code should be generated
21
+ * @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
22
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
23
+ * @param {string} type which kind of code should be generated
24
+ * @returns {Source} generated code
25
+ */
26
+ generate(module, dependencyTemplates, runtimeTemplate, type) {
15
27
  const initIdentifer = Array.isArray(module.usedExports)
16
28
  ? Template.numberToIdentifer(module.usedExports.length)
17
29
  : "__webpack_init__";
@@ -21,6 +33,7 @@ class WebAssemblyJavascriptGenerator extends Generator {
21
33
  const initParams = [];
22
34
  let index = 0;
23
35
  for (const dep of module.dependencies) {
36
+ const depAsAny = /** @type {any} */ (dep);
24
37
  if (dep.module) {
25
38
  let importData = importedModules.get(dep.module);
26
39
  if (importData === undefined) {
@@ -29,7 +42,8 @@ class WebAssemblyJavascriptGenerator extends Generator {
29
42
  (importData = {
30
43
  importVar: `m${index}`,
31
44
  index,
32
- request: dep.userRequest,
45
+ request:
46
+ "userRequest" in depAsAny ? depAsAny.userRequest : undefined,
33
47
  names: new Set(),
34
48
  reexports: []
35
49
  })
package/lib/webpack.js CHANGED
@@ -69,6 +69,7 @@ webpack.WebpackOptionsApply = WebpackOptionsApply;
69
69
  webpack.Compiler = Compiler;
70
70
  webpack.MultiCompiler = MultiCompiler;
71
71
  webpack.NodeEnvironmentPlugin = NodeEnvironmentPlugin;
72
+ // @ts-ignore Global @this directive is not supported
72
73
  webpack.validate = validateSchema.bind(this, webpackOptionsSchema);
73
74
  webpack.validateSchema = validateSchema;
74
75
  webpack.WebpackOptionsValidationError = WebpackOptionsValidationError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "4.16.1",
3
+ "version": "4.16.2",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "license": "MIT",
@@ -128,10 +128,10 @@
128
128
  "pretest": "yarn lint",
129
129
  "prelint": "yarn setup",
130
130
  "lint": "yarn code-lint && yarn schema-lint && yarn type-lint",
131
- "code-lint": "eslint --cache setup lib bin hot buildin benchmark \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\"",
131
+ "code-lint": "eslint --cache setup lib bin hot buildin benchmark tooling \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\"",
132
132
  "type-lint": "tsc --pretty",
133
133
  "fix": "yarn code-lint --fix",
134
- "pretty": "prettier --write \"setup/**/*.js\" \"lib/**/*.js\" \"bin/*.js\" \"hot/*.js\" \"buildin/*.js\" \"benchmark/**/*.js\" \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\" \"declarations.d.ts\" \"tsconfig.json\"",
134
+ "pretty": "prettier --write \"setup/**/*.js\" \"lib/**/*.js\" \"bin/*.js\" \"hot/*.js\" \"buildin/*.js\" \"benchmark/**/*.js\" \"tooling/*.js\" \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\" \"declarations.d.ts\" \"tsconfig.json\"",
135
135
  "schema-lint": "node --max-old-space-size=4096 node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.lint.js\" --no-verbose",
136
136
  "benchmark": "node --max-old-space-size=4096 --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.benchmark.js\" --runInBand",
137
137
  "cover": "yarn cover:init && yarn cover:all && yarn cover:report",