@depup/webpack 5.109.0-depup.0 → 5.109.2-depup.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.
Files changed (62) hide show
  1. package/README.md +4 -4
  2. package/bin/webpack.js +12 -0
  3. package/changes.json +4 -4
  4. package/lib/ChunkGraph.js +17 -15
  5. package/lib/CleanPlugin.js +11 -9
  6. package/lib/CompatibilityPlugin.js +31 -0
  7. package/lib/Compilation.js +21 -5
  8. package/lib/Compiler.js +16 -4
  9. package/lib/DefinePlugin.js +47 -20
  10. package/lib/ExportsInfo.js +22 -5
  11. package/lib/ExternalModule.js +10 -7
  12. package/lib/FileSystemInfo.js +126 -26
  13. package/lib/FlagDependencyUsagePlugin.js +33 -12
  14. package/lib/InitFragment.js +20 -32
  15. package/lib/ModuleFilenameHelpers.js +13 -2
  16. package/lib/NormalModule.js +80 -71
  17. package/lib/NormalModuleFactory.js +8 -2
  18. package/lib/RuntimePlugin.js +40 -113
  19. package/lib/Template.js +23 -3
  20. package/lib/cache/PackFileCacheStrategy.js +259 -5
  21. package/lib/config/defaults.js +21 -2
  22. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  23. package/lib/container/ModuleFederationPlugin.js +15 -9
  24. package/lib/css/CssGenerator.js +8 -2
  25. package/lib/css/CssLoadingRuntimeModule.js +25 -12
  26. package/lib/css/CssModulesPlugin.js +29 -18
  27. package/lib/css/CssParser.js +135 -50
  28. package/lib/css/syntax.js +862 -765
  29. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
  30. package/lib/dependencies/CommonJsFullRequireDependency.js +33 -4
  31. package/lib/dependencies/CommonJsImportsParserPlugin.js +2 -0
  32. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
  33. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
  34. package/lib/dependencies/HarmonyImportDependency.js +1 -1
  35. package/lib/dependencies/HarmonyImportGuard.js +2 -1
  36. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
  37. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +15 -9
  38. package/lib/hmr/lazyCompilationBackend.js +19 -4
  39. package/lib/html/HtmlGenerator.js +23 -3
  40. package/lib/html/HtmlModulesPlugin.js +30 -12
  41. package/lib/html/syntax.js +2485 -2399
  42. package/lib/ids/IdHelpers.js +24 -10
  43. package/lib/javascript/JavascriptModulesPlugin.js +83 -49
  44. package/lib/javascript/JavascriptParser.js +49 -13
  45. package/lib/javascript/syntax.js +700 -43
  46. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +10 -2
  47. package/lib/node/ReadFileCompileWasmPlugin.js +10 -2
  48. package/lib/optimize/AggressiveMergingPlugin.js +19 -15
  49. package/lib/optimize/ConcatenatedModule.js +19 -15
  50. package/lib/optimize/ModuleConcatenationPlugin.js +73 -24
  51. package/lib/optimize/RealContentHashPlugin.js +10 -7
  52. package/lib/optimize/SplitChunksPlugin.js +146 -44
  53. package/lib/prefetch/ResourceHintPlugin.js +96 -72
  54. package/lib/serialization/BinaryMiddleware.js +270 -938
  55. package/lib/serialization/FileMiddleware.js +299 -60
  56. package/lib/stats/DefaultStatsFactoryPlugin.js +204 -198
  57. package/lib/stats/DefaultStatsPrinterPlugin.js +24 -166
  58. package/lib/stats/StatsFactory.js +31 -9
  59. package/lib/util/identifier.js +21 -1
  60. package/package.json +10 -10
  61. package/schemas/WebpackOptions.json +110 -55
  62. package/types.d.ts +832 -247
@@ -95,14 +95,6 @@ const CssParser = require("./CssParser");
95
95
  * @property {Source} moduleSourceContent content
96
96
  */
97
97
 
98
- /**
99
- * Defines the compilation hooks type used by this module.
100
- * @typedef {object} CompilationHooks
101
- * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
102
- * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
103
- * @property {SyncBailHook<[Chunk, Module[], Compilation], Module[] | undefined | void>} orderModules called for each CSS source type (CSS_IMPORT_TYPE, CSS_TYPE) with the chunk's modules pre-sorted by full module name; return an ordered `Module[]` to override the default import-order topological sort, or return `undefined` to keep the default
104
- */
105
-
106
98
  /**
107
99
  * Defines the module factory cache entry type used by this module.
108
100
  * @typedef {object} ModuleFactoryCacheEntry
@@ -220,6 +212,34 @@ const generatorValidationOptions = {
220
212
 
221
213
  const PLUGIN_NAME = "CssModulesPlugin";
222
214
 
215
+ const createCompilationHooks = () => ({
216
+ /**
217
+ * @type {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>}
218
+ * @since 5.94.0
219
+ */
220
+ renderModulePackage: new SyncWaterfallHook([
221
+ "source",
222
+ "module",
223
+ "renderContext"
224
+ ]),
225
+ /**
226
+ * @type {SyncHook<[Chunk, Hash, ChunkHashContext]>}
227
+ * @since 5.94.0
228
+ */
229
+ chunkHash: new SyncHook(["chunk", "hash", "context"]),
230
+ /**
231
+ * Called for each CSS source type (CSS_IMPORT_TYPE, CSS_TYPE) with the chunk's modules pre-sorted by full module name; return an ordered `Module[]` to override the default import-order topological sort, or return `undefined` to keep the default.
232
+ * @type {SyncBailHook<[Chunk, Module[], Compilation], Module[] | undefined | void>}
233
+ * @since 5.107.0
234
+ */
235
+ orderModules: new SyncBailHook(["chunk", "modules", "compilation"])
236
+ });
237
+
238
+ /**
239
+ * Defines the compilation hooks type used by this module.
240
+ * @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks
241
+ */
242
+
223
243
  class CssModulesPlugin {
224
244
  constructor() {
225
245
  /** @type {WeakMap<Source, ModuleFactoryCacheEntry>} */
@@ -1175,16 +1195,7 @@ class CssModulesPlugin {
1175
1195
  }
1176
1196
 
1177
1197
  CssModulesPlugin.getCompilationHooks = createHooksRegistry(
1178
- () =>
1179
- /** @type {CompilationHooks} */ ({
1180
- renderModulePackage: new SyncWaterfallHook([
1181
- "source",
1182
- "module",
1183
- "renderContext"
1184
- ]),
1185
- chunkHash: new SyncHook(["chunk", "hash", "context"]),
1186
- orderModules: new SyncBailHook(["chunk", "modules", "compilation"])
1187
- })
1198
+ createCompilationHooks
1188
1199
  );
1189
1200
 
1190
1201
  module.exports = CssModulesPlugin;
@@ -82,6 +82,7 @@ const CC_FORM_FEED = "\f".charCodeAt(0);
82
82
  const CC_LEFT_CURLY = "{".charCodeAt(0);
83
83
  const CC_LOWER_V = "v".charCodeAt(0);
84
84
  const CC_UPPER_V = "V".charCodeAt(0);
85
+ const CC_REVERSE_SOLIDUS = "\\".charCodeAt(0);
85
86
 
86
87
  // A parsed CSS comment. `loc` is computed on demand — only magic-comment error
87
88
  // warnings read it, so comment-heavy CSS skips the per-comment line/col work.
@@ -595,6 +596,20 @@ const isContainerKeyword = (input, start, end) => {
595
596
  }
596
597
  };
597
598
 
599
+ /**
600
+ * Whether the byte range contains a CSS escape (`\`) — function names are short, so this scan replaces a per-name slice.
601
+ * @param {string} input source
602
+ * @param {number} start start offset
603
+ * @param {number} end end offset (exclusive)
604
+ * @returns {boolean} true when the range contains a backslash
605
+ */
606
+ const rangeHasEscape = (input, start, end) => {
607
+ for (let i = start; i < end; i++) {
608
+ if (input.charCodeAt(i) === CC_REVERSE_SOLIDUS) return true;
609
+ }
610
+ return false;
611
+ };
612
+
598
613
  /**
599
614
  * @param {string} input source
600
615
  * @param {number} pos position
@@ -1848,26 +1863,6 @@ class CssParser extends Parser {
1848
1863
  }
1849
1864
  };
1850
1865
 
1851
- /**
1852
- * The child list of an AST node (a function/block `value` or a rule `prelude`) for sibling lookahead.
1853
- * @param {AstNode | null} parent parent node
1854
- * @returns {AstNode[] | undefined} the child list, or undefined
1855
- */
1856
- const childrenOf = (parent) => {
1857
- if (!parent) return undefined;
1858
- switch (A.type(parent)) {
1859
- case NodeType.Function:
1860
- case NodeType.SimpleBlock:
1861
- case NodeType.Declaration:
1862
- return A.children(parent);
1863
- case NodeType.AtRule:
1864
- case NodeType.QualifiedRule:
1865
- return A.prelude(parent);
1866
- default:
1867
- return undefined;
1868
- }
1869
- };
1870
-
1871
1866
  // `allowImport` mirrors `allowImportAtRule`: true until the first top-level block-bearing rule.
1872
1867
  let allowImport = true;
1873
1868
  // Persistent CSS-Modules mode for a top-level rule: set by bare `:local` / `:global`, leaks into sibling rules, reset at each top-level `}`.
@@ -2639,10 +2634,39 @@ class CssParser extends Parser {
2639
2634
  /**
2640
2635
  * Emit url() deps for a `url(...)` / `src(...)` / `image-set(...)` value function.
2641
2636
  * @param {FunctionNode} fn the function node
2642
- * @param {string} fname the unescaped function name (any case)
2637
+ * @param {string | undefined} escapedName the unescaped function name when it carries an escape, undefined for the raw byte-range path
2643
2638
  */
2644
- const emitUrlFunction = (fn, fname) => {
2645
- if (equalsLowerCase(fname, "url") || equalsLowerCase(fname, "src")) {
2639
+ const emitUrlFunction = (fn, escapedName) => {
2640
+ const fnNameStart = A.nameStart(fn);
2641
+ const fnNameEnd = A.nameEnd(fn);
2642
+ let isUrlOrSrc;
2643
+ let isImageSet = false;
2644
+ if (escapedName !== undefined) {
2645
+ isUrlOrSrc =
2646
+ equalsLowerCase(escapedName, "url") ||
2647
+ equalsLowerCase(escapedName, "src");
2648
+ if (!isUrlOrSrc) isImageSet = IMAGE_SET_FUNCTION.test(escapedName);
2649
+ } else {
2650
+ const nameLength = fnNameEnd - fnNameStart;
2651
+ isUrlOrSrc =
2652
+ nameLength === 3 &&
2653
+ (rangeEqualsLowerCase(input, fnNameStart, fnNameEnd, "url") ||
2654
+ rangeEqualsLowerCase(input, fnNameStart, fnNameEnd, "src"));
2655
+ if (!isUrlOrSrc) {
2656
+ // Suffix probe first, so only a vendor-prefixed `…-image-set` pays the slice + regex.
2657
+ isImageSet =
2658
+ nameLength >= 9 &&
2659
+ rangeEqualsLowerCase(
2660
+ input,
2661
+ fnNameEnd - 9,
2662
+ fnNameEnd,
2663
+ "image-set"
2664
+ ) &&
2665
+ (nameLength === 9 ||
2666
+ IMAGE_SET_FUNCTION.test(input.slice(fnNameStart, fnNameEnd)));
2667
+ }
2668
+ }
2669
+ if (isUrlOrSrc) {
2646
2670
  // Quoted `url("…")` / `src("…")`: first non-whitespace value must be the string token.
2647
2671
  const first = A.children(fn)[nextNonWhitespace(A.children(fn), 0)];
2648
2672
  if (!first || A.type(first) !== NodeType.String) return;
@@ -2673,9 +2697,9 @@ class CssParser extends Parser {
2673
2697
  );
2674
2698
  module.addDependency(dep);
2675
2699
  module.addCodeGenerationDependency(dep);
2676
- } else if (IMAGE_SET_FUNCTION.test(fname)) {
2700
+ } else if (isImageSet) {
2677
2701
  // `image-set(…)`: each comma segment's first string is the URL; advance the magic-comment fence per string.
2678
- lastTokenEndForComments = A.nameEnd(fn) + 1;
2702
+ lastTokenEndForComments = fnNameEnd + 1;
2679
2703
  let prevStringEnd = A.start(fn);
2680
2704
  let firstInSegment = true;
2681
2705
  for (const cv of A.children(fn)) {
@@ -4052,12 +4076,34 @@ class CssParser extends Parser {
4052
4076
  enter: (path) => {
4053
4077
  const node = path.node;
4054
4078
  const fn = /** @type {FunctionNode} */ (node);
4055
- const fnameRaw = A.unescapedName(fn);
4056
- // `equalsLowerCase` keeps this visitor free of a per-function
4057
- // lowercased copy — functions are the densest value nodes.
4058
- const isLocalFn = equalsLowerCase(fnameRaw, "local");
4059
- const isGlobalFn = !isLocalFn && equalsLowerCase(fnameRaw, "global");
4060
- if (urlActive()) emitUrlFunction(fn, fnameRaw);
4079
+ const fnNameStart = A.nameStart(fn);
4080
+ const fnNameEnd = A.nameEnd(fn);
4081
+ const fnNameLength = fnNameEnd - fnNameStart;
4082
+ // Functions are the densest value nodes, so the name is matched by raw byte range; only a name carrying an escape (rare) pays the unescaped slice.
4083
+ /** @type {string | undefined} */
4084
+ let escapedName;
4085
+ let isLocalFn = false;
4086
+ let isGlobalFn = false;
4087
+ if (rangeHasEscape(input, fnNameStart, fnNameEnd)) {
4088
+ escapedName = A.unescapedName(fn);
4089
+ isLocalFn = equalsLowerCase(escapedName, "local");
4090
+ isGlobalFn = !isLocalFn && equalsLowerCase(escapedName, "global");
4091
+ } else if (fnNameLength === 5) {
4092
+ isLocalFn = rangeEqualsLowerCase(
4093
+ input,
4094
+ fnNameStart,
4095
+ fnNameEnd,
4096
+ "local"
4097
+ );
4098
+ } else if (fnNameLength === 6) {
4099
+ isGlobalFn = rangeEqualsLowerCase(
4100
+ input,
4101
+ fnNameStart,
4102
+ fnNameEnd,
4103
+ "global"
4104
+ );
4105
+ }
4106
+ if (urlActive()) emitUrlFunction(fn, escapedName);
4061
4107
  if (localGlobalActive() && (isLocalFn || isGlobalFn)) {
4062
4108
  processLocalOrGlobalFunction(fn, isLocalFn ? 1 : 2);
4063
4109
  }
@@ -4065,10 +4111,16 @@ class CssParser extends Parser {
4065
4111
  icssActive() &&
4066
4112
  !isLocalFn &&
4067
4113
  !isGlobalFn &&
4068
- !(dashed.active && isDashedIdentifier(fnameRaw)) &&
4069
- icssDefinitions.has(fnameRaw)
4114
+ icssDefinitions.size !== 0
4070
4115
  ) {
4071
- emitICSSSymbol(fnameRaw, A.nameStart(fn), A.nameEnd(fn));
4116
+ // Without an escape the raw name equals the unescaped one — only the `@value`-lookup path needs the string at all.
4117
+ const fname = escapedName === undefined ? A.name(fn) : escapedName;
4118
+ if (
4119
+ !(dashed.active && isDashedIdentifier(fname)) &&
4120
+ icssDefinitions.has(fname)
4121
+ ) {
4122
+ emitICSSSymbol(fname, fnNameStart, fnNameEnd);
4123
+ }
4072
4124
  }
4073
4125
  // Dashed-ident scoping: handle this function, then set the child nesting level's state for the walk.
4074
4126
  dashed.push();
@@ -4077,15 +4129,35 @@ class CssParser extends Parser {
4077
4129
  // `local()` / `global()` dashed args go through the ICSS path above, not here.
4078
4130
  dashed.active = false;
4079
4131
  } else if (
4080
- equalsLowerCase(fnameRaw, "var") ||
4081
- equalsLowerCase(fnameRaw, "style")
4132
+ escapedName === undefined
4133
+ ? (fnNameLength === 3 &&
4134
+ rangeEqualsLowerCase(
4135
+ input,
4136
+ fnNameStart,
4137
+ fnNameEnd,
4138
+ "var"
4139
+ )) ||
4140
+ (fnNameLength === 5 &&
4141
+ rangeEqualsLowerCase(
4142
+ input,
4143
+ fnNameStart,
4144
+ fnNameEnd,
4145
+ "style"
4146
+ ))
4147
+ : equalsLowerCase(escapedName, "var") ||
4148
+ equalsLowerCase(escapedName, "style")
4082
4149
  ) {
4083
4150
  // `var(--foo, …)` / `style(--foo, …)`: emit the first ident; the fallback doesn't self-emit.
4084
4151
  processDashedIdentInVarFunction(fn);
4085
4152
  dashed.emit = false;
4086
- } else if (dashed.emit && isDashedIdentifier(A.name(fn))) {
4087
- // Custom-function call `--my-func(args)` — the name is the exported dashed-ident.
4088
- emitDashedIdentExport(A.nameStart(fn), A.nameEnd(fn));
4153
+ } else if (
4154
+ dashed.emit &&
4155
+ fnNameLength >= 3 &&
4156
+ input.charCodeAt(fnNameStart) === CC_HYPHEN_MINUS &&
4157
+ input.charCodeAt(fnNameStart + 1) === CC_HYPHEN_MINUS
4158
+ ) {
4159
+ // Custom-function call `--my-func(args)` — the name is the exported dashed-ident (a literal `--` prefix, like the `A.name` string check it replaces).
4160
+ emitDashedIdentExport(fnNameStart, fnNameEnd);
4089
4161
  }
4090
4162
  }
4091
4163
  },
@@ -4107,23 +4179,36 @@ class CssParser extends Parser {
4107
4179
  if (dashedActive && isDashedIdentifier(identValue)) {
4108
4180
  // Dashed idents are scoped here, never `@value` ICSS-rewritten.
4109
4181
  if (!dashed.emit) return;
4110
- // Resolve the `--foo from "./x.css"` / `--foo from global` import suffix via sibling lookahead.
4111
- const siblings = childrenOf(path.parent);
4112
- const i = siblings ? siblings.indexOf(node) : -1;
4113
- if (siblings && i !== -1) {
4114
- const j = nextNonWhitespace(siblings, i + 1);
4182
+ // Resolve the `--foo from "./x.css"` / `--foo from global` import suffix via sibling lookahead over the parent's child span (`path.index` avoids materializing the sibling list per dashed ident).
4183
+ const parent = path.parent;
4184
+ if (parent) {
4185
+ const count = A.childCount(parent);
4186
+ let j = path.index + 1;
4187
+ while (
4188
+ j < count &&
4189
+ A.type(A.childAt(parent, j)) === NodeType.Whitespace
4190
+ ) {
4191
+ j++;
4192
+ }
4193
+ const fromIdent = j < count ? A.childAt(parent, j) : undefined;
4115
4194
  if (
4116
- j < siblings.length &&
4117
- A.type(siblings[j]) === NodeType.Ident &&
4195
+ fromIdent &&
4196
+ A.type(fromIdent) === NodeType.Ident &&
4118
4197
  rangeEqualsLowerCase(
4119
4198
  input,
4120
- A.start(siblings[j]),
4121
- A.end(siblings[j]),
4199
+ A.start(fromIdent),
4200
+ A.end(fromIdent),
4122
4201
  "from"
4123
4202
  )
4124
4203
  ) {
4125
- const fromIdent = siblings[j];
4126
- const sourceNode = siblings[nextNonWhitespace(siblings, j + 1)];
4204
+ j++;
4205
+ while (
4206
+ j < count &&
4207
+ A.type(A.childAt(parent, j)) === NodeType.Whitespace
4208
+ ) {
4209
+ j++;
4210
+ }
4211
+ const sourceNode = j < count ? A.childAt(parent, j) : undefined;
4127
4212
  if (
4128
4213
  sourceNode &&
4129
4214
  A.type(sourceNode) === NodeType.Ident &&