webpack 5.69.1 → 5.72.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 (84) hide show
  1. package/hot/poll.js +1 -1
  2. package/hot/signal.js +1 -1
  3. package/lib/BannerPlugin.js +12 -4
  4. package/lib/Chunk.js +1 -1
  5. package/lib/ChunkGraph.js +93 -6
  6. package/lib/ChunkGroup.js +1 -1
  7. package/lib/CleanPlugin.js +64 -18
  8. package/lib/Compilation.js +51 -25
  9. package/lib/Compiler.js +16 -3
  10. package/lib/ConstPlugin.js +2 -2
  11. package/lib/ContextModule.js +121 -34
  12. package/lib/ContextModuleFactory.js +65 -25
  13. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  14. package/lib/Dependency.js +7 -0
  15. package/lib/EntryOptionPlugin.js +1 -0
  16. package/lib/ErrorHelpers.js +2 -2
  17. package/lib/ExportsInfo.js +1 -1
  18. package/lib/ExternalModuleFactoryPlugin.js +4 -4
  19. package/lib/FileSystemInfo.js +8 -0
  20. package/lib/Generator.js +1 -0
  21. package/lib/LoaderOptionsPlugin.js +1 -1
  22. package/lib/Module.js +3 -0
  23. package/lib/ModuleFilenameHelpers.js +3 -3
  24. package/lib/ModuleHashingError.js +29 -0
  25. package/lib/NodeStuffPlugin.js +10 -0
  26. package/lib/NormalModule.js +26 -20
  27. package/lib/NormalModuleFactory.js +17 -10
  28. package/lib/ProgressPlugin.js +3 -4
  29. package/lib/RuntimePlugin.js +18 -0
  30. package/lib/RuntimeTemplate.js +1 -0
  31. package/lib/WebpackOptionsApply.js +2 -0
  32. package/lib/asset/AssetGenerator.js +155 -40
  33. package/lib/asset/AssetParser.js +1 -0
  34. package/lib/asset/AssetSourceGenerator.js +31 -6
  35. package/lib/asset/AssetSourceParser.js +1 -0
  36. package/lib/cache/PackFileCacheStrategy.js +8 -4
  37. package/lib/cache/ResolverCachePlugin.js +89 -28
  38. package/lib/config/browserslistTargetHandler.js +3 -5
  39. package/lib/config/defaults.js +9 -1
  40. package/lib/config/normalization.js +1 -0
  41. package/lib/container/RemoteRuntimeModule.js +8 -7
  42. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  43. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  44. package/lib/dependencies/ContextElementDependency.js +33 -1
  45. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  46. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +95 -0
  47. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  48. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +127 -43
  49. package/lib/dependencies/HarmonyImportSpecifierDependency.js +22 -8
  50. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  51. package/lib/dependencies/ImportContextDependency.js +0 -2
  52. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  53. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  54. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  55. package/lib/dependencies/LoaderPlugin.js +2 -0
  56. package/lib/dependencies/RequireContextDependency.js +0 -16
  57. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  58. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +24 -8
  59. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  60. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  61. package/lib/ids/HashedModuleIdsPlugin.js +2 -2
  62. package/lib/ids/IdHelpers.js +1 -1
  63. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  64. package/lib/javascript/JavascriptParser.js +66 -40
  65. package/lib/library/UmdLibraryPlugin.js +5 -3
  66. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -7
  67. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -7
  68. package/lib/optimize/ConcatenatedModule.js +2 -1
  69. package/lib/optimize/ModuleConcatenationPlugin.js +20 -1
  70. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  71. package/lib/schemes/HttpUriPlugin.js +44 -3
  72. package/lib/stats/DefaultStatsFactoryPlugin.js +1 -1
  73. package/lib/util/internalSerializables.js +4 -0
  74. package/lib/web/JsonpChunkLoadingRuntimeModule.js +17 -6
  75. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -20
  76. package/module.d.ts +15 -0
  77. package/package.json +2 -2
  78. package/schemas/WebpackOptions.check.js +1 -1
  79. package/schemas/WebpackOptions.json +17 -1
  80. package/schemas/plugins/BannerPlugin.check.js +1 -1
  81. package/schemas/plugins/BannerPlugin.json +4 -0
  82. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  83. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  84. package/types.d.ts +202 -84
@@ -50,6 +50,7 @@ const memoize = require("./util/memoize");
50
50
  /** @typedef {import("webpack-sources").Source} Source */
51
51
  /** @typedef {import("../declarations/LoaderContext").NormalModuleLoaderContext} NormalModuleLoaderContext */
52
52
  /** @typedef {import("../declarations/WebpackOptions").Mode} Mode */
53
+ /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
53
54
  /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
54
55
  /** @typedef {import("./ChunkGraph")} ChunkGraph */
55
56
  /** @typedef {import("./Compiler")} Compiler */
@@ -194,6 +195,25 @@ makeSerializable(
194
195
  * @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild
195
196
  */
196
197
 
198
+ /**
199
+ * @typedef {Object} NormalModuleCreateData
200
+ * @property {string=} layer an optional layer in which the module is
201
+ * @property {string} type module type
202
+ * @property {string} request request string
203
+ * @property {string} userRequest request intended by user (without loaders from config)
204
+ * @property {string} rawRequest request without resolving
205
+ * @property {LoaderItem[]} loaders list of loaders
206
+ * @property {string} resource path + query of the real resource
207
+ * @property {Record<string, any>=} resourceResolveData resource resolve data
208
+ * @property {string} context context directory for resolving
209
+ * @property {string=} matchResource path + query of the matched resource (virtual)
210
+ * @property {Parser} parser the parser used
211
+ * @property {Record<string, any>=} parserOptions the options of the parser used
212
+ * @property {Generator} generator the generator used
213
+ * @property {Record<string, any>=} generatorOptions the options of the generator used
214
+ * @property {ResolveOptions=} resolveOptions options used for resolving requests from this module
215
+ */
216
+
197
217
  /** @type {WeakMap<Compilation, NormalModuleCompilationHooks>} */
198
218
  const compilationHooksMap = new WeakMap();
199
219
 
@@ -246,22 +266,7 @@ class NormalModule extends Module {
246
266
  }
247
267
 
248
268
  /**
249
- * @param {Object} options options object
250
- * @param {string=} options.layer an optional layer in which the module is
251
- * @param {string} options.type module type
252
- * @param {string} options.request request string
253
- * @param {string} options.userRequest request intended by user (without loaders from config)
254
- * @param {string} options.rawRequest request without resolving
255
- * @param {LoaderItem[]} options.loaders list of loaders
256
- * @param {string} options.resource path + query of the real resource
257
- * @param {Record<string, any>=} options.resourceResolveData resource resolve data
258
- * @param {string} options.context context directory for resolving
259
- * @param {string | undefined} options.matchResource path + query of the matched resource (virtual)
260
- * @param {Parser} options.parser the parser used
261
- * @param {object} options.parserOptions the options of the parser used
262
- * @param {Generator} options.generator the generator used
263
- * @param {object} options.generatorOptions the options of the generator used
264
- * @param {Object} options.resolveOptions options used for resolving requests from this module
269
+ * @param {NormalModuleCreateData} options options object
265
270
  */
266
271
  constructor({
267
272
  layer,
@@ -370,7 +375,7 @@ class NormalModule extends Module {
370
375
  nameForCondition() {
371
376
  const resource = this.matchResource || this.resource;
372
377
  const idx = resource.indexOf("?");
373
- if (idx >= 0) return resource.substr(0, idx);
378
+ if (idx >= 0) return resource.slice(0, idx);
374
379
  return resource;
375
380
  }
376
381
 
@@ -553,7 +558,7 @@ class NormalModule extends Module {
553
558
  let { options } = loader;
554
559
 
555
560
  if (typeof options === "string") {
556
- if (options.substr(0, 1) === "{" && options.substr(-1) === "}") {
561
+ if (options.startsWith("{") && options.endsWith("}")) {
557
562
  try {
558
563
  options = parseJson(options);
559
564
  } catch (e) {
@@ -1171,7 +1176,8 @@ class NormalModule extends Module {
1171
1176
  chunkGraph,
1172
1177
  runtime,
1173
1178
  concatenationScope,
1174
- codeGenerationResults
1179
+ codeGenerationResults,
1180
+ sourceTypes
1175
1181
  }) {
1176
1182
  /** @type {Set<string>} */
1177
1183
  const runtimeRequirements = new Set();
@@ -1190,7 +1196,7 @@ class NormalModule extends Module {
1190
1196
  };
1191
1197
 
1192
1198
  const sources = new Map();
1193
- for (const type of this.generator.getTypes(this)) {
1199
+ for (const type of sourceTypes || chunkGraph.getModuleSourceTypes(this)) {
1194
1200
  const source = this.error
1195
1201
  ? new RawSource(
1196
1202
  "throw new Error(" + JSON.stringify(this.error.message) + ");"
@@ -34,14 +34,19 @@ const {
34
34
  } = require("./util/identifier");
35
35
 
36
36
  /** @typedef {import("../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
37
+ /** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
37
38
  /** @typedef {import("./Generator")} Generator */
38
39
  /** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
39
40
  /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
41
+ /** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */
40
42
  /** @typedef {import("./Parser")} Parser */
41
43
  /** @typedef {import("./ResolverFactory")} ResolverFactory */
42
44
  /** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
43
45
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
44
46
 
47
+ /** @typedef {Pick<RuleSetRule, 'type'|'sideEffects'|'parser'|'generator'|'resolve'|'layer'>} ModuleSettings */
48
+ /** @typedef {Partial<NormalModuleCreateData & {settings: ModuleSettings}>} CreateData */
49
+
45
50
  /**
46
51
  * @typedef {Object} ResolveData
47
52
  * @property {ModuleFactoryCreateData["contextInfo"]} contextInfo
@@ -51,7 +56,7 @@ const {
51
56
  * @property {Record<string, any> | undefined} assertions
52
57
  * @property {ModuleDependency[]} dependencies
53
58
  * @property {string} dependencyType
54
- * @property {Object} createData
59
+ * @property {CreateData} createData
55
60
  * @property {LazySet<string>} fileDependencies
56
61
  * @property {LazySet<string>} missingDependencies
57
62
  * @property {LazySet<string>} contextDependencies
@@ -199,7 +204,7 @@ class NormalModuleFactory extends ModuleFactory {
199
204
  }) {
200
205
  super();
201
206
  this.hooks = Object.freeze({
202
- /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */
207
+ /** @type {AsyncSeriesBailHook<[ResolveData], Module | false | void>} */
203
208
  resolve: new AsyncSeriesBailHook(["resolveData"]),
204
209
  /** @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>} */
205
210
  resolveForScheme: new HookMap(
@@ -209,15 +214,15 @@ class NormalModuleFactory extends ModuleFactory {
209
214
  resolveInScheme: new HookMap(
210
215
  () => new AsyncSeriesBailHook(["resourceData", "resolveData"])
211
216
  ),
212
- /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */
217
+ /** @type {AsyncSeriesBailHook<[ResolveData], Module>} */
213
218
  factorize: new AsyncSeriesBailHook(["resolveData"]),
214
- /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */
219
+ /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */
215
220
  beforeResolve: new AsyncSeriesBailHook(["resolveData"]),
216
- /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */
221
+ /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */
217
222
  afterResolve: new AsyncSeriesBailHook(["resolveData"]),
218
- /** @type {AsyncSeriesBailHook<[ResolveData["createData"], ResolveData], TODO>} */
223
+ /** @type {AsyncSeriesBailHook<[ResolveData["createData"], ResolveData], Module | void>} */
219
224
  createModule: new AsyncSeriesBailHook(["createData", "resolveData"]),
220
- /** @type {SyncWaterfallHook<[Module, ResolveData["createData"], ResolveData], TODO>} */
225
+ /** @type {SyncWaterfallHook<[Module, ResolveData["createData"], ResolveData], Module>} */
221
226
  module: new SyncWaterfallHook(["module", "createData", "resolveData"]),
222
227
  createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
223
228
  parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
@@ -301,7 +306,9 @@ class NormalModuleFactory extends ModuleFactory {
301
306
  return callback(new Error("Empty dependency (no request)"));
302
307
  }
303
308
 
304
- createdModule = new NormalModule(createData);
309
+ createdModule = new NormalModule(
310
+ /** @type {NormalModuleCreateData} */ (createData)
311
+ );
305
312
  }
306
313
 
307
314
  createdModule = this.hooks.module.call(
@@ -372,7 +379,7 @@ class NormalModuleFactory extends ModuleFactory {
372
379
  resource: matchResource,
373
380
  ...cacheParseResource(matchResource)
374
381
  };
375
- requestWithoutMatchResource = request.substr(
382
+ requestWithoutMatchResource = request.slice(
376
383
  matchResourceMatch[0].length
377
384
  );
378
385
  }
@@ -430,7 +437,7 @@ class NormalModuleFactory extends ModuleFactory {
430
437
  try {
431
438
  for (const item of loaders) {
432
439
  if (typeof item.options === "string" && item.options[0] === "?") {
433
- const ident = item.options.substr(1);
440
+ const ident = item.options.slice(1);
434
441
  if (ident === "[[missing ident]]") {
435
442
  throw new Error(
436
443
  "No ident is provided by referenced loader. " +
@@ -531,15 +531,14 @@ class ProgressPlugin {
531
531
  }
532
532
  });
533
533
  interceptHook(compiler.cache.hooks.endIdle, 0.01, "cache", "end idle");
534
- compiler.hooks.initialize.intercept({
534
+ compiler.hooks.beforeRun.intercept({
535
535
  name: "ProgressPlugin",
536
536
  call() {
537
537
  handler(0, "");
538
538
  }
539
539
  });
540
- interceptHook(compiler.hooks.initialize, 0.01, "setup", "initialize");
541
- interceptHook(compiler.hooks.beforeRun, 0.02, "setup", "before run");
542
- interceptHook(compiler.hooks.run, 0.03, "setup", "run");
540
+ interceptHook(compiler.hooks.beforeRun, 0.01, "setup", "before run");
541
+ interceptHook(compiler.hooks.run, 0.02, "setup", "run");
543
542
  interceptHook(compiler.hooks.watchRun, 0.03, "setup", "watch run");
544
543
  interceptHook(
545
544
  compiler.hooks.normalModuleFactory,
@@ -11,6 +11,7 @@ const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirement
11
11
  const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
12
12
  const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
13
13
  const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
14
+ const BaseUriRuntimeModule = require("./runtime/BaseUriRuntimeModule");
14
15
  const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
15
16
  const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
16
17
  const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
@@ -96,6 +97,15 @@ class RuntimePlugin {
96
97
  */
97
98
  apply(compiler) {
98
99
  compiler.hooks.compilation.tap("RuntimePlugin", compilation => {
100
+ const globalChunkLoading = compilation.outputOptions.chunkLoading;
101
+ const isChunkLoadingDisabledForChunk = chunk => {
102
+ const options = chunk.getEntryOptions();
103
+ const chunkLoading =
104
+ options && options.chunkLoading !== undefined
105
+ ? options.chunkLoading
106
+ : globalChunkLoading;
107
+ return chunkLoading === false;
108
+ };
99
109
  compilation.dependencyTemplates.set(
100
110
  RuntimeRequirementsDependency,
101
111
  new RuntimeRequirementsDependency.Template()
@@ -413,6 +423,14 @@ class RuntimePlugin {
413
423
  );
414
424
  return true;
415
425
  });
426
+ compilation.hooks.runtimeRequirementInTree
427
+ .for(RuntimeGlobals.baseURI)
428
+ .tap("RuntimePlugin", chunk => {
429
+ if (isChunkLoadingDisabledForChunk(chunk)) {
430
+ compilation.addRuntimeModule(chunk, new BaseUriRuntimeModule());
431
+ return true;
432
+ }
433
+ });
416
434
  // TODO webpack 6: remove CompatRuntimeModule
417
435
  compilation.hooks.additionalTreeRuntimeRequirements.tap(
418
436
  "RuntimePlugin",
@@ -83,6 +83,7 @@ class RuntimeTemplate {
83
83
  this.outputOptions = outputOptions || {};
84
84
  this.requestShortener = requestShortener;
85
85
  this.globalObject = getGlobalObject(outputOptions.globalObject);
86
+ this.contentHashReplacement = "X".repeat(outputOptions.hashDigestLength);
86
87
  }
87
88
 
88
89
  isIIFE() {
@@ -35,6 +35,7 @@ const ResolverCachePlugin = require("./cache/ResolverCachePlugin");
35
35
 
36
36
  const CommonJsPlugin = require("./dependencies/CommonJsPlugin");
37
37
  const HarmonyModulesPlugin = require("./dependencies/HarmonyModulesPlugin");
38
+ const ImportMetaContextPlugin = require("./dependencies/ImportMetaContextPlugin");
38
39
  const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
39
40
  const ImportPlugin = require("./dependencies/ImportPlugin");
40
41
  const LoaderPlugin = require("./dependencies/LoaderPlugin");
@@ -361,6 +362,7 @@ class WebpackOptionsApply extends OptionsApply {
361
362
  new RequireEnsurePlugin().apply(compiler);
362
363
  new RequireContextPlugin().apply(compiler);
363
364
  new ImportPlugin().apply(compiler);
365
+ new ImportMetaContextPlugin().apply(compiler);
364
366
  new SystemPlugin().apply(compiler);
365
367
  new ImportMetaPlugin().apply(compiler);
366
368
  new URLPlugin().apply(compiler);
@@ -8,6 +8,7 @@
8
8
  const mimeTypes = require("mime-types");
9
9
  const path = require("path");
10
10
  const { RawSource } = require("webpack-sources");
11
+ const ConcatenationScope = require("../ConcatenationScope");
11
12
  const Generator = require("../Generator");
12
13
  const RuntimeGlobals = require("../RuntimeGlobals");
13
14
  const createHash = require("../util/createHash");
@@ -23,6 +24,7 @@ const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
23
24
  /** @typedef {import("../Generator").GenerateContext} GenerateContext */
24
25
  /** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
25
26
  /** @typedef {import("../Module")} Module */
27
+ /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
26
28
  /** @typedef {import("../NormalModule")} NormalModule */
27
29
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
28
30
  /** @typedef {import("../util/Hash")} Hash */
@@ -113,6 +115,7 @@ const decodeDataUriContent = (encoding, content) => {
113
115
 
114
116
  const JS_TYPES = new Set(["javascript"]);
115
117
  const JS_AND_ASSET_TYPES = new Set(["javascript", "asset"]);
118
+ const DEFAULT_ENCODING = "base64";
116
119
 
117
120
  class AssetGenerator extends Generator {
118
121
  /**
@@ -131,6 +134,74 @@ class AssetGenerator extends Generator {
131
134
  this.emit = emit;
132
135
  }
133
136
 
137
+ /**
138
+ * @param {NormalModule} module module
139
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
140
+ * @returns {string} source file name
141
+ */
142
+ getSourceFileName(module, runtimeTemplate) {
143
+ return makePathsRelative(
144
+ runtimeTemplate.compilation.compiler.context,
145
+ module.matchResource || module.resource,
146
+ runtimeTemplate.compilation.compiler.root
147
+ ).replace(/^\.\//, "");
148
+ }
149
+
150
+ /**
151
+ * @param {NormalModule} module module for which the bailout reason should be determined
152
+ * @param {ConcatenationBailoutReasonContext} context context
153
+ * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
154
+ */
155
+ getConcatenationBailoutReason(module, context) {
156
+ return undefined;
157
+ }
158
+
159
+ /**
160
+ * @param {NormalModule} module module
161
+ * @returns {string} mime type
162
+ */
163
+ getMimeType(module) {
164
+ if (typeof this.dataUrlOptions === "function") {
165
+ throw new Error(
166
+ "This method must not be called when dataUrlOptions is a function"
167
+ );
168
+ }
169
+
170
+ let mimeType = this.dataUrlOptions.mimetype;
171
+ if (mimeType === undefined) {
172
+ const ext = path.extname(module.nameForCondition());
173
+ if (
174
+ module.resourceResolveData &&
175
+ module.resourceResolveData.mimetype !== undefined
176
+ ) {
177
+ mimeType =
178
+ module.resourceResolveData.mimetype +
179
+ module.resourceResolveData.parameters;
180
+ } else if (ext) {
181
+ mimeType = mimeTypes.lookup(ext);
182
+
183
+ if (typeof mimeType !== "string") {
184
+ throw new Error(
185
+ "DataUrl can't be generated automatically, " +
186
+ `because there is no mimetype for "${ext}" in mimetype database. ` +
187
+ 'Either pass a mimetype via "generator.mimetype" or ' +
188
+ 'use type: "asset/resource" to create a resource file instead of a DataUrl'
189
+ );
190
+ }
191
+ }
192
+ }
193
+
194
+ if (typeof mimeType !== "string") {
195
+ throw new Error(
196
+ "DataUrl can't be generated automatically. " +
197
+ 'Either pass a mimetype via "generator.mimetype" or ' +
198
+ 'use type: "asset/resource" to create a resource file instead of a DataUrl'
199
+ );
200
+ }
201
+
202
+ return mimeType;
203
+ }
204
+
134
205
  /**
135
206
  * @param {NormalModule} module module for which the code should be generated
136
207
  * @param {GenerateContext} generateContext context for generate
@@ -138,14 +209,21 @@ class AssetGenerator extends Generator {
138
209
  */
139
210
  generate(
140
211
  module,
141
- { runtime, chunkGraph, runtimeTemplate, runtimeRequirements, type, getData }
212
+ {
213
+ runtime,
214
+ concatenationScope,
215
+ chunkGraph,
216
+ runtimeTemplate,
217
+ runtimeRequirements,
218
+ type,
219
+ getData
220
+ }
142
221
  ) {
143
222
  switch (type) {
144
223
  case "asset":
145
224
  return module.originalSource();
146
225
  default: {
147
- runtimeRequirements.add(RuntimeGlobals.module);
148
-
226
+ let content;
149
227
  const originalSource = module.originalSource();
150
228
  if (module.buildInfo.dataUrl) {
151
229
  let encodedSource;
@@ -170,31 +248,9 @@ class AssetGenerator extends Generator {
170
248
  }
171
249
  }
172
250
  if (encoding === undefined) {
173
- encoding = "base64";
174
- }
175
- let ext;
176
- let mimeType = this.dataUrlOptions.mimetype;
177
- if (mimeType === undefined) {
178
- ext = path.extname(module.nameForCondition());
179
- if (
180
- module.resourceResolveData &&
181
- module.resourceResolveData.mimetype !== undefined
182
- ) {
183
- mimeType =
184
- module.resourceResolveData.mimetype +
185
- module.resourceResolveData.parameters;
186
- } else if (ext) {
187
- mimeType = mimeTypes.lookup(ext);
188
- }
189
- }
190
- if (typeof mimeType !== "string") {
191
- throw new Error(
192
- "DataUrl can't be generated automatically, " +
193
- `because there is no mimetype for "${ext}" in mimetype database. ` +
194
- 'Either pass a mimetype via "generator.mimetype" or ' +
195
- 'use type: "asset/resource" to create a resource file instead of a DataUrl'
196
- );
251
+ encoding = DEFAULT_ENCODING;
197
252
  }
253
+ const mimeType = this.getMimeType(module);
198
254
 
199
255
  let encodedContent;
200
256
 
@@ -217,11 +273,7 @@ class AssetGenerator extends Generator {
217
273
  }
218
274
  const data = getData();
219
275
  data.set("url", Buffer.from(encodedSource));
220
- return new RawSource(
221
- `${RuntimeGlobals.module}.exports = ${JSON.stringify(
222
- encodedSource
223
- )};`
224
- );
276
+ content = JSON.stringify(encodedSource);
225
277
  } else {
226
278
  const assetModuleFilename =
227
279
  this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
@@ -238,11 +290,10 @@ class AssetGenerator extends Generator {
238
290
  runtimeTemplate.outputOptions.hashDigestLength
239
291
  );
240
292
  module.buildInfo.fullContentHash = fullHash;
241
- const sourceFilename = makePathsRelative(
242
- runtimeTemplate.compilation.compiler.context,
243
- module.matchResource || module.resource,
244
- runtimeTemplate.compilation.compiler.root
245
- ).replace(/^\.\//, "");
293
+ const sourceFilename = this.getSourceFileName(
294
+ module,
295
+ runtimeTemplate
296
+ );
246
297
  let { path: filename, info: assetInfo } =
247
298
  runtimeTemplate.compilation.getAssetPathWithInfo(
248
299
  assetModuleFilename,
@@ -306,9 +357,22 @@ class AssetGenerator extends Generator {
306
357
  data.set("filename", filename);
307
358
  data.set("assetInfo", assetInfo);
308
359
  }
360
+ content = assetPath;
361
+ }
309
362
 
363
+ if (concatenationScope) {
364
+ concatenationScope.registerNamespaceExport(
365
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
366
+ );
367
+ return new RawSource(
368
+ `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
369
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
370
+ } = ${content};`
371
+ );
372
+ } else {
373
+ runtimeRequirements.add(RuntimeGlobals.module);
310
374
  return new RawSource(
311
- `${RuntimeGlobals.module}.exports = ${assetPath};`
375
+ `${RuntimeGlobals.module}.exports = ${content};`
312
376
  );
313
377
  }
314
378
  }
@@ -368,8 +432,59 @@ class AssetGenerator extends Generator {
368
432
  * @param {Hash} hash hash that will be modified
369
433
  * @param {UpdateHashContext} updateHashContext context for updating hash
370
434
  */
371
- updateHash(hash, { module }) {
372
- hash.update(module.buildInfo.dataUrl ? "data-url" : "resource");
435
+ updateHash(hash, { module, runtime, runtimeTemplate, chunkGraph }) {
436
+ if (module.buildInfo.dataUrl) {
437
+ hash.update("data-url");
438
+ // this.dataUrlOptions as function should be pure and only depend on input source and filename
439
+ // therefore it doesn't need to be hashed
440
+ if (typeof this.dataUrlOptions === "function") {
441
+ const ident = /** @type {{ ident?: string }} */ (this.dataUrlOptions)
442
+ .ident;
443
+ if (ident) hash.update(ident);
444
+ } else {
445
+ if (
446
+ this.dataUrlOptions.encoding &&
447
+ this.dataUrlOptions.encoding !== DEFAULT_ENCODING
448
+ ) {
449
+ hash.update(this.dataUrlOptions.encoding);
450
+ }
451
+ if (this.dataUrlOptions.mimetype)
452
+ hash.update(this.dataUrlOptions.mimetype);
453
+ // computed mimetype depends only on module filename which is already part of the hash
454
+ }
455
+ } else {
456
+ hash.update("resource");
457
+
458
+ const pathData = {
459
+ module,
460
+ runtime,
461
+ filename: this.getSourceFileName(module, runtimeTemplate),
462
+ chunkGraph,
463
+ contentHash: runtimeTemplate.contentHashReplacement
464
+ };
465
+
466
+ if (typeof this.publicPath === "function") {
467
+ hash.update("path");
468
+ const assetInfo = {};
469
+ hash.update(this.publicPath(pathData, assetInfo));
470
+ hash.update(JSON.stringify(assetInfo));
471
+ } else if (this.publicPath) {
472
+ hash.update("path");
473
+ hash.update(this.publicPath);
474
+ } else {
475
+ hash.update("no-path");
476
+ }
477
+
478
+ const assetModuleFilename =
479
+ this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
480
+ const { path: filename, info } =
481
+ runtimeTemplate.compilation.getAssetPathWithInfo(
482
+ assetModuleFilename,
483
+ pathData
484
+ );
485
+ hash.update(filename);
486
+ hash.update(JSON.stringify(info));
487
+ }
373
488
  }
374
489
  }
375
490
 
@@ -31,6 +31,7 @@ class AssetParser extends Parser {
31
31
  }
32
32
  state.module.buildInfo.strict = true;
33
33
  state.module.buildMeta.exportsType = "default";
34
+ state.module.buildMeta.defaultObject = false;
34
35
 
35
36
  if (typeof this.dataUrlCondition === "function") {
36
37
  state.module.buildInfo.dataUrl = this.dataUrlCondition(source, {
@@ -6,11 +6,13 @@
6
6
  "use strict";
7
7
 
8
8
  const { RawSource } = require("webpack-sources");
9
+ const ConcatenationScope = require("../ConcatenationScope");
9
10
  const Generator = require("../Generator");
10
11
  const RuntimeGlobals = require("../RuntimeGlobals");
11
12
 
12
13
  /** @typedef {import("webpack-sources").Source} Source */
13
14
  /** @typedef {import("../Generator").GenerateContext} GenerateContext */
15
+ /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
14
16
  /** @typedef {import("../NormalModule")} NormalModule */
15
17
 
16
18
  const TYPES = new Set(["javascript"]);
@@ -21,9 +23,10 @@ class AssetSourceGenerator extends Generator {
21
23
  * @param {GenerateContext} generateContext context for generate
22
24
  * @returns {Source} generated code
23
25
  */
24
- generate(module, { chunkGraph, runtimeTemplate, runtimeRequirements }) {
25
- runtimeRequirements.add(RuntimeGlobals.module);
26
-
26
+ generate(
27
+ module,
28
+ { concatenationScope, chunkGraph, runtimeTemplate, runtimeRequirements }
29
+ ) {
27
30
  const originalSource = module.originalSource();
28
31
 
29
32
  if (!originalSource) {
@@ -38,9 +41,31 @@ class AssetSourceGenerator extends Generator {
38
41
  } else {
39
42
  encodedSource = content.toString("utf-8");
40
43
  }
41
- return new RawSource(
42
- `${RuntimeGlobals.module}.exports = ${JSON.stringify(encodedSource)};`
43
- );
44
+
45
+ let sourceContent;
46
+ if (concatenationScope) {
47
+ concatenationScope.registerNamespaceExport(
48
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
49
+ );
50
+ sourceContent = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
51
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
52
+ } = ${JSON.stringify(encodedSource)};`;
53
+ } else {
54
+ runtimeRequirements.add(RuntimeGlobals.module);
55
+ sourceContent = `${RuntimeGlobals.module}.exports = ${JSON.stringify(
56
+ encodedSource
57
+ )};`;
58
+ }
59
+ return new RawSource(sourceContent);
60
+ }
61
+
62
+ /**
63
+ * @param {NormalModule} module module for which the bailout reason should be determined
64
+ * @param {ConcatenationBailoutReasonContext} context context
65
+ * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
66
+ */
67
+ getConcatenationBailoutReason(module, context) {
68
+ return undefined;
44
69
  }
45
70
 
46
71
  /**
@@ -23,6 +23,7 @@ class AssetSourceParser extends Parser {
23
23
  const { module } = state;
24
24
  module.buildInfo.strict = true;
25
25
  module.buildMeta.exportsType = "default";
26
+ state.module.buildMeta.defaultObject = false;
26
27
 
27
28
  return state;
28
29
  }
@@ -639,10 +639,14 @@ class PackContentItems {
639
639
  } catch (e) {
640
640
  rollback(s);
641
641
  if (e === NOT_SERIALIZABLE) continue;
642
- logger.warn(
643
- `Skipped not serializable cache item '${key}': ${e.message}`
644
- );
645
- logger.debug(e.stack);
642
+ const msg = "Skipped not serializable cache item";
643
+ if (e.message.includes("ModuleBuildError")) {
644
+ logger.log(`${msg} (in build error): ${e.message}`);
645
+ logger.debug(`${msg} '${key}' (in build error): ${e.stack}`);
646
+ } else {
647
+ logger.warn(`${msg}: ${e.message}`);
648
+ logger.debug(`${msg} '${key}': ${e.stack}`);
649
+ }
646
650
  }
647
651
  }
648
652
  write(null);