webpack 5.64.3 → 5.67.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 (121) hide show
  1. package/README.md +1 -1
  2. package/lib/Cache.js +1 -1
  3. package/lib/CacheFacade.js +4 -11
  4. package/lib/Chunk.js +2 -0
  5. package/lib/CleanPlugin.js +1 -1
  6. package/lib/Compilation.js +91 -47
  7. package/lib/Compiler.js +57 -3
  8. package/lib/ContextModule.js +21 -17
  9. package/lib/DelegatedModule.js +1 -1
  10. package/lib/Dependency.js +10 -0
  11. package/lib/DependencyTemplate.js +9 -0
  12. package/lib/DependencyTemplates.js +1 -1
  13. package/lib/DllModule.js +1 -1
  14. package/lib/EvalDevToolModulePlugin.js +16 -1
  15. package/lib/EvalSourceMapDevToolPlugin.js +18 -1
  16. package/lib/ExternalModule.js +94 -54
  17. package/lib/ExternalModuleFactoryPlugin.js +1 -1
  18. package/lib/FileSystemInfo.js +29 -25
  19. package/lib/Generator.js +2 -0
  20. package/lib/HookWebpackError.js +1 -1
  21. package/lib/Module.js +25 -2
  22. package/lib/ModuleFilenameHelpers.js +5 -1
  23. package/lib/MultiCompiler.js +1 -1
  24. package/lib/MultiWatching.js +1 -1
  25. package/lib/NormalModule.js +9 -5
  26. package/lib/RawModule.js +1 -1
  27. package/lib/RuntimeGlobals.js +29 -1
  28. package/lib/RuntimeModule.js +1 -1
  29. package/lib/RuntimePlugin.js +50 -0
  30. package/lib/RuntimeTemplate.js +113 -2
  31. package/lib/Template.js +2 -1
  32. package/lib/WatchIgnorePlugin.js +14 -1
  33. package/lib/Watching.js +33 -19
  34. package/lib/WebpackOptionsApply.js +43 -2
  35. package/lib/asset/AssetGenerator.js +71 -30
  36. package/lib/asset/AssetModulesPlugin.js +3 -0
  37. package/lib/asset/RawDataUrlModule.js +148 -0
  38. package/lib/cache/ResolverCachePlugin.js +1 -1
  39. package/lib/cli.js +44 -3
  40. package/lib/config/browserslistTargetHandler.js +38 -1
  41. package/lib/config/defaults.js +79 -6
  42. package/lib/config/normalization.js +5 -0
  43. package/lib/config/target.js +10 -0
  44. package/lib/container/ContainerEntryModule.js +8 -5
  45. package/lib/container/FallbackModule.js +4 -4
  46. package/lib/container/RemoteModule.js +4 -2
  47. package/lib/css/CssExportsGenerator.js +139 -0
  48. package/lib/css/CssGenerator.js +109 -0
  49. package/lib/css/CssLoadingRuntimeModule.js +447 -0
  50. package/lib/css/CssModulesPlugin.js +461 -0
  51. package/lib/css/CssParser.js +618 -0
  52. package/lib/css/walkCssTokens.js +659 -0
  53. package/lib/debug/ProfilingPlugin.js +12 -10
  54. package/lib/dependencies/CreateScriptUrlDependency.js +12 -0
  55. package/lib/dependencies/CssExportDependency.js +85 -0
  56. package/lib/dependencies/CssImportDependency.js +75 -0
  57. package/lib/dependencies/CssLocalIdentifierDependency.js +119 -0
  58. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +101 -0
  59. package/lib/dependencies/CssUrlDependency.js +132 -0
  60. package/lib/dependencies/LoaderPlugin.js +2 -2
  61. package/lib/dependencies/URLDependency.js +3 -8
  62. package/lib/esm/ModuleChunkFormatPlugin.js +74 -49
  63. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +1 -1
  64. package/lib/hmr/LazyCompilationPlugin.js +45 -21
  65. package/lib/hmr/lazyCompilationBackend.js +4 -2
  66. package/lib/ids/DeterministicModuleIdsPlugin.js +55 -35
  67. package/lib/ids/HashedModuleIdsPlugin.js +9 -12
  68. package/lib/ids/IdHelpers.js +24 -10
  69. package/lib/ids/NamedModuleIdsPlugin.js +6 -9
  70. package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
  71. package/lib/ids/OccurrenceModuleIdsPlugin.js +13 -10
  72. package/lib/ids/SyncModuleIdsPlugin.js +140 -0
  73. package/lib/index.js +8 -0
  74. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
  75. package/lib/javascript/ChunkHelpers.js +33 -0
  76. package/lib/javascript/JavascriptGenerator.js +1 -0
  77. package/lib/javascript/JavascriptParser.js +16 -8
  78. package/lib/javascript/StartupHelpers.js +4 -28
  79. package/lib/library/AssignLibraryPlugin.js +31 -13
  80. package/lib/library/EnableLibraryPlugin.js +11 -0
  81. package/lib/node/NodeWatchFileSystem.js +85 -31
  82. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +1 -1
  83. package/lib/node/RequireChunkLoadingRuntimeModule.js +1 -1
  84. package/lib/optimize/ConcatenatedModule.js +11 -5
  85. package/lib/runtime/CreateScriptRuntimeModule.js +36 -0
  86. package/lib/runtime/CreateScriptUrlRuntimeModule.js +9 -34
  87. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +76 -0
  88. package/lib/schemes/HttpUriPlugin.js +8 -8
  89. package/lib/sharing/ConsumeSharedModule.js +8 -2
  90. package/lib/sharing/ConsumeSharedRuntimeModule.js +25 -4
  91. package/lib/sharing/ProvideSharedModule.js +4 -2
  92. package/lib/sharing/utils.js +1 -1
  93. package/lib/stats/DefaultStatsFactoryPlugin.js +112 -67
  94. package/lib/stats/DefaultStatsPrinterPlugin.js +89 -24
  95. package/lib/util/AsyncQueue.js +1 -1
  96. package/lib/util/extractUrlAndGlobal.js +3 -0
  97. package/lib/util/fs.js +10 -0
  98. package/lib/util/hash/xxhash64.js +2 -2
  99. package/lib/util/internalSerializables.js +11 -0
  100. package/lib/web/JsonpChunkLoadingRuntimeModule.js +3 -3
  101. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -11
  102. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -2
  103. package/package.json +5 -12
  104. package/schemas/WebpackOptions.check.js +1 -1
  105. package/schemas/WebpackOptions.json +100 -1
  106. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  107. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  108. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  109. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  110. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  111. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  112. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  113. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  114. package/schemas/plugins/container/ModuleFederationPlugin.json +3 -1
  115. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
  116. package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
  117. package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
  118. package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
  119. package/schemas/plugins/css/CssParserOptions.check.js +6 -0
  120. package/schemas/plugins/css/CssParserOptions.json +3 -0
  121. package/types.d.ts +305 -58
@@ -164,10 +164,17 @@ exports.scriptNonce = "__webpack_require__.nc";
164
164
  * function to load a script tag.
165
165
  * Arguments: (url: string, done: (event) => void), key?: string | number, chunkId?: string | number) => void
166
166
  * done function is called when loading has finished or timeout occurred.
167
- * It will attach to existing script tags with data-webpack == key or src == url.
167
+ * It will attach to existing script tags with data-webpack == uniqueName + ":" + key or src == url.
168
168
  */
169
169
  exports.loadScript = "__webpack_require__.l";
170
170
 
171
+ /**
172
+ * function to promote a string to a TrustedScript using webpack's Trusted
173
+ * Types policy
174
+ * Arguments: (script: string) => TrustedScript
175
+ */
176
+ exports.createScript = "__webpack_require__.ts";
177
+
171
178
  /**
172
179
  * function to promote a string to a TrustedScriptURL using webpack's Trusted
173
180
  * Types policy
@@ -175,6 +182,12 @@ exports.loadScript = "__webpack_require__.l";
175
182
  */
176
183
  exports.createScriptUrl = "__webpack_require__.tu";
177
184
 
185
+ /**
186
+ * function to return webpack's Trusted Types policy
187
+ * Arguments: () => TrustedTypePolicy
188
+ */
189
+ exports.getTrustedTypesPolicy = "__webpack_require__.tt";
190
+
178
191
  /**
179
192
  * the chunk name of the chunk with the runtime
180
193
  */
@@ -190,11 +203,26 @@ exports.runtimeId = "__webpack_require__.j";
190
203
  */
191
204
  exports.getChunkScriptFilename = "__webpack_require__.u";
192
205
 
206
+ /**
207
+ * the filename of the css part of the chunk
208
+ */
209
+ exports.getChunkCssFilename = "__webpack_require__.k";
210
+
211
+ /**
212
+ * a flag when a module/chunk/tree has css modules
213
+ */
214
+ exports.hasCssModules = "has css modules";
215
+
193
216
  /**
194
217
  * the filename of the script part of the hot update chunk
195
218
  */
196
219
  exports.getChunkUpdateScriptFilename = "__webpack_require__.hu";
197
220
 
221
+ /**
222
+ * the filename of the css part of the hot update chunk
223
+ */
224
+ exports.getChunkUpdateCssFilename = "__webpack_require__.hk";
225
+
198
226
  /**
199
227
  * startup signal from runtime
200
228
  * This will be called when the runtime chunk has been loaded.
@@ -78,7 +78,7 @@ class RuntimeModule extends Module {
78
78
 
79
79
  /**
80
80
  * @param {NeedBuildContext} context context info
81
- * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
81
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
82
82
  * @returns {void}
83
83
  */
84
84
  needBuild(context, callback) {
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const RuntimeGlobals = require("./RuntimeGlobals");
9
+ const { getChunkFilenameTemplate } = require("./css/CssModulesPlugin");
9
10
  const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
10
11
  const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
11
12
  const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
@@ -13,11 +14,13 @@ const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModu
13
14
  const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
14
15
  const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
15
16
  const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
17
+ const CreateScriptRuntimeModule = require("./runtime/CreateScriptRuntimeModule");
16
18
  const CreateScriptUrlRuntimeModule = require("./runtime/CreateScriptUrlRuntimeModule");
17
19
  const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
18
20
  const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
19
21
  const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
20
22
  const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
23
+ const GetTrustedTypesPolicyRuntimeModule = require("./runtime/GetTrustedTypesPolicyRuntimeModule");
21
24
  const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
22
25
  const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
23
26
  const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
@@ -39,7 +42,9 @@ const GLOBALS_ON_REQUIRE = [
39
42
  RuntimeGlobals.runtimeId,
40
43
  RuntimeGlobals.compatGetDefaultExport,
41
44
  RuntimeGlobals.createFakeNamespaceObject,
45
+ RuntimeGlobals.createScript,
42
46
  RuntimeGlobals.createScriptUrl,
47
+ RuntimeGlobals.getTrustedTypesPolicy,
43
48
  RuntimeGlobals.definePropertyGetters,
44
49
  RuntimeGlobals.ensureChunk,
45
50
  RuntimeGlobals.entryModuleId,
@@ -261,6 +266,30 @@ class RuntimePlugin {
261
266
  );
262
267
  return true;
263
268
  });
269
+ compilation.hooks.runtimeRequirementInTree
270
+ .for(RuntimeGlobals.getChunkCssFilename)
271
+ .tap("RuntimePlugin", (chunk, set) => {
272
+ if (
273
+ typeof compilation.outputOptions.cssChunkFilename === "string" &&
274
+ /\[(full)?hash(:\d+)?\]/.test(
275
+ compilation.outputOptions.cssChunkFilename
276
+ )
277
+ ) {
278
+ set.add(RuntimeGlobals.getFullHash);
279
+ }
280
+ compilation.addRuntimeModule(
281
+ chunk,
282
+ new GetChunkFilenameRuntimeModule(
283
+ "css",
284
+ "css",
285
+ RuntimeGlobals.getChunkCssFilename,
286
+ chunk =>
287
+ getChunkFilenameTemplate(chunk, compilation.outputOptions),
288
+ set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
289
+ )
290
+ );
291
+ return true;
292
+ });
264
293
  compilation.hooks.runtimeRequirementInTree
265
294
  .for(RuntimeGlobals.getChunkUpdateScriptFilename)
266
295
  .tap("RuntimePlugin", (chunk, set) => {
@@ -339,15 +368,36 @@ class RuntimePlugin {
339
368
  );
340
369
  return true;
341
370
  });
371
+ compilation.hooks.runtimeRequirementInTree
372
+ .for(RuntimeGlobals.createScript)
373
+ .tap("RuntimePlugin", (chunk, set) => {
374
+ if (compilation.outputOptions.trustedTypes) {
375
+ set.add(RuntimeGlobals.getTrustedTypesPolicy);
376
+ }
377
+ compilation.addRuntimeModule(chunk, new CreateScriptRuntimeModule());
378
+ return true;
379
+ });
342
380
  compilation.hooks.runtimeRequirementInTree
343
381
  .for(RuntimeGlobals.createScriptUrl)
344
382
  .tap("RuntimePlugin", (chunk, set) => {
383
+ if (compilation.outputOptions.trustedTypes) {
384
+ set.add(RuntimeGlobals.getTrustedTypesPolicy);
385
+ }
345
386
  compilation.addRuntimeModule(
346
387
  chunk,
347
388
  new CreateScriptUrlRuntimeModule()
348
389
  );
349
390
  return true;
350
391
  });
392
+ compilation.hooks.runtimeRequirementInTree
393
+ .for(RuntimeGlobals.getTrustedTypesPolicy)
394
+ .tap("RuntimePlugin", (chunk, set) => {
395
+ compilation.addRuntimeModule(
396
+ chunk,
397
+ new GetTrustedTypesPolicyRuntimeModule(set)
398
+ );
399
+ return true;
400
+ });
351
401
  compilation.hooks.runtimeRequirementInTree
352
402
  .for(RuntimeGlobals.relativeUrl)
353
403
  .tap("RuntimePlugin", (chunk, set) => {
@@ -16,6 +16,7 @@ const { forEachRuntime, subtractRuntime } = require("./util/runtime");
16
16
  /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
17
17
  /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
18
18
  /** @typedef {import("./ChunkGraph")} ChunkGraph */
19
+ /** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
19
20
  /** @typedef {import("./Compilation")} Compilation */
20
21
  /** @typedef {import("./Dependency")} Dependency */
21
22
  /** @typedef {import("./Module")} Module */
@@ -50,6 +51,27 @@ Module has these incoming connections: ${Array.from(
50
51
  ).join("")}`;
51
52
  };
52
53
 
54
+ /**
55
+ * @param {string|undefined} definition global object definition
56
+ * @returns {string} save to use global object
57
+ */
58
+ function getGlobalObject(definition) {
59
+ if (!definition) return definition;
60
+ const trimmed = definition.trim();
61
+
62
+ if (
63
+ // identifier, we do not need real identifier regarding ECMAScript/Unicode
64
+ trimmed.match(/^[_\p{L}][_0-9\p{L}]*$/iu) ||
65
+ // iife
66
+ // call expression
67
+ // expression in parentheses
68
+ trimmed.match(/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu)
69
+ )
70
+ return trimmed;
71
+
72
+ return `Object(${trimmed})`;
73
+ }
74
+
53
75
  class RuntimeTemplate {
54
76
  /**
55
77
  * @param {Compilation} compilation the compilation
@@ -60,6 +82,7 @@ class RuntimeTemplate {
60
82
  this.compilation = compilation;
61
83
  this.outputOptions = outputOptions || {};
62
84
  this.requestShortener = requestShortener;
85
+ this.globalObject = getGlobalObject(outputOptions.globalObject);
63
86
  }
64
87
 
65
88
  isIIFE() {
@@ -78,6 +101,10 @@ class RuntimeTemplate {
78
101
  return this.outputOptions.environment.arrowFunction;
79
102
  }
80
103
 
104
+ supportsOptionalChaining() {
105
+ return this.outputOptions.environment.optionalChaining;
106
+ }
107
+
81
108
  supportsForOf() {
82
109
  return this.outputOptions.environment.forOf;
83
110
  }
@@ -99,8 +126,7 @@ class RuntimeTemplate {
99
126
  }
100
127
 
101
128
  supportTemplateLiteral() {
102
- // TODO
103
- return false;
129
+ return this.outputOptions.environment.templateLiteral;
104
130
  }
105
131
 
106
132
  returningFunction(returnValue, args = "") {
@@ -115,6 +141,71 @@ class RuntimeTemplate {
115
141
  : `function(${args}) {\n${Template.indent(body)}\n}`;
116
142
  }
117
143
 
144
+ /**
145
+ * @param {Array<string|{expr: string}>} args args
146
+ * @returns {string} result expression
147
+ */
148
+ concatenation(...args) {
149
+ const len = args.length;
150
+
151
+ if (len === 2) return this._es5Concatenation(args);
152
+ if (len === 0) return '""';
153
+ if (len === 1) {
154
+ return typeof args[0] === "string"
155
+ ? JSON.stringify(args[0])
156
+ : `"" + ${args[0].expr}`;
157
+ }
158
+ if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);
159
+
160
+ // cost comparison between template literal and concatenation:
161
+ // both need equal surroundings: `xxx` vs "xxx"
162
+ // template literal has constant cost of 3 chars for each expression
163
+ // es5 concatenation has cost of 3 + n chars for n expressions in row
164
+ // when a es5 concatenation ends with an expression it reduces cost by 3
165
+ // when a es5 concatenation starts with an single expression it reduces cost by 3
166
+ // e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3)
167
+ // e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12)
168
+
169
+ let templateCost = 0;
170
+ let concatenationCost = 0;
171
+
172
+ let lastWasExpr = false;
173
+ for (const arg of args) {
174
+ const isExpr = typeof arg !== "string";
175
+ if (isExpr) {
176
+ templateCost += 3;
177
+ concatenationCost += lastWasExpr ? 1 : 4;
178
+ }
179
+ lastWasExpr = isExpr;
180
+ }
181
+ if (lastWasExpr) concatenationCost -= 3;
182
+ if (typeof args[0] !== "string" && typeof args[1] === "string")
183
+ concatenationCost -= 3;
184
+
185
+ if (concatenationCost <= templateCost) return this._es5Concatenation(args);
186
+
187
+ return `\`${args
188
+ .map(arg => (typeof arg === "string" ? arg : `\${${arg.expr}}`))
189
+ .join("")}\``;
190
+ }
191
+
192
+ /**
193
+ * @param {Array<string|{expr: string}>} args args (len >= 2)
194
+ * @returns {string} result expression
195
+ * @private
196
+ */
197
+ _es5Concatenation(args) {
198
+ const str = args
199
+ .map(arg => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr))
200
+ .join(" + ");
201
+
202
+ // when the first two args are expression, we need to prepend "" + to force string
203
+ // concatenation instead of number addition.
204
+ return typeof args[0] !== "string" && typeof args[1] !== "string"
205
+ ? `"" + ${str}`
206
+ : str;
207
+ }
208
+
118
209
  expressionFunction(expression, args = "") {
119
210
  return this.supportsArrowFunction()
120
211
  ? `(${args}) => (${expression})`
@@ -924,6 +1015,26 @@ class RuntimeTemplate {
924
1015
  runtimeRequirements.add(RuntimeGlobals.exports);
925
1016
  return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`;
926
1017
  }
1018
+
1019
+ /**
1020
+ * @param {Object} options options object
1021
+ * @param {Module} options.module the module
1022
+ * @param {string} options.publicPath the public path
1023
+ * @param {RuntimeSpec=} options.runtime runtime
1024
+ * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
1025
+ * @returns {string} the url of the asset
1026
+ */
1027
+ assetUrl({ publicPath, runtime, module, codeGenerationResults }) {
1028
+ if (!module) {
1029
+ return "data:,";
1030
+ }
1031
+ const codeGen = codeGenerationResults.get(module, runtime);
1032
+ const { data } = codeGen;
1033
+ const url = data.get("url");
1034
+ if (url) return url.toString();
1035
+ const filename = data.get("filename");
1036
+ return publicPath + filename;
1037
+ }
927
1038
  }
928
1039
 
929
1040
  module.exports = RuntimeTemplate;
package/lib/Template.js CHANGED
@@ -370,7 +370,8 @@ class Template {
370
370
  dependencyTemplates: renderContext.dependencyTemplates,
371
371
  moduleGraph: renderContext.moduleGraph,
372
372
  runtimeTemplate: renderContext.runtimeTemplate,
373
- runtime: renderContext.chunk.runtime
373
+ runtime: renderContext.chunk.runtime,
374
+ codeGenerationResults
374
375
  });
375
376
  if (!codeGenResult) continue;
376
377
  runtimeSource = codeGenResult.sources.get("runtime");
@@ -87,7 +87,20 @@ class IgnoringWatchFileSystem {
87
87
  fileTimestamps.set(path, IGNORE_TIME_ENTRY);
88
88
  }
89
89
  return fileTimestamps;
90
- }
90
+ },
91
+ getInfo:
92
+ watcher.getInfo &&
93
+ (() => {
94
+ const info = watcher.getInfo();
95
+ const { fileTimeInfoEntries, contextTimeInfoEntries } = info;
96
+ for (const path of ignoredFiles) {
97
+ fileTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
98
+ }
99
+ for (const path of ignoredDirs) {
100
+ contextTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
101
+ }
102
+ return info;
103
+ })
91
104
  };
92
105
  }
93
106
  }
package/lib/Watching.js CHANGED
@@ -15,7 +15,7 @@ const Stats = require("./Stats");
15
15
  /**
16
16
  * @template T
17
17
  * @callback Callback
18
- * @param {Error=} err
18
+ * @param {(Error | null)=} err
19
19
  * @param {T=} result
20
20
  */
21
21
 
@@ -49,7 +49,7 @@ class Watching {
49
49
  this.watchOptions = {};
50
50
  }
51
51
  if (typeof this.watchOptions.aggregateTimeout !== "number") {
52
- this.watchOptions.aggregateTimeout = 200;
52
+ this.watchOptions.aggregateTimeout = 20;
53
53
  }
54
54
  this.compiler = compiler;
55
55
  this.running = false;
@@ -109,30 +109,44 @@ class Watching {
109
109
  this.lastWatcherStartTime = Date.now();
110
110
  }
111
111
  this.compiler.fsStartTime = Date.now();
112
- this._mergeWithCollected(
113
- changedFiles ||
114
- (this.pausedWatcher &&
112
+ if (
113
+ changedFiles &&
114
+ removedFiles &&
115
+ fileTimeInfoEntries &&
116
+ contextTimeInfoEntries
117
+ ) {
118
+ this._mergeWithCollected(changedFiles, removedFiles);
119
+ this.compiler.fileTimestamps = fileTimeInfoEntries;
120
+ this.compiler.contextTimestamps = contextTimeInfoEntries;
121
+ } else if (this.pausedWatcher) {
122
+ if (this.pausedWatcher.getInfo) {
123
+ const {
124
+ changes,
125
+ removals,
126
+ fileTimeInfoEntries,
127
+ contextTimeInfoEntries
128
+ } = this.pausedWatcher.getInfo();
129
+ this._mergeWithCollected(changes, removals);
130
+ this.compiler.fileTimestamps = fileTimeInfoEntries;
131
+ this.compiler.contextTimestamps = contextTimeInfoEntries;
132
+ } else {
133
+ this._mergeWithCollected(
115
134
  this.pausedWatcher.getAggregatedChanges &&
116
- this.pausedWatcher.getAggregatedChanges()),
117
- (this.compiler.removedFiles =
118
- removedFiles ||
119
- (this.pausedWatcher &&
135
+ this.pausedWatcher.getAggregatedChanges(),
120
136
  this.pausedWatcher.getAggregatedRemovals &&
121
- this.pausedWatcher.getAggregatedRemovals()))
122
- );
123
-
137
+ this.pausedWatcher.getAggregatedRemovals()
138
+ );
139
+ this.compiler.fileTimestamps =
140
+ this.pausedWatcher.getFileTimeInfoEntries();
141
+ this.compiler.contextTimestamps =
142
+ this.pausedWatcher.getContextTimeInfoEntries();
143
+ }
144
+ }
124
145
  this.compiler.modifiedFiles = this._collectedChangedFiles;
125
146
  this._collectedChangedFiles = undefined;
126
147
  this.compiler.removedFiles = this._collectedRemovedFiles;
127
148
  this._collectedRemovedFiles = undefined;
128
149
 
129
- this.compiler.fileTimestamps =
130
- fileTimeInfoEntries ||
131
- (this.pausedWatcher && this.pausedWatcher.getFileTimeInfoEntries());
132
- this.compiler.contextTimestamps =
133
- contextTimeInfoEntries ||
134
- (this.pausedWatcher && this.pausedWatcher.getContextTimeInfoEntries());
135
-
136
150
  const run = () => {
137
151
  if (this.compiler.idle) {
138
152
  return this.compiler.cache.endIdle(err => {
@@ -118,11 +118,47 @@ class WebpackOptionsApply extends OptionsApply {
118
118
  if (options.externalsPresets.webAsync) {
119
119
  //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
120
120
  const ExternalsPlugin = require("./ExternalsPlugin");
121
- new ExternalsPlugin("import", /^(https?:\/\/|std:)/).apply(compiler);
121
+ new ExternalsPlugin(
122
+ "import",
123
+ options.experiments.css
124
+ ? ({ request, dependencyType }, callback) => {
125
+ if (dependencyType === "url") {
126
+ if (/^(\/\/|https?:\/\/)/.test(request))
127
+ return callback(null, `asset ${request}`);
128
+ } else if (dependencyType === "css-import") {
129
+ if (/^(\/\/|https?:\/\/)/.test(request))
130
+ return callback(null, `css-import ${request}`);
131
+ } else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
132
+ if (/^\.css(\?|$)/.test(request))
133
+ return callback(null, `css-import ${request}`);
134
+ return callback(null, `import ${request}`);
135
+ }
136
+ callback();
137
+ }
138
+ : /^(\/\/|https?:\/\/|std:)/
139
+ ).apply(compiler);
122
140
  } else if (options.externalsPresets.web) {
123
141
  //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
124
142
  const ExternalsPlugin = require("./ExternalsPlugin");
125
- new ExternalsPlugin("module", /^(https?:\/\/|std:)/).apply(compiler);
143
+ new ExternalsPlugin(
144
+ "module",
145
+ options.experiments.css
146
+ ? ({ request, dependencyType }, callback) => {
147
+ if (dependencyType === "url") {
148
+ if (/^(\/\/|https?:\/\/)/.test(request))
149
+ return callback(null, `asset ${request}`);
150
+ } else if (dependencyType === "css-import") {
151
+ if (/^(\/\/|https?:\/\/)/.test(request))
152
+ return callback(null, `css-import ${request}`);
153
+ } else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
154
+ if (/^\.css(\?|$)/.test(request))
155
+ return callback(null, `css-import ${request}`);
156
+ return callback(null, `module ${request}`);
157
+ }
158
+ callback();
159
+ }
160
+ : /^(\/\/|https?:\/\/|std:)/
161
+ ).apply(compiler);
126
162
  }
127
163
 
128
164
  new ChunkPrefetchPreloadPlugin().apply(compiler);
@@ -253,6 +289,11 @@ class WebpackOptionsApply extends OptionsApply {
253
289
  }).apply(compiler);
254
290
  }
255
291
 
292
+ if (options.experiments.css) {
293
+ const CssModulesPlugin = require("./css/CssModulesPlugin");
294
+ new CssModulesPlugin(options.experiments.css).apply(compiler);
295
+ }
296
+
256
297
  if (options.experiments.lazyCompilation) {
257
298
  const LazyCompilationPlugin = require("./hmr/LazyCompilationPlugin");
258
299
  const lazyOptions =
@@ -15,6 +15,7 @@ const { makePathsRelative } = require("../util/identifier");
15
15
 
16
16
  /** @typedef {import("webpack-sources").Source} Source */
17
17
  /** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
18
+ /** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */
18
19
  /** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */
19
20
  /** @typedef {import("../Compilation")} Compilation */
20
21
  /** @typedef {import("../Compiler")} Compiler */
@@ -49,7 +50,7 @@ const mergeAssetInfo = (a, b) => {
49
50
  case "immutable":
50
51
  case "development":
51
52
  case "hotModuleReplacement":
52
- case "javascriptModule ":
53
+ case "javascriptModule":
53
54
  result[key] = a[key] || b[key];
54
55
  break;
55
56
  case "related":
@@ -74,6 +75,41 @@ const mergeRelatedInfo = (a, b) => {
74
75
  return result;
75
76
  };
76
77
 
78
+ const encodeDataUri = (encoding, source) => {
79
+ let encodedContent;
80
+
81
+ switch (encoding) {
82
+ case "base64": {
83
+ encodedContent = source.buffer().toString("base64");
84
+ break;
85
+ }
86
+ case false: {
87
+ const content = source.source();
88
+
89
+ if (typeof content !== "string") {
90
+ encodedContent = content.toString("utf-8");
91
+ }
92
+
93
+ encodedContent = encodeURIComponent(encodedContent).replace(
94
+ /[!'()*]/g,
95
+ character => "%" + character.codePointAt(0).toString(16)
96
+ );
97
+ break;
98
+ }
99
+ default:
100
+ throw new Error(`Unsupported encoding '${encoding}'`);
101
+ }
102
+
103
+ return encodedContent;
104
+ };
105
+
106
+ const decodeDataUriContent = (encoding, content) => {
107
+ const isBase64 = encoding === "base64";
108
+ return isBase64
109
+ ? Buffer.from(content, "base64")
110
+ : Buffer.from(decodeURIComponent(content), "ascii");
111
+ };
112
+
77
113
  const JS_TYPES = new Set(["javascript"]);
78
114
  const JS_AND_ASSET_TYPES = new Set(["javascript", "asset"]);
79
115
 
@@ -82,13 +118,15 @@ class AssetGenerator extends Generator {
82
118
  * @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url
83
119
  * @param {string=} filename override for output.assetModuleFilename
84
120
  * @param {RawPublicPath=} publicPath override for output.assetModulePublicPath
121
+ * @param {AssetModuleOutputPath=} outputPath the output path for the emitted file which is not included in the runtime import
85
122
  * @param {boolean=} emit generate output asset
86
123
  */
87
- constructor(dataUrlOptions, filename, publicPath, emit) {
124
+ constructor(dataUrlOptions, filename, publicPath, outputPath, emit) {
88
125
  super();
89
126
  this.dataUrlOptions = dataUrlOptions;
90
127
  this.filename = filename;
91
128
  this.publicPath = publicPath;
129
+ this.outputPath = outputPath;
92
130
  this.emit = emit;
93
131
  }
94
132
 
@@ -158,39 +196,26 @@ class AssetGenerator extends Generator {
158
196
  }
159
197
 
160
198
  let encodedContent;
199
+
161
200
  if (
162
201
  module.resourceResolveData &&
163
- module.resourceResolveData.encoding === encoding
202
+ module.resourceResolveData.encoding === encoding &&
203
+ decodeDataUriContent(
204
+ module.resourceResolveData.encoding,
205
+ module.resourceResolveData.encodedContent
206
+ ).equals(originalSource.buffer())
164
207
  ) {
165
208
  encodedContent = module.resourceResolveData.encodedContent;
166
209
  } else {
167
- switch (encoding) {
168
- case "base64": {
169
- encodedContent = originalSource.buffer().toString("base64");
170
- break;
171
- }
172
- case false: {
173
- const content = originalSource.source();
174
-
175
- if (typeof content !== "string") {
176
- encodedContent = content.toString("utf-8");
177
- }
178
-
179
- encodedContent = encodeURIComponent(encodedContent).replace(
180
- /[!'()*]/g,
181
- character => "%" + character.codePointAt(0).toString(16)
182
- );
183
- break;
184
- }
185
- default:
186
- throw new Error(`Unsupported encoding '${encoding}'`);
187
- }
210
+ encodedContent = encodeDataUri(encoding, originalSource);
188
211
  }
189
212
 
190
213
  encodedSource = `data:${mimeType}${
191
214
  encoding ? `;${encoding}` : ""
192
215
  },${encodedContent}`;
193
216
  }
217
+ const data = getData();
218
+ data.set("url", Buffer.from(encodedSource));
194
219
  return new RawSource(
195
220
  `${RuntimeGlobals.module}.exports = ${JSON.stringify(
196
221
  encodedSource
@@ -228,7 +253,7 @@ class AssetGenerator extends Generator {
228
253
  contentHash
229
254
  }
230
255
  );
231
- let publicPath;
256
+ let assetPath;
232
257
  if (this.publicPath !== undefined) {
233
258
  const { path, info } =
234
259
  runtimeTemplate.compilation.getAssetPathWithInfo(
@@ -241,16 +266,34 @@ class AssetGenerator extends Generator {
241
266
  contentHash
242
267
  }
243
268
  );
244
- publicPath = JSON.stringify(path);
245
269
  assetInfo = mergeAssetInfo(assetInfo, info);
270
+ assetPath = JSON.stringify(path + filename);
246
271
  } else {
247
- publicPath = RuntimeGlobals.publicPath;
248
272
  runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p
273
+ assetPath = runtimeTemplate.concatenation(
274
+ { expr: RuntimeGlobals.publicPath },
275
+ filename
276
+ );
249
277
  }
250
278
  assetInfo = {
251
279
  sourceFilename,
252
280
  ...assetInfo
253
281
  };
282
+ if (this.outputPath) {
283
+ const { path: outputPath, info } =
284
+ runtimeTemplate.compilation.getAssetPathWithInfo(
285
+ this.outputPath,
286
+ {
287
+ module,
288
+ runtime,
289
+ filename: sourceFilename,
290
+ chunkGraph,
291
+ contentHash
292
+ }
293
+ );
294
+ assetInfo = mergeAssetInfo(assetInfo, info);
295
+ filename = path.posix.join(outputPath, filename);
296
+ }
254
297
  module.buildInfo.filename = filename;
255
298
  module.buildInfo.assetInfo = assetInfo;
256
299
  if (getData) {
@@ -264,9 +307,7 @@ class AssetGenerator extends Generator {
264
307
  }
265
308
 
266
309
  return new RawSource(
267
- `${
268
- RuntimeGlobals.module
269
- }.exports = ${publicPath} + ${JSON.stringify(filename)};`
310
+ `${RuntimeGlobals.module}.exports = ${assetPath};`
270
311
  );
271
312
  }
272
313
  }