webpack 5.110.3 → 5.111.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 (208) hide show
  1. package/README.md +5 -0
  2. package/lib/APIPlugin.js +23 -7
  3. package/lib/AutomaticPrefetchPlugin.js +1 -1
  4. package/lib/Cache.js +8 -3
  5. package/lib/CacheFacade.js +1 -1
  6. package/lib/CircularModulesPlugin.js +157 -55
  7. package/lib/CleanPlugin.js +2 -2
  8. package/lib/Compilation.js +320 -302
  9. package/lib/Compiler.js +209 -46
  10. package/lib/ContextModule.js +17 -81
  11. package/lib/ContextModuleFactory.js +1 -1
  12. package/lib/CopyPlugin.js +1054 -0
  13. package/lib/DefinePlugin.js +24 -8
  14. package/lib/ExternalModule.js +41 -14
  15. package/lib/FileSystemInfo.js +17 -14
  16. package/lib/FlagDependencyExportsPlugin.js +45 -21
  17. package/lib/HotModuleReplacementPlugin.js +53 -7
  18. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  19. package/lib/MainTemplate.js +5 -1
  20. package/lib/Module.js +16 -7
  21. package/lib/MultiCompiler.js +1 -1
  22. package/lib/MultiWatching.js +1 -1
  23. package/lib/NormalModule.js +45 -12
  24. package/lib/NormalModuleFactory.js +1 -1
  25. package/lib/RuntimeGlobals.js +21 -7
  26. package/lib/RuntimeModule.js +28 -12
  27. package/lib/RuntimePlugin.js +30 -3
  28. package/lib/RuntimeTemplate.js +780 -475
  29. package/lib/SourceMapDevToolPlugin.js +1 -1
  30. package/lib/Watching.js +9 -0
  31. package/lib/WebpackOptionsApply.js +84 -91
  32. package/lib/asset/AssetGenerator.js +25 -8
  33. package/lib/asset/AssetModule.js +3 -0
  34. package/lib/asset/WebManifestParser.js +7 -5
  35. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  36. package/lib/cache/IdleFileCachePlugin.js +2 -2
  37. package/lib/cache/PackFileCacheStrategy.js +14 -1
  38. package/lib/config/browserslistTargetHandler.js +19 -0
  39. package/lib/config/defaults.js +86 -50
  40. package/lib/config/normalization.js +82 -12
  41. package/lib/config/target.js +10 -0
  42. package/lib/container/ContainerReferencePlugin.js +6 -0
  43. package/lib/container/RemoteRuntimeModule.js +9 -0
  44. package/lib/container/declaredRemotes.js +39 -0
  45. package/lib/css/CssGenerator.js +8 -0
  46. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  47. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  48. package/lib/css/CssModule.js +1 -1
  49. package/lib/css/CssModulesPlugin.js +7 -6
  50. package/lib/css/CssParser.js +144 -11
  51. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  52. package/lib/css/cssMinify.js +11 -3
  53. package/lib/css/data.js +2814 -678
  54. package/lib/css/syntax.js +4082 -248
  55. package/lib/debug/ProfilingPlugin.js +4 -0
  56. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  57. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  58. package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
  59. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  60. package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
  61. package/lib/dependencies/CommonJsPlugin.js +19 -3
  62. package/lib/dependencies/CommonJsRequireDependency.js +14 -5
  63. package/lib/dependencies/CssIcssExportDependency.js +7 -1
  64. package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
  65. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
  66. package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
  67. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +71 -13
  68. package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
  69. package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
  70. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  71. package/lib/dependencies/HarmonyImportDependency.js +6 -1
  72. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -1
  73. package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
  74. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  75. package/lib/dependencies/HtmlEntryDependency.js +50 -0
  76. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  77. package/lib/dependencies/ImportMetaPlugin.js +59 -15
  78. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  79. package/lib/dependencies/WorkerDependency.js +1 -2
  80. package/lib/dependencies/WorkletDependency.js +1 -2
  81. package/lib/dll/DelegatedModule.js +18 -1
  82. package/lib/dll/DllReferencePlugin.js +11 -8
  83. package/lib/dll/LibManifestPlugin.js +1 -1
  84. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  85. package/lib/errors/DuplicateModulesWarning.js +12 -7
  86. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  87. package/lib/errors/ExternalStarReexportError.js +44 -0
  88. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  89. package/lib/errors/ModuleParseError.js +2 -1
  90. package/lib/errors/UnusedAssetsWarning.js +36 -0
  91. package/lib/errors/UnusedFederationWarning.js +35 -0
  92. package/lib/errors/UnusedModulesWarning.js +38 -0
  93. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  94. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  95. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  96. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  97. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  98. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  99. package/lib/html/HtmlGenerator.js +11 -5
  100. package/lib/html/HtmlModulesPlugin.js +331 -62
  101. package/lib/html/HtmlParser.js +13 -6
  102. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  103. package/lib/html/data.js +121 -7
  104. package/lib/html/htmlMinify.js +84 -113
  105. package/lib/html/syntax.js +763 -426
  106. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  107. package/lib/index.js +3 -0
  108. package/lib/javascript/JavascriptModule.js +1 -0
  109. package/lib/javascript/JavascriptModulesPlugin.js +52 -24
  110. package/lib/javascript/JavascriptParser.js +1255 -728
  111. package/lib/javascript/StartupHelpers.js +27 -3
  112. package/lib/javascript/data.js +172 -0
  113. package/lib/javascript/grammar.js +5546 -0
  114. package/lib/javascript/parser.js +1494 -0
  115. package/lib/javascript/regexp.js +1762 -0
  116. package/lib/javascript/regexpData.js +51 -0
  117. package/lib/javascript/syntax.js +8696 -5225
  118. package/lib/library/ModuleLibraryPlugin.js +116 -5
  119. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  120. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  121. package/lib/optimize/ConcatenatedModule.js +97 -20
  122. package/lib/optimize/ConstExportsPlugin.js +50 -39
  123. package/lib/optimize/InlineExports.js +20 -123
  124. package/lib/optimize/MangleExportsPlugin.js +10 -0
  125. package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
  126. package/lib/optimize/RealContentHashPlugin.js +68 -9
  127. package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
  128. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  129. package/lib/performance/CacheEffectivenessPlugin.js +4 -3
  130. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  131. package/lib/performance/EvalUsagePlugin.js +5 -2
  132. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  133. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  134. package/lib/performance/TopLevelThisPlugin.js +5 -4
  135. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  136. package/lib/performance/UnusedFederationPlugin.js +147 -0
  137. package/lib/performance/UnusedModulesPlugin.js +141 -0
  138. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  139. package/lib/performance/isOnlyReexported.js +65 -0
  140. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  141. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
  142. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  143. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  144. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  145. package/lib/prefetch/ResourceHintPlugin.js +1 -2
  146. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  147. package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
  148. package/lib/rules/RuleSetCompiler.js +211 -4
  149. package/lib/runtime/AsyncModuleRuntimeModule.js +100 -66
  150. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  151. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  152. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  153. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  154. package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
  155. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  156. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  157. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  158. package/lib/runtime/GlobalRuntimeModule.js +9 -0
  159. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  160. package/lib/runtime/HelperRuntimeModule.js +10 -0
  161. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +330 -219
  162. package/lib/runtime/NonceRuntimeModule.js +9 -0
  163. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  164. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  165. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  166. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  167. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  168. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  169. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  170. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  171. package/lib/serialization/ObjectMiddleware.js +138 -106
  172. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  173. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  174. package/lib/sharing/ShareRuntimeModule.js +9 -0
  175. package/lib/sharing/declaredShared.js +47 -0
  176. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
  177. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  178. package/lib/util/SourceProcessor.js +76 -69
  179. package/lib/util/async.js +292 -0
  180. package/lib/util/buildDiagnostics.js +69 -0
  181. package/lib/util/fs.js +27 -1
  182. package/lib/util/handlerKeys.js +40 -0
  183. package/lib/util/identifier.js +20 -0
  184. package/lib/util/internalSerializables.js +4 -0
  185. package/lib/util/registerExternalSerializer.js +6 -45
  186. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  187. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  188. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
  189. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  190. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  191. package/package.json +22 -16
  192. package/schemas/WebpackOptions.check.js +1 -1
  193. package/schemas/WebpackOptions.json +379 -66
  194. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  195. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  197. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  198. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  199. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  202. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  203. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  204. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  205. package/types.d.ts +1414 -314
  206. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  207. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  208. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -7,12 +7,31 @@
7
7
  const RuntimeGlobals = require("../RuntimeGlobals");
8
8
  const RuntimeModule = require("../RuntimeModule");
9
9
  const Template = require("../Template");
10
+ const { getOnlyHandlerKey } = require("../util/handlerKeys");
11
+ const { propertyAccess } = require("../util/property");
10
12
 
11
13
  /** @import Compilation from "../Compilation" */
14
+ /** @import { ReadOnlyRuntimeRequirements } from "../Module" */
12
15
 
13
16
  class OnChunksLoadedRuntimeModule extends RuntimeModule {
14
- constructor() {
17
+ /**
18
+ * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
19
+ */
20
+ constructor(runtimeRequirements) {
15
21
  super("chunk loaded");
22
+ /** @type {ReadOnlyRuntimeRequirements} */
23
+ this.runtimeRequirements = runtimeRequirements;
24
+ }
25
+
26
+ /**
27
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
28
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
29
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
30
+ */
31
+ getInstalledChunkHandlers() {
32
+ // Reads a map rather than installing onto one, so reading its code back would
33
+ // render it in a cycle.
34
+ return RuntimeModule.NO_CHUNK_HANDLERS;
16
35
  }
17
36
 
18
37
  /**
@@ -22,24 +41,38 @@ class OnChunksLoadedRuntimeModule extends RuntimeModule {
22
41
  generate() {
23
42
  const compilation = /** @type {Compilation} */ (this.compilation);
24
43
  const { runtimeTemplate } = compilation;
44
+ // Only a prefetch startup callback is queued behind a priority, so without one
45
+ // the queue keeps insertion order and nothing has to hold the lowest seen.
46
+ const withPriority = this.runtimeRequirements.has(
47
+ RuntimeGlobals.hasChunkPriority
48
+ );
49
+ const only = getOnlyHandlerKey(this, RuntimeGlobals.onChunksLoaded);
25
50
  return Template.asString([
26
51
  `${runtimeTemplate.renderConst()} deferred = [];`,
27
52
  `${RuntimeGlobals.onChunksLoaded} = ${runtimeTemplate.basicFunction(
28
- "result, chunkIds, fn, priority",
53
+ `result, chunkIds, fn${withPriority ? ", priority" : ""}`,
29
54
  [
30
55
  "if(chunkIds) {",
31
- Template.indent([
32
- `${runtimeTemplate.assignOr("priority", "0")};`,
33
- "for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];",
34
- "deferred[i] = [chunkIds, fn, priority];",
35
- "return;"
36
- ]),
56
+ Template.indent(
57
+ withPriority
58
+ ? [
59
+ `${runtimeTemplate.assignOr("priority", "0")};`,
60
+ "for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];",
61
+ "deferred[i] = [chunkIds, fn, priority];",
62
+ "return;"
63
+ ]
64
+ : ["deferred.push([chunkIds, fn]);", "return;"]
65
+ ),
37
66
  "}",
38
- `${runtimeTemplate.renderLet()} notFulfilled = Infinity;`,
67
+ ...(withPriority
68
+ ? [`${runtimeTemplate.renderLet()} notFulfilled = Infinity;`]
69
+ : []),
39
70
  "for (var i = 0; i < deferred.length; i++) {",
40
71
  Template.indent([
41
72
  runtimeTemplate.destructureArray(
42
- ["chunkIds", "fn", "priority"],
73
+ withPriority
74
+ ? ["chunkIds", "fn", "priority"]
75
+ : ["chunkIds", "fn"],
43
76
  "deferred[i]"
44
77
  ),
45
78
  `${runtimeTemplate.renderLet()} fulfilled = true;`,
@@ -47,18 +80,32 @@ class OnChunksLoadedRuntimeModule extends RuntimeModule {
47
80
  Template.indent([
48
81
  // Parenthesized: `&` binds looser than `===`, so `priority & 1 === 0`
49
82
  // is `priority & false` and gates every priority, not just the odd ones.
50
- `if (((priority & 1) === 0 || notFulfilled >= priority) && Object.keys(${
51
- RuntimeGlobals.onChunksLoaded
52
- }).every(${runtimeTemplate.returningFunction(
53
- `${RuntimeGlobals.onChunksLoaded}[key](chunkIds[j])`,
54
- "key"
55
- )})) {`,
83
+ `if (${
84
+ withPriority
85
+ ? "((priority & 1) === 0 || notFulfilled >= priority) && "
86
+ : ""
87
+ }${
88
+ only === null
89
+ ? `Object.keys(${
90
+ RuntimeGlobals.onChunksLoaded
91
+ }).every(${runtimeTemplate.returningFunction(
92
+ `${RuntimeGlobals.onChunksLoaded}[key](chunkIds[j])`,
93
+ "key"
94
+ )})`
95
+ : `${RuntimeGlobals.onChunksLoaded}${propertyAccess([
96
+ only
97
+ ])}(chunkIds[j])`
98
+ }) {`,
56
99
  Template.indent(["chunkIds.splice(j--, 1);"]),
57
100
  "} else {",
58
- Template.indent([
59
- "fulfilled = false;",
60
- "if(priority < notFulfilled) notFulfilled = priority;"
61
- ]),
101
+ Template.indent(
102
+ withPriority
103
+ ? [
104
+ "fulfilled = false;",
105
+ "if(priority < notFulfilled) notFulfilled = priority;"
106
+ ]
107
+ : ["fulfilled = false;"]
108
+ ),
62
109
  "}"
63
110
  ]),
64
111
  "}",
@@ -30,6 +30,15 @@ class PublicPathRuntimeModule extends RuntimeModule {
30
30
  this.publicPath = publicPath;
31
31
  }
32
32
 
33
+ /**
34
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
35
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
36
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
37
+ */
38
+ getInstalledChunkHandlers() {
39
+ return RuntimeModule.NO_CHUNK_HANDLERS;
40
+ }
41
+
33
42
  /**
34
43
  * Generates runtime code for this runtime module.
35
44
  * @returns {string | null} runtime code
@@ -25,6 +25,15 @@ class RuntimeIdRuntimeModule extends RuntimeModule {
25
25
  return false;
26
26
  }
27
27
 
28
+ /**
29
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
30
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
31
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
32
+ */
33
+ getInstalledChunkHandlers() {
34
+ return RuntimeModule.NO_CHUNK_HANDLERS;
35
+ }
36
+
28
37
  /**
29
38
  * Generates runtime code for this runtime module.
30
39
  * @returns {string | null} runtime code
@@ -0,0 +1,90 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Alexander Akait @alexander-akait
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const RuntimeGlobals = require("../RuntimeGlobals");
9
+ const Template = require("../Template");
10
+ const HelperRuntimeModule = require("./HelperRuntimeModule");
11
+
12
+ /** @import Compilation from "../Compilation" */
13
+
14
+ class SpecNamespaceObjectRuntimeModule extends HelperRuntimeModule {
15
+ constructor() {
16
+ super("spec namespace object");
17
+ }
18
+
19
+ /**
20
+ * Generates runtime code for this runtime module.
21
+ * @returns {string | null} runtime code
22
+ */
23
+ generate() {
24
+ const compilation = /** @type {Compilation} */ (this.compilation);
25
+ const { runtimeTemplate } = compilation;
26
+ const cst = runtimeTemplate.renderConst();
27
+ const lt = runtimeTemplate.renderLet();
28
+ const fn = RuntimeGlobals.specNamespaceObject;
29
+ return Template.asString([
30
+ `${fn} = ${runtimeTemplate.basicFunction("exports, record, mode", [
31
+ // One namespace per module: a module's own exports object identifies it,
32
+ // while a synthesized one is fresh per site, so its record identifies it.
33
+ `${cst} owner = record || exports;`,
34
+ `${lt} slots = ${fn}.c.get(owner);`,
35
+ `if (!slots) ${fn}.c.set(owner, (slots = { __proto__: null }));`,
36
+ // A synthesized namespace carries different names per mode, so one
37
+ // module can owe its importers more than one namespace.
38
+ `${cst} cached = slots[mode];`,
39
+ "if (cached) return cached;",
40
+ // The exports object keeps the live bindings; the sealed target
41
+ // carries only their names, so the traps stay invariant-safe.
42
+ `${cst} names = Object.getOwnPropertyNames(exports).filter(${runtimeTemplate.returningFunction(
43
+ "name !== '__esModule'",
44
+ "name"
45
+ )}).sort();`,
46
+ `${cst} target = { __proto__: null };`,
47
+ "for (var i = 0; i < names.length; i++) Object.defineProperty(target, names[i], { value: undefined, writable: true, enumerable: true, configurable: false });",
48
+ "Object.defineProperty(target, Symbol.toStringTag, { value: 'Module' });",
49
+ "Object.preventExtensions(target);",
50
+ `${cst} own = ${runtimeTemplate.returningFunction(
51
+ "typeof name === 'string' && Object.prototype.hasOwnProperty.call(target, name)",
52
+ "name"
53
+ )};`,
54
+ `${cst} ns = new Proxy(target, {`,
55
+ Template.indent([
56
+ "__proto__: null,",
57
+ "getPrototypeOf: function() { return null; },",
58
+ "setPrototypeOf: function(_, proto) { return proto === null; },",
59
+ "isExtensible: function() { return false; },",
60
+ "preventExtensions: function() { return true; },",
61
+ "get: function(_, name, receiver) { return own(name) ? exports[name] : Reflect.get(target, name, receiver); },",
62
+ "has: function(_, name) { return own(name) || Reflect.has(target, name); },",
63
+ "ownKeys: function() { return Reflect.ownKeys(target); },",
64
+ "getOwnPropertyDescriptor: function(_, name) { return own(name) ? { value: exports[name], writable: true, enumerable: true, configurable: false } : Reflect.getOwnPropertyDescriptor(target, name); },",
65
+ "set: function() { return false; },",
66
+ // A namespace may only be redefined to the descriptor it
67
+ // already reports, so anything else is rejected.
68
+ "defineProperty: function(_, name, descriptor) {",
69
+ Template.indent([
70
+ // Symbol keys are ordinary, so redefining Symbol.toStringTag
71
+ // to the descriptor it already has must still succeed.
72
+ "if (typeof name === 'symbol') return Reflect.defineProperty(target, name, descriptor);",
73
+ "if (!own(name) || 'get' in descriptor || 'set' in descriptor) return false;",
74
+ "if (descriptor.configurable === true || descriptor.enumerable === false || descriptor.writable === false) return false;",
75
+ "return !('value' in descriptor) || Object.is(descriptor.value, exports[name]);"
76
+ ]),
77
+ "},",
78
+ "deleteProperty: function(_, name) { return !own(name) && !Reflect.has(target, name); }"
79
+ ]),
80
+ "});",
81
+ "slots[mode] = ns;",
82
+ "return ns;"
83
+ ])};`,
84
+ // The same owner must always yield the same namespace.
85
+ `${fn}.c = new WeakMap();`
86
+ ]);
87
+ }
88
+ }
89
+
90
+ module.exports = SpecNamespaceObjectRuntimeModule;
@@ -23,6 +23,15 @@ class StartupChunkDependenciesRuntimeModule extends RuntimeModule {
23
23
  this.asyncChunkLoading = asyncChunkLoading;
24
24
  }
25
25
 
26
+ /**
27
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
28
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
29
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
30
+ */
31
+ getInstalledChunkHandlers() {
32
+ return RuntimeModule.NO_CHUNK_HANDLERS;
33
+ }
34
+
26
35
  /**
27
36
  * Generates runtime code for this runtime module.
28
37
  * @returns {string | null} runtime code
@@ -31,6 +31,15 @@ class StartupEntrypointRuntimeModule extends RuntimeModule {
31
31
  this.asyncChunkLoading = asyncChunkLoading;
32
32
  }
33
33
 
34
+ /**
35
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
36
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
37
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
38
+ */
39
+ getInstalledChunkHandlers() {
40
+ return RuntimeModule.NO_CHUNK_HANDLERS;
41
+ }
42
+
34
43
  /**
35
44
  * Generates runtime code for this runtime module.
36
45
  * @returns {string | null} runtime code
@@ -22,6 +22,15 @@ class SystemContextRuntimeModule extends RuntimeModule {
22
22
  return false;
23
23
  }
24
24
 
25
+ /**
26
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
27
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
28
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
29
+ */
30
+ getInstalledChunkHandlers() {
31
+ return RuntimeModule.NO_CHUNK_HANDLERS;
32
+ }
33
+
25
34
  /**
26
35
  * Generates runtime code for this runtime module.
27
36
  * @returns {string | null} runtime code
@@ -16,6 +16,15 @@ class ToBinaryRuntimeModule extends RuntimeModule {
16
16
  super("to binary");
17
17
  }
18
18
 
19
+ /**
20
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
21
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
22
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
23
+ */
24
+ getInstalledChunkHandlers() {
25
+ return RuntimeModule.NO_CHUNK_HANDLERS;
26
+ }
27
+
19
28
  /**
20
29
  * Generates runtime code for this runtime module.
21
30
  * @returns {string | null} runtime code
@@ -107,21 +107,6 @@ Technically any value can be used.
107
107
  * @property {(context: ObjectDeserializerContext<EXPECTED_ANY>) => EXPECTED_ANY} deserialize
108
108
  */
109
109
 
110
- /**
111
- * Updates set size using the provided set.
112
- * @template T
113
- * @param {Set<T>} set set
114
- * @param {number} size count of items to keep
115
- */
116
- const setSetSize = (set, size) => {
117
- let i = 0;
118
- for (const item of set) {
119
- if (i++ >= size) {
120
- set.delete(item);
121
- }
122
- }
123
- };
124
-
125
110
  /**
126
111
  * Updates map size using the provided map.
127
112
  * @template K, X
@@ -149,6 +134,9 @@ const toHash = (buffer, hashFunction) => {
149
134
  return hash.digest("latin1");
150
135
  };
151
136
 
137
+ /** Marks an object whose children are still being written; never a real position. */
138
+ const IN_PROGRESS = -1;
139
+
152
140
  const ESCAPE = null;
153
141
  const ESCAPE_ESCAPE_VALUE = null;
154
142
  const ESCAPE_END_OBJECT = true;
@@ -463,16 +451,22 @@ class ObjectMiddleware extends SerializerMiddleware {
463
451
  let currentPosTypeLookup = 0;
464
452
  /** @type {Map<SerializerConfigWithSerializer, number>} */
465
453
  let objectTypeLookup = new Map();
466
- /** @type {Set<ComplexSerializableType>} */
467
- const cycleStack = new Set();
454
+ /**
455
+ * One-entry cache in front of `objectTypeLookup`, since runs of one class are common.
456
+ * @type {SerializerConfigWithSerializer | undefined}
457
+ */
458
+ let lastConfig;
459
+ /** @type {number} */
460
+ let lastConfigIndex = 0;
461
+ /** @type {ComplexSerializableType[]} */
462
+ const cycleStack = [];
468
463
  /**
469
464
  * Returns stack.
470
465
  * @param {ComplexSerializableType} item item to stack
471
466
  * @returns {string} stack
472
467
  */
473
468
  const stackToString = (item) => {
474
- const arr = [...cycleStack];
475
- arr.push(item);
469
+ const arr = [...cycleStack, item];
476
470
  return arr
477
471
  .map((item) => {
478
472
  if (typeof item === "string") {
@@ -528,63 +522,35 @@ class ObjectMiddleware extends SerializerMiddleware {
528
522
  };
529
523
  /** @type {undefined | WeakSet<Error>} */
530
524
  let hasDebugInfoAttached;
531
- /** @type {ObjectSerializerContext<EXPECTED_ANY>} */
532
- let ctx = {
533
- write(value) {
534
- try {
535
- process(/** @type {ComplexSerializableType} */ (value));
536
- } catch (err) {
537
- if (err !== NOT_SERIALIZABLE) {
538
- if (hasDebugInfoAttached === undefined) {
539
- hasDebugInfoAttached = new WeakSet();
540
- }
541
- if (!hasDebugInfoAttached.has(/** @type {Error} */ (err))) {
542
- /** @type {Error} */
543
- (err).message +=
544
- `\nwhile serializing ${stackToString(/** @type {ComplexSerializableType} */ (value))}`;
545
- hasDebugInfoAttached.add(/** @type {Error} */ (err));
546
- }
547
- }
548
- throw err;
549
- }
550
- return ctx;
551
- },
552
- setCircularReference(ref) {
553
- addReferenceable(ref);
554
- },
555
- snapshot() {
556
- return {
557
- length: result.length,
558
- cycleStackSize: cycleStack.size,
559
- referenceableSize: referenceable.size,
560
- currentPos,
561
- objectTypeLookupSize: objectTypeLookup.size,
562
- currentPosTypeLookup
563
- };
564
- },
565
- rollback(snapshot) {
566
- result.length = snapshot.length;
567
- setSetSize(cycleStack, snapshot.cycleStackSize);
568
- setMapSize(referenceable, snapshot.referenceableSize);
569
- currentPos = snapshot.currentPos;
570
- setMapSize(objectTypeLookup, snapshot.objectTypeLookupSize);
571
- currentPosTypeLookup = snapshot.currentPosTypeLookup;
572
- },
573
- ...context
525
+ /**
526
+ * Appends the path from the root to `item`, once per error.
527
+ * @param {Error} err error thrown while writing `item`
528
+ * @param {ComplexSerializableType} item item being written
529
+ * @returns {Error} err
530
+ */
531
+ const attachSerializationPath = (err, item) => {
532
+ if (hasDebugInfoAttached === undefined) {
533
+ hasDebugInfoAttached = new WeakSet();
534
+ }
535
+ if (!hasDebugInfoAttached.has(err)) {
536
+ err.message += `\nwhile serializing ${stackToString(item)}`;
537
+ hasDebugInfoAttached.add(err);
538
+ }
539
+ return err;
574
540
  };
575
- this.extendContext(ctx);
576
541
  // Dispatched on `typeof` first: two thirds of the items are numbers,
577
542
  // booleans and `undefined`, and only 3% are buffers.
578
543
  /**
579
- * Processes the provided item.
544
+ * Writes one item into the output; the context is returned so writes chain.
580
545
  * @param {ComplexSerializableType} item item to serialize
546
+ * @returns {ObjectSerializerContext<EXPECTED_ANY>} context
581
547
  */
582
548
  const process = (item) => {
583
549
  switch (typeof item) {
584
550
  case "number":
585
551
  case "boolean":
586
552
  result.push(item);
587
- return;
553
+ return ctx;
588
554
  case "string": {
589
555
  if (item.length > 1) {
590
556
  // short strings are shorter when not emitting a reference (this saves 1 byte per empty string)
@@ -602,10 +568,10 @@ class ObjectMiddleware extends SerializerMiddleware {
602
568
  ) {
603
569
  // A back-reference is `null` + the offset.
604
570
  result.push(ESCAPE, offset);
605
- return;
571
+ return ctx;
606
572
  }
607
573
  }
608
- addReferenceable(item);
574
+ referenceable.set(item, currentPos++);
609
575
  }
610
576
 
611
577
  if (item.length > 102400 && context.logger) {
@@ -617,87 +583,115 @@ class ObjectMiddleware extends SerializerMiddleware {
617
583
  }
618
584
 
619
585
  result.push(item);
620
- return;
586
+ return ctx;
621
587
  }
622
588
  case "undefined":
623
589
  result.push(ESCAPE, ESCAPE_UNDEFINED);
624
- return;
590
+ return ctx;
625
591
  case "object": {
626
592
  // ESCAPE is null, so this covers null too
627
593
  if (item === ESCAPE) {
628
594
  result.push(ESCAPE, ESCAPE_ESCAPE_VALUE);
629
- return;
595
+ return ctx;
630
596
  }
631
597
 
632
- if (Buffer.isBuffer(item)) {
633
- // check if we can emit a reference
634
- const ref = referenceable.get(item);
635
- if (ref !== undefined) {
636
- result.push(ESCAPE, ref - currentPos);
637
- return;
598
+ // buffers and objects share one reference table, so a single
599
+ // lookup answers both before the costlier buffer test
600
+ const ref = referenceable.get(item);
601
+ if (ref !== undefined) {
602
+ if (ref === IN_PROGRESS) {
603
+ throw attachSerializationPath(
604
+ new Error(
605
+ "This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize."
606
+ ),
607
+ item
608
+ );
638
609
  }
610
+ result.push(ESCAPE, ref - currentPos);
611
+ return ctx;
612
+ }
613
+
614
+ if (Buffer.isBuffer(item)) {
639
615
  const alreadyUsedBuffer = dedupeBuffer(item);
640
616
  if (alreadyUsedBuffer !== item) {
641
617
  const ref = referenceable.get(alreadyUsedBuffer);
642
618
  if (ref !== undefined) {
643
619
  referenceable.set(item, ref);
644
620
  result.push(ESCAPE, ref - currentPos);
645
- return;
621
+ return ctx;
646
622
  }
647
623
  item = alreadyUsedBuffer;
648
624
  }
649
- addReferenceable(item);
625
+ referenceable.set(item, currentPos++);
650
626
 
651
627
  result.push(/** @type {Buffer} */ (item));
652
- return;
653
- }
654
-
655
- // check if we can emit a reference
656
- const ref = referenceable.get(item);
657
- if (ref !== undefined) {
658
- result.push(ESCAPE, ref - currentPos);
659
- return;
660
- }
661
-
662
- if (cycleStack.has(item)) {
663
- throw new Error(
664
- "This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize."
665
- );
628
+ return ctx;
666
629
  }
667
630
 
668
631
  // Keyed by the registration itself: one per class, so it stands in for
669
632
  // `${request}/${name}` without building that string per object.
670
- const config = ObjectMiddleware.getSerializerFor(
671
- /** @type {Constructor} */
672
- (item)
633
+ const proto = Object.getPrototypeOf(item);
634
+ const registered = serializers.get(
635
+ proto === null ? null : proto.constructor
673
636
  );
637
+ /** @type {SerializerConfigWithSerializer} */
638
+ let config;
639
+ if (registered !== undefined && registered.serializer !== undefined) {
640
+ config = /** @type {SerializerConfigWithSerializer} */ (registered);
641
+ } else {
642
+ try {
643
+ // re-resolved so the miss reports which class is unregistered
644
+ config = ObjectMiddleware.getSerializerFor(
645
+ /** @type {Constructor} */
646
+ (item)
647
+ );
648
+ } catch (err) {
649
+ if (err === NOT_SERIALIZABLE) throw err;
650
+ throw attachSerializationPath(/** @type {Error} */ (err), item);
651
+ }
652
+ }
674
653
  const { request, name, serializer } = config;
675
- const lastIndex = objectTypeLookup.get(config);
654
+ const lastIndex =
655
+ config === lastConfig
656
+ ? lastConfigIndex
657
+ : objectTypeLookup.get(config);
676
658
 
677
659
  if (lastIndex === undefined) {
678
- objectTypeLookup.set(config, currentPosTypeLookup++);
660
+ lastConfigIndex = currentPosTypeLookup++;
661
+ objectTypeLookup.set(config, lastConfigIndex);
679
662
 
680
663
  result.push(ESCAPE, request, name);
681
664
  } else {
665
+ lastConfigIndex = lastIndex;
682
666
  result.push(ESCAPE, currentPosTypeLookup - lastIndex);
683
667
  }
668
+ lastConfig = config;
684
669
 
685
- cycleStack.add(item);
670
+ referenceable.set(item, IN_PROGRESS);
671
+ cycleStack.push(item);
686
672
 
687
673
  try {
688
674
  serializer.serialize(item, ctx);
689
- } finally {
690
- cycleStack.delete(item);
675
+ } catch (err) {
676
+ cycleStack.pop();
677
+ if (err !== NOT_SERIALIZABLE) {
678
+ attachSerializationPath(/** @type {Error} */ (err), item);
679
+ }
680
+ throw err;
691
681
  }
682
+ cycleStack.pop();
692
683
 
693
684
  result.push(ESCAPE, ESCAPE_END_OBJECT);
694
685
 
695
- addReferenceable(item);
696
- return;
686
+ referenceable.set(item, currentPos++);
687
+ return ctx;
697
688
  }
698
689
  case "function": {
699
690
  if (!SerializerMiddleware.isLazy(item)) {
700
- throw new Error(`Unexpected function ${item}`);
691
+ throw attachSerializationPath(
692
+ new Error(`Unexpected function ${item}`),
693
+ item
694
+ );
701
695
  }
702
696
 
703
697
  /** @type {SerializedType | undefined} */
@@ -708,10 +702,10 @@ class ObjectMiddleware extends SerializerMiddleware {
708
702
  if (typeof serializedData === "function") {
709
703
  result.push(serializedData);
710
704
  } else {
711
- throw new Error("Not implemented");
705
+ throw attachSerializationPath(new Error("Not implemented"), item);
712
706
  }
713
707
  } else if (SerializerMiddleware.isLazy(item, this)) {
714
- throw new Error("Not implemented");
708
+ throw attachSerializationPath(new Error("Not implemented"), item);
715
709
  } else {
716
710
  const data =
717
711
  /** @type {() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>} */
@@ -723,12 +717,50 @@ class ObjectMiddleware extends SerializerMiddleware {
723
717
  SerializerMiddleware.setLazySerializedValue(item, data);
724
718
  result.push(data);
725
719
  }
726
- return;
720
+ return ctx;
727
721
  }
728
722
  default:
729
723
  result.push(item);
730
724
  }
725
+ return ctx;
731
726
  };
727
+ /** @type {ObjectSerializerContext<EXPECTED_ANY>} */
728
+ let ctx = {
729
+ write: process,
730
+ setCircularReference(ref) {
731
+ addReferenceable(ref);
732
+ },
733
+ snapshot() {
734
+ return {
735
+ length: result.length,
736
+ cycleStackSize: cycleStack.length,
737
+ referenceableSize: referenceable.size,
738
+ currentPos,
739
+ objectTypeLookupSize: objectTypeLookup.size,
740
+ currentPosTypeLookup
741
+ };
742
+ },
743
+ rollback(snapshot) {
744
+ result.length = snapshot.length;
745
+ cycleStack.length = snapshot.cycleStackSize;
746
+ // a `setCircularReference` since the snapshot replaced a marker on an
747
+ // item already keyed here, which `setMapSize` cannot undo
748
+ for (let i = 0; i < cycleStack.length; i++) {
749
+ const item = /** @type {ReferenceableItem} */ (cycleStack[i]);
750
+ const ref = referenceable.get(item);
751
+ if (ref !== undefined && ref >= snapshot.currentPos) {
752
+ referenceable.set(item, IN_PROGRESS);
753
+ }
754
+ }
755
+ setMapSize(referenceable, snapshot.referenceableSize);
756
+ currentPos = snapshot.currentPos;
757
+ setMapSize(objectTypeLookup, snapshot.objectTypeLookupSize);
758
+ lastConfig = undefined;
759
+ currentPosTypeLookup = snapshot.currentPosTypeLookup;
760
+ },
761
+ ...context
762
+ };
763
+ this.extendContext(ctx);
732
764
 
733
765
  try {
734
766
  for (const item of data) {