webpack 5.71.0 → 5.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (47) hide show
  1. package/lib/BannerPlugin.js +3 -1
  2. package/lib/ChunkGraph.js +93 -6
  3. package/lib/Compilation.js +5 -1
  4. package/lib/Compiler.js +1 -1
  5. package/lib/DllReferencePlugin.js +1 -1
  6. package/lib/ExportsInfo.js +1 -1
  7. package/lib/Module.js +1 -0
  8. package/lib/NodeStuffPlugin.js +1 -1
  9. package/lib/NormalModule.js +4 -3
  10. package/lib/RuntimePlugin.js +7 -0
  11. package/lib/asset/AssetGenerator.js +36 -9
  12. package/lib/asset/AssetParser.js +1 -0
  13. package/lib/asset/AssetSourceGenerator.js +31 -6
  14. package/lib/asset/AssetSourceParser.js +1 -0
  15. package/lib/cache/PackFileCacheStrategy.js +8 -4
  16. package/lib/config/defaults.js +12 -4
  17. package/lib/container/RemoteRuntimeModule.js +8 -7
  18. package/lib/dependencies/CommonJsImportsParserPlugin.js +342 -61
  19. package/lib/dependencies/CommonJsRequireContextDependency.js +2 -2
  20. package/lib/dependencies/CommonJsRequireDependency.js +2 -1
  21. package/lib/dependencies/ContextDependency.js +15 -2
  22. package/lib/dependencies/ContextDependencyHelpers.js +18 -5
  23. package/lib/dependencies/ContextElementDependency.js +0 -16
  24. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +35 -3
  25. package/lib/dependencies/ImportParserPlugin.js +31 -25
  26. package/lib/dependencies/JsonExportsDependency.js +17 -21
  27. package/lib/dependencies/LoaderDependency.js +13 -0
  28. package/lib/dependencies/LoaderImportDependency.js +13 -0
  29. package/lib/dependencies/ModuleDependency.js +11 -1
  30. package/lib/dependencies/RequireResolveContextDependency.js +2 -2
  31. package/lib/dependencies/RequireResolveDependency.js +2 -1
  32. package/lib/dependencies/URLPlugin.js +21 -0
  33. package/lib/index.js +1 -0
  34. package/lib/javascript/JavascriptParser.js +40 -19
  35. package/lib/json/JsonData.js +8 -0
  36. package/lib/json/JsonParser.js +4 -6
  37. package/lib/optimize/ConcatenatedModule.js +2 -1
  38. package/lib/optimize/ModuleConcatenationPlugin.js +21 -2
  39. package/lib/runtime/AsyncModuleRuntimeModule.js +34 -58
  40. package/lib/runtime/NonceRuntimeModule.js +24 -0
  41. package/lib/sharing/ProvideSharedPlugin.js +1 -2
  42. package/package.json +3 -3
  43. package/schemas/WebpackOptions.check.js +1 -1
  44. package/schemas/WebpackOptions.json +37 -0
  45. package/schemas/plugins/BannerPlugin.check.js +1 -1
  46. package/schemas/plugins/BannerPlugin.json +4 -0
  47. package/types.d.ts +51 -3
@@ -49,20 +49,6 @@ class ContextElementDependency extends ModuleDependency {
49
49
  return "context element";
50
50
  }
51
51
 
52
- /**
53
- * @returns {string | undefined} a request context
54
- */
55
- getContext() {
56
- return this._context;
57
- }
58
-
59
- /**
60
- * @returns {string | null} an identifier to merge equal requests
61
- */
62
- getResourceIdentifier() {
63
- return `context${this._context || ""}|${super.getResourceIdentifier()}`;
64
- }
65
-
66
52
  get category() {
67
53
  return this._category;
68
54
  }
@@ -86,7 +72,6 @@ class ContextElementDependency extends ModuleDependency {
86
72
  const { write } = context;
87
73
  write(this._typePrefix);
88
74
  write(this._category);
89
- write(this._context);
90
75
  write(this.referencedExports);
91
76
  super.serialize(context);
92
77
  }
@@ -95,7 +80,6 @@ class ContextElementDependency extends ModuleDependency {
95
80
  const { read } = context;
96
81
  this._typePrefix = read();
97
82
  this._category = read();
98
- this._context = read();
99
83
  this.referencedExports = read();
100
84
  super.deserialize(context);
101
85
  }
@@ -61,17 +61,49 @@ HarmonyEvaluatedImportSpecifierDependency.Template = class HarmonyEvaluatedImpor
61
61
  const dep = /** @type {HarmonyEvaluatedImportSpecifierDependency} */ (
62
62
  dependency
63
63
  );
64
- const { moduleGraph, runtime } = templateContext;
64
+ const { module, moduleGraph, runtime } = templateContext;
65
65
  const connection = moduleGraph.getConnection(dep);
66
66
  // Skip rendering depending when dependency is conditional
67
67
  if (connection && !connection.isTargetActive(runtime)) return;
68
68
 
69
69
  const exportsInfo = moduleGraph.getExportsInfo(connection.module);
70
70
  const ids = dep.getIds(moduleGraph);
71
- const value = exportsInfo.isExportProvided(ids);
71
+
72
+ let value;
73
+
74
+ const exportsType = connection.module.getExportsType(
75
+ moduleGraph,
76
+ module.buildMeta.strictHarmonyModule
77
+ );
78
+ switch (exportsType) {
79
+ case "default-with-named": {
80
+ if (ids[0] === "default") {
81
+ value =
82
+ ids.length === 1 || exportsInfo.isExportProvided(ids.slice(1));
83
+ } else {
84
+ value = exportsInfo.isExportProvided(ids);
85
+ }
86
+ break;
87
+ }
88
+ case "namespace": {
89
+ if (ids[0] === "__esModule") {
90
+ value = ids.length === 1 || undefined;
91
+ } else {
92
+ value = exportsInfo.isExportProvided(ids);
93
+ }
94
+ break;
95
+ }
96
+ case "dynamic": {
97
+ if (ids[0] !== "default") {
98
+ value = exportsInfo.isExportProvided(ids);
99
+ }
100
+ break;
101
+ }
102
+ // default-only could lead to runtime error, when default value is primitive
103
+ }
72
104
 
73
105
  if (typeof value === "boolean") {
74
- source.replace(dep.range[0], dep.range[1] - 1, `${value}`);
106
+ source.replace(dep.range[0], dep.range[1] - 1, ` ${value}`);
75
107
  } else {
76
108
  const usedName = exportsInfo.getUsedName(ids, runtime);
77
109
 
@@ -14,10 +14,14 @@ const ImportDependency = require("./ImportDependency");
14
14
  const ImportEagerDependency = require("./ImportEagerDependency");
15
15
  const ImportWeakDependency = require("./ImportWeakDependency");
16
16
 
17
+ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
17
18
  /** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
18
19
  /** @typedef {import("../ContextModule").ContextMode} ContextMode */
19
20
 
20
21
  class ImportParserPlugin {
22
+ /**
23
+ * @param {JavascriptParserOptions} options options
24
+ */
21
25
  constructor(options) {
22
26
  this.options = options;
23
27
  }
@@ -28,7 +32,7 @@ class ImportParserPlugin {
28
32
 
29
33
  let chunkName = null;
30
34
  /** @type {ContextMode} */
31
- let mode = "lazy";
35
+ let mode = this.options.dynamicImportMode;
32
36
  let include = null;
33
37
  let exclude = null;
34
38
  /** @type {string[][] | null} */
@@ -36,6 +40,17 @@ class ImportParserPlugin {
36
40
  /** @type {RawChunkGroupOptions} */
37
41
  const groupOptions = {};
38
42
 
43
+ const { dynamicImportPreload, dynamicImportPrefetch } = this.options;
44
+ if (dynamicImportPreload !== undefined && dynamicImportPreload !== false)
45
+ groupOptions.preloadOrder =
46
+ dynamicImportPreload === true ? 0 : dynamicImportPreload;
47
+ if (
48
+ dynamicImportPrefetch !== undefined &&
49
+ dynamicImportPrefetch !== false
50
+ )
51
+ groupOptions.prefetchOrder =
52
+ dynamicImportPrefetch === true ? 0 : dynamicImportPrefetch;
53
+
39
54
  const { options: importOptions, errors: commentErrors } =
40
55
  parser.parseCommentOptions(expr.range);
41
56
 
@@ -175,16 +190,22 @@ class ImportParserPlugin {
175
190
  }
176
191
  }
177
192
 
178
- if (param.isString()) {
179
- if (mode !== "lazy" && mode !== "eager" && mode !== "weak") {
180
- parser.state.module.addWarning(
181
- new UnsupportedFeatureWarning(
182
- `\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.`,
183
- expr.loc
184
- )
185
- );
186
- }
193
+ if (
194
+ mode !== "lazy" &&
195
+ mode !== "lazy-once" &&
196
+ mode !== "eager" &&
197
+ mode !== "weak"
198
+ ) {
199
+ parser.state.module.addWarning(
200
+ new UnsupportedFeatureWarning(
201
+ `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`,
202
+ expr.loc
203
+ )
204
+ );
205
+ mode = "lazy";
206
+ }
187
207
 
208
+ if (param.isString()) {
188
209
  if (mode === "eager") {
189
210
  const dep = new ImportEagerDependency(
190
211
  param.string,
@@ -215,21 +236,6 @@ class ImportParserPlugin {
215
236
  }
216
237
  return true;
217
238
  } else {
218
- if (
219
- mode !== "lazy" &&
220
- mode !== "lazy-once" &&
221
- mode !== "eager" &&
222
- mode !== "weak"
223
- ) {
224
- parser.state.module.addWarning(
225
- new UnsupportedFeatureWarning(
226
- `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`,
227
- expr.loc
228
- )
229
- );
230
- mode = "lazy";
231
- }
232
-
233
239
  if (mode === "weak") {
234
240
  mode = "async-weak";
235
241
  }
@@ -13,18 +13,21 @@ const NullDependency = require("./NullDependency");
13
13
  /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
14
14
  /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
15
15
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
16
+ /** @typedef {import("../json/JsonData")} JsonData */
16
17
  /** @typedef {import("../util/Hash")} Hash */
17
18
 
18
19
  const getExportsFromData = data => {
19
20
  if (data && typeof data === "object") {
20
21
  if (Array.isArray(data)) {
21
- return data.map((item, idx) => {
22
- return {
23
- name: `${idx}`,
24
- canMangle: true,
25
- exports: getExportsFromData(item)
26
- };
27
- });
22
+ return data.length < 100
23
+ ? data.map((item, idx) => {
24
+ return {
25
+ name: `${idx}`,
26
+ canMangle: true,
27
+ exports: getExportsFromData(item)
28
+ };
29
+ })
30
+ : undefined;
28
31
  } else {
29
32
  const exports = [];
30
33
  for (const key of Object.keys(data)) {
@@ -42,12 +45,11 @@ const getExportsFromData = data => {
42
45
 
43
46
  class JsonExportsDependency extends NullDependency {
44
47
  /**
45
- * @param {(string | ExportSpec)[]} exports json exports
48
+ * @param {JsonData=} data json data
46
49
  */
47
- constructor(exports) {
50
+ constructor(data) {
48
51
  super();
49
- this.exports = exports;
50
- this._hashUpdate = undefined;
52
+ this.data = data;
51
53
  }
52
54
 
53
55
  get type() {
@@ -61,7 +63,7 @@ class JsonExportsDependency extends NullDependency {
61
63
  */
62
64
  getExports(moduleGraph) {
63
65
  return {
64
- exports: this.exports,
66
+ exports: getExportsFromData(this.data && this.data.get()),
65
67
  dependencies: undefined
66
68
  };
67
69
  }
@@ -73,23 +75,18 @@ class JsonExportsDependency extends NullDependency {
73
75
  * @returns {void}
74
76
  */
75
77
  updateHash(hash, context) {
76
- if (this._hashUpdate === undefined) {
77
- this._hashUpdate = this.exports
78
- ? JSON.stringify(this.exports)
79
- : "undefined";
80
- }
81
- hash.update(this._hashUpdate);
78
+ this.data.updateHash(hash);
82
79
  }
83
80
 
84
81
  serialize(context) {
85
82
  const { write } = context;
86
- write(this.exports);
83
+ write(this.data);
87
84
  super.serialize(context);
88
85
  }
89
86
 
90
87
  deserialize(context) {
91
88
  const { read } = context;
92
- this.exports = read();
89
+ this.data = read();
93
90
  super.deserialize(context);
94
91
  }
95
92
  }
@@ -100,4 +97,3 @@ makeSerializable(
100
97
  );
101
98
 
102
99
  module.exports = JsonExportsDependency;
103
- module.exports.getExportsFromData = getExportsFromData;
@@ -7,6 +7,11 @@
7
7
 
8
8
  const ModuleDependency = require("./ModuleDependency");
9
9
 
10
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
11
+ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
12
+ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
13
+ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
14
+
10
15
  class LoaderDependency extends ModuleDependency {
11
16
  /**
12
17
  * @param {string} request request string
@@ -22,6 +27,14 @@ class LoaderDependency extends ModuleDependency {
22
27
  get category() {
23
28
  return "loader";
24
29
  }
30
+
31
+ /**
32
+ * @param {ModuleGraph} moduleGraph module graph
33
+ * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
34
+ */
35
+ getCondition(moduleGraph) {
36
+ return false;
37
+ }
25
38
  }
26
39
 
27
40
  module.exports = LoaderDependency;
@@ -7,6 +7,11 @@
7
7
 
8
8
  const ModuleDependency = require("./ModuleDependency");
9
9
 
10
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
11
+ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
12
+ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
13
+ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
14
+
10
15
  class LoaderImportDependency extends ModuleDependency {
11
16
  /**
12
17
  * @param {string} request request string
@@ -23,6 +28,14 @@ class LoaderImportDependency extends ModuleDependency {
23
28
  get category() {
24
29
  return "loaderImport";
25
30
  }
31
+
32
+ /**
33
+ * @param {ModuleGraph} moduleGraph module graph
34
+ * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
35
+ */
36
+ getCondition(moduleGraph) {
37
+ return false;
38
+ }
26
39
  }
27
40
 
28
41
  module.exports = LoaderImportDependency;
@@ -26,13 +26,21 @@ class ModuleDependency extends Dependency {
26
26
  // assertions must be serialized by subclasses that use it
27
27
  /** @type {Record<string, any> | undefined} */
28
28
  this.assertions = undefined;
29
+ this._context = undefined;
30
+ }
31
+
32
+ /**
33
+ * @returns {string | undefined} a request context
34
+ */
35
+ getContext() {
36
+ return this._context;
29
37
  }
30
38
 
31
39
  /**
32
40
  * @returns {string | null} an identifier to merge equal requests
33
41
  */
34
42
  getResourceIdentifier() {
35
- let str = `module${this.request}`;
43
+ let str = `context${this._context || ""}|module${this.request}`;
36
44
  if (this.assertions !== undefined) {
37
45
  str += JSON.stringify(this.assertions);
38
46
  }
@@ -63,6 +71,7 @@ class ModuleDependency extends Dependency {
63
71
  const { write } = context;
64
72
  write(this.request);
65
73
  write(this.userRequest);
74
+ write(this._context);
66
75
  write(this.range);
67
76
  super.serialize(context);
68
77
  }
@@ -71,6 +80,7 @@ class ModuleDependency extends Dependency {
71
80
  const { read } = context;
72
81
  this.request = read();
73
82
  this.userRequest = read();
83
+ this._context = read();
74
84
  this.range = read();
75
85
  super.deserialize(context);
76
86
  }
@@ -10,8 +10,8 @@ const ContextDependency = require("./ContextDependency");
10
10
  const ContextDependencyTemplateAsId = require("./ContextDependencyTemplateAsId");
11
11
 
12
12
  class RequireResolveContextDependency extends ContextDependency {
13
- constructor(options, range, valueRange) {
14
- super(options);
13
+ constructor(options, range, valueRange, context) {
14
+ super(options, context);
15
15
 
16
16
  this.range = range;
17
17
  this.valueRange = valueRange;
@@ -15,10 +15,11 @@ const ModuleDependencyAsId = require("./ModuleDependencyTemplateAsId");
15
15
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
16
16
 
17
17
  class RequireResolveDependency extends ModuleDependency {
18
- constructor(request, range) {
18
+ constructor(request, range, context) {
19
19
  super(request);
20
20
 
21
21
  this.range = range;
22
+ this._context = context;
22
23
  }
23
24
 
24
25
  get type() {
@@ -5,12 +5,15 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const { pathToFileURL } = require("url");
9
+ const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
8
10
  const { approve } = require("../javascript/JavascriptParserHelpers");
9
11
  const InnerGraph = require("../optimize/InnerGraph");
10
12
  const URLDependency = require("./URLDependency");
11
13
 
12
14
  /** @typedef {import("estree").NewExpression} NewExpressionNode */
13
15
  /** @typedef {import("../Compiler")} Compiler */
16
+ /** @typedef {import("../NormalModule")} NormalModule */
14
17
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
15
18
 
16
19
  class URLPlugin {
@@ -27,6 +30,13 @@ class URLPlugin {
27
30
  new URLDependency.Template()
28
31
  );
29
32
 
33
+ /**
34
+ * @param {NormalModule} module module
35
+ * @returns {URL} file url
36
+ */
37
+ const getUrl = module => {
38
+ return pathToFileURL(module.resource);
39
+ };
30
40
  /**
31
41
  * @param {JavascriptParser} parser parser
32
42
  * @param {object} parserOptions options
@@ -67,6 +77,17 @@ class URLPlugin {
67
77
  };
68
78
 
69
79
  parser.hooks.canRename.for("URL").tap("URLPlugin", approve);
80
+ parser.hooks.evaluateNewExpression
81
+ .for("URL")
82
+ .tap("URLPlugin", expr => {
83
+ const request = getUrlRequest(expr);
84
+ if (!request) return;
85
+ const url = new URL(request, getUrl(parser.state.module));
86
+
87
+ return new BasicEvaluatedExpression()
88
+ .setString(url.toString())
89
+ .setRange(expr.range);
90
+ });
70
91
  parser.hooks.new.for("URL").tap("URLPlugin", _expr => {
71
92
  const expr = /** @type {NewExpressionNode} */ (_expr);
72
93
 
package/lib/index.js CHANGED
@@ -28,6 +28,7 @@ const memoize = require("./util/memoize");
28
28
  /** @typedef {import("./Compilation").Asset} Asset */
29
29
  /** @typedef {import("./Compilation").AssetInfo} AssetInfo */
30
30
  /** @typedef {import("./Compilation").EntryOptions} EntryOptions */
31
+ /** @typedef {import("./Compilation").PathData} PathData */
31
32
  /** @typedef {import("./Compiler").AssetEmittedInfo} AssetEmittedInfo */
32
33
  /** @typedef {import("./MultiStats")} MultiStats */
33
34
  /** @typedef {import("./Parser").ParserState} ParserState */
@@ -165,6 +165,14 @@ class JavascriptParser extends Parser {
165
165
  evaluateDefinedIdentifier: new HookMap(
166
166
  () => new SyncBailHook(["expression"])
167
167
  ),
168
+ /** @type {HookMap<SyncBailHook<[NewExpressionNode], BasicEvaluatedExpression | undefined | null>>} */
169
+ evaluateNewExpression: new HookMap(
170
+ () => new SyncBailHook(["expression"])
171
+ ),
172
+ /** @type {HookMap<SyncBailHook<[CallExpressionNode], BasicEvaluatedExpression | undefined | null>>} */
173
+ evaluateCallExpression: new HookMap(
174
+ () => new SyncBailHook(["expression"])
175
+ ),
168
176
  /** @type {HookMap<SyncBailHook<[CallExpressionNode, BasicEvaluatedExpression | undefined], BasicEvaluatedExpression | undefined | null>>} */
169
177
  evaluateCallExpressionMember: new HookMap(
170
178
  () => new SyncBailHook(["expression", "param"])
@@ -361,9 +369,14 @@ class JavascriptParser extends Parser {
361
369
  this.hooks.evaluate.for("NewExpression").tap("JavascriptParser", _expr => {
362
370
  const expr = /** @type {NewExpressionNode} */ (_expr);
363
371
  const callee = expr.callee;
364
- if (
365
- callee.type !== "Identifier" ||
366
- callee.name !== "RegExp" ||
372
+ if (callee.type !== "Identifier") return;
373
+ if (callee.name !== "RegExp") {
374
+ return this.callHooksForName(
375
+ this.hooks.evaluateNewExpression,
376
+ callee.name,
377
+ expr
378
+ );
379
+ } else if (
367
380
  expr.arguments.length > 2 ||
368
381
  this.getVariableInfo("RegExp") !== "RegExp"
369
382
  )
@@ -1036,24 +1049,28 @@ class JavascriptParser extends Parser {
1036
1049
  this.hooks.evaluate.for("CallExpression").tap("JavascriptParser", _expr => {
1037
1050
  const expr = /** @type {CallExpressionNode} */ (_expr);
1038
1051
  if (
1039
- expr.callee.type !== "MemberExpression" ||
1040
- expr.callee.property.type !==
1052
+ expr.callee.type === "MemberExpression" &&
1053
+ expr.callee.property.type ===
1041
1054
  (expr.callee.computed ? "Literal" : "Identifier")
1042
1055
  ) {
1043
- return;
1044
- }
1045
-
1046
- // type Super also possible here
1047
- const param = this.evaluateExpression(
1048
- /** @type {ExpressionNode} */ (expr.callee.object)
1049
- );
1050
- const property =
1051
- expr.callee.property.type === "Literal"
1052
- ? `${expr.callee.property.value}`
1053
- : expr.callee.property.name;
1054
- const hook = this.hooks.evaluateCallExpressionMember.get(property);
1055
- if (hook !== undefined) {
1056
- return hook.call(expr, param);
1056
+ // type Super also possible here
1057
+ const param = this.evaluateExpression(
1058
+ /** @type {ExpressionNode} */ (expr.callee.object)
1059
+ );
1060
+ const property =
1061
+ expr.callee.property.type === "Literal"
1062
+ ? `${expr.callee.property.value}`
1063
+ : expr.callee.property.name;
1064
+ const hook = this.hooks.evaluateCallExpressionMember.get(property);
1065
+ if (hook !== undefined) {
1066
+ return hook.call(expr, param);
1067
+ }
1068
+ } else if (expr.callee.type === "Identifier") {
1069
+ return this.callHooksForName(
1070
+ this.hooks.evaluateCallExpression,
1071
+ expr.callee.name,
1072
+ expr
1073
+ );
1057
1074
  }
1058
1075
  });
1059
1076
  this.hooks.evaluateCallExpressionMember
@@ -3603,6 +3620,10 @@ class JavascriptParser extends Parser {
3603
3620
  }
3604
3621
  }
3605
3622
 
3623
+ evaluatedVariable(tagInfo) {
3624
+ return new VariableInfo(this.scope, undefined, tagInfo);
3625
+ }
3626
+
3606
3627
  parseCommentOptions(range) {
3607
3628
  const comments = this.getComments(range);
3608
3629
  if (comments.length === 0) {
@@ -24,6 +24,14 @@ class JsonData {
24
24
  }
25
25
  return this._data;
26
26
  }
27
+
28
+ updateHash(hash) {
29
+ if (this._buffer === undefined && this._data !== undefined) {
30
+ this._buffer = Buffer.from(JSON.stringify(this._data));
31
+ }
32
+
33
+ if (this._buffer) return hash.update(this._buffer);
34
+ }
27
35
  }
28
36
 
29
37
  register(JsonData, "webpack/lib/json/JsonData", null, {
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const parseJson = require("json-parse-better-errors");
8
+ const parseJson = require("json-parse-even-better-errors");
9
9
  const Parser = require("../Parser");
10
10
  const JsonExportsDependency = require("../dependencies/JsonExportsDependency");
11
11
  const JsonData = require("./JsonData");
@@ -41,15 +41,13 @@ class JsonParser extends Parser {
41
41
  typeof source === "object"
42
42
  ? source
43
43
  : parseFn(source[0] === "\ufeff" ? source.slice(1) : source);
44
-
45
- state.module.buildInfo.jsonData = new JsonData(data);
44
+ const jsonData = new JsonData(data);
45
+ state.module.buildInfo.jsonData = jsonData;
46
46
  state.module.buildInfo.strict = true;
47
47
  state.module.buildMeta.exportsType = "default";
48
48
  state.module.buildMeta.defaultObject =
49
49
  typeof data === "object" ? "redirect-warn" : false;
50
- state.module.addDependency(
51
- new JsonExportsDependency(JsonExportsDependency.getExportsFromData(data))
52
- );
50
+ state.module.addDependency(new JsonExportsDependency(jsonData));
53
51
  return state;
54
52
  }
55
53
  }
@@ -1669,7 +1669,8 @@ ${defineGetters}`
1669
1669
  chunkGraph,
1670
1670
  runtime,
1671
1671
  concatenationScope,
1672
- codeGenerationResults
1672
+ codeGenerationResults,
1673
+ sourceTypes: TYPES
1673
1674
  });
1674
1675
  const source = codeGenResult.sources.get("javascript");
1675
1676
  const data = codeGenResult.data;
@@ -58,6 +58,11 @@ class ModuleConcatenationPlugin {
58
58
  apply(compiler) {
59
59
  const { _backCompat: backCompat } = compiler;
60
60
  compiler.hooks.compilation.tap("ModuleConcatenationPlugin", compilation => {
61
+ if (compilation.moduleMemCaches) {
62
+ throw new Error(
63
+ "optimization.concatenateModules can't be used with cacheUnaffected as module concatenation is a global effect"
64
+ );
65
+ }
61
66
  const moduleGraph = compilation.moduleGraph;
62
67
  const bailoutReasonMap = new Map();
63
68
 
@@ -425,7 +430,21 @@ class ModuleConcatenationPlugin {
425
430
  for (const chunk of chunkGraph.getModuleChunksIterable(
426
431
  rootModule
427
432
  )) {
428
- chunkGraph.disconnectChunkAndModule(chunk, m);
433
+ const sourceTypes = chunkGraph.getChunkModuleSourceTypes(
434
+ chunk,
435
+ m
436
+ );
437
+ if (sourceTypes.size === 1) {
438
+ chunkGraph.disconnectChunkAndModule(chunk, m);
439
+ } else {
440
+ const newSourceTypes = new Set(sourceTypes);
441
+ newSourceTypes.delete("javascript");
442
+ chunkGraph.setChunkModuleSourceTypes(
443
+ chunk,
444
+ m,
445
+ newSourceTypes
446
+ );
447
+ }
429
448
  }
430
449
  }
431
450
  }
@@ -587,7 +606,7 @@ class ModuleConcatenationPlugin {
587
606
  incomingConnectionsFromNonModules.filter(connection => {
588
607
  // We are not interested in inactive connections
589
608
  // or connections without dependency
590
- return connection.isActive(runtime) || connection.dependency;
609
+ return connection.isActive(runtime);
591
610
  });
592
611
  if (activeNonModulesConnections.length > 0) {
593
612
  const problem = requestShortener => {