webpack 5.111.0 → 5.111.1

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 (144) hide show
  1. package/lib/APIPlugin.js +3 -4
  2. package/lib/CompatibilityPlugin.js +3 -4
  3. package/lib/Compilation.js +16 -35
  4. package/lib/Compiler.js +4 -5
  5. package/lib/ConstPlugin.js +16 -132
  6. package/lib/DependencyTemplate.js +2 -1
  7. package/lib/DotenvPlugin.js +24 -28
  8. package/lib/ErrorHelpers.js +113 -0
  9. package/lib/ExportsInfo.js +20 -16
  10. package/lib/ExternalModule.js +6 -8
  11. package/lib/FlagDependencyExportsPlugin.js +8 -13
  12. package/lib/FlagDependencyUsagePlugin.js +9 -13
  13. package/lib/Generator.js +24 -2
  14. package/lib/HotModuleReplacementPlugin.js +2 -0
  15. package/lib/IgnorePlugin.js +1 -1
  16. package/lib/LoaderOptionsPlugin.js +1 -1
  17. package/lib/Module.js +3 -3
  18. package/lib/ModuleGraph.js +6 -9
  19. package/lib/MultiCompiler.js +6 -16
  20. package/lib/NormalModule.js +96 -44
  21. package/lib/RuntimeTemplate.js +33 -43
  22. package/lib/SourceMapDevToolPlugin.js +53 -103
  23. package/lib/TemplatedPathPlugin.js +16 -59
  24. package/lib/asset/AssetBytesGenerator.js +7 -1
  25. package/lib/asset/AssetGenerator.js +25 -16
  26. package/lib/asset/AssetSourceGenerator.js +7 -1
  27. package/lib/buildChunkGraph.js +11 -15
  28. package/lib/cache/MemoryCachePlugin.js +4 -4
  29. package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
  30. package/lib/cache/PackFileCacheStrategy.js +3 -18
  31. package/lib/cache/getLazyHashedEtag.js +3 -5
  32. package/lib/config/browserslistTargetHandler.js +2 -8
  33. package/lib/config/defaults.js +52 -78
  34. package/lib/config/getClaimedAssetTypes.js +10 -11
  35. package/lib/config/target.js +3 -4
  36. package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
  37. package/lib/{ContextModule.js → context/ContextModule.js} +37 -34
  38. package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
  39. package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
  40. package/lib/css/CssGenerator.js +19 -11
  41. package/lib/css/CssParser.js +18 -20
  42. package/lib/css/cssMinify.js +32 -29
  43. package/lib/css/data.js +797 -288
  44. package/lib/css/syntax.js +2250 -934
  45. package/lib/debug/ProfilingPlugin.js +3 -4
  46. package/lib/dependencies/CommonJsExportRequireDependency.js +10 -11
  47. package/lib/dependencies/CommonJsImportsParserPlugin.js +4 -5
  48. package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
  49. package/lib/dependencies/ContextDependency.js +1 -1
  50. package/lib/dependencies/ContextDependencyHelpers.js +3 -9
  51. package/lib/dependencies/ContextElementDependency.js +1 -1
  52. package/lib/dependencies/CssIcssExportDependency.js +6 -8
  53. package/lib/dependencies/CssIcssImportDependency.js +3 -6
  54. package/lib/dependencies/CssUrlDependency.js +3 -5
  55. package/lib/dependencies/HarmonyCompatibilityDependency.js +11 -20
  56. package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
  57. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -4
  58. package/lib/dependencies/HarmonyExportExpressionDependency.js +3 -4
  59. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +3 -4
  60. package/lib/dependencies/HarmonyExportInitFragment.js +26 -19
  61. package/lib/dependencies/HarmonyExportSpecifierDependency.js +7 -28
  62. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +103 -16
  63. package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -4
  64. package/lib/dependencies/HarmonyImportSpecifierDependency.js +16 -2
  65. package/lib/dependencies/HtmlEntryDependency.js +74 -102
  66. package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
  67. package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
  68. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  69. package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
  70. package/lib/dependencies/ImportMetaPlugin.js +8 -10
  71. package/lib/dependencies/ImportParserPlugin.js +1 -1
  72. package/lib/dependencies/LoaderPlugin.js +26 -1
  73. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  74. package/lib/dependencies/URLContextDependency.js +1 -1
  75. package/lib/dependencies/URLDependency.js +6 -5
  76. package/lib/dependencies/WorkerAndWorkletPlugin.js +15 -21
  77. package/lib/dependencies/WorkerDependency.js +6 -5
  78. package/lib/dependencies/WorkletDependency.js +6 -9
  79. package/lib/errors/HookWebpackError.js +3 -2
  80. package/lib/hmr/LazyCompilationPlugin.js +3 -5
  81. package/lib/html/HtmlGenerator.js +61 -82
  82. package/lib/html/HtmlModulesPlugin.js +88 -139
  83. package/lib/html/HtmlParser.js +97 -141
  84. package/lib/html/data.js +21 -0
  85. package/lib/html/htmlMinify.js +10 -11
  86. package/lib/html/syntax.js +883 -993
  87. package/lib/index.js +46 -3
  88. package/lib/javascript/ChunkFormatHelpers.js +4 -3
  89. package/lib/javascript/JavascriptGenerator.js +8 -1
  90. package/lib/javascript/JavascriptModulesPlugin.js +21 -48
  91. package/lib/javascript/JavascriptParser.js +721 -178
  92. package/lib/javascript/parser.js +6 -0
  93. package/lib/javascript/syntax.js +420 -92
  94. package/lib/json/JsonGenerator.js +7 -1
  95. package/lib/library/ModuleLibraryPlugin.js +64 -136
  96. package/lib/loaders/LoaderRunner.js +137 -9
  97. package/lib/node/NodeWatchFileSystem.js +3 -9
  98. package/lib/optimize/AggressiveMergingPlugin.js +3 -5
  99. package/lib/optimize/ConcatenatedModule.js +81 -100
  100. package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
  101. package/lib/optimize/InnerGraphPlugin.js +7 -13
  102. package/lib/optimize/LimitChunkCountPlugin.js +5 -8
  103. package/lib/optimize/MangleExportsPlugin.js +3 -4
  104. package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
  105. package/lib/optimize/SideEffectsFlagPlugin.js +7 -19
  106. package/lib/optimize/SplitChunksPlugin.js +2 -4
  107. package/lib/performance/BroadContextsPlugin.js +1 -1
  108. package/lib/performance/CacheEffectivenessPlugin.js +3 -4
  109. package/lib/performance/SizeLimitsPlugin.js +2 -4
  110. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +6 -8
  111. package/lib/prefetch/ResourceHintPlugin.js +17 -21
  112. package/lib/prefetch/StartupAssetHintRuntimeModule.js +7 -10
  113. package/lib/runtime/AsyncModuleRuntimeModule.js +3 -5
  114. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -4
  115. package/lib/runtime/GlobalRuntimeModule.js +2 -4
  116. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +55 -85
  117. package/lib/schemes/DataUriPlugin.js +3 -6
  118. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  119. package/lib/serialization/BinaryMiddleware.js +9 -9
  120. package/lib/serialization/FileMiddleware.js +16 -16
  121. package/lib/serialization/ObjectMiddleware.js +30 -33
  122. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -4
  123. package/lib/typescript/TypeScriptPlugin.js +2 -3
  124. package/lib/url/URLParserPlugin.js +6 -8
  125. package/lib/util/LocConverter.js +4 -7
  126. package/lib/util/SourceProcessor.js +15 -22
  127. package/lib/util/chainedImports.js +3 -4
  128. package/lib/util/concatenate.js +4 -4
  129. package/lib/util/createHooksRegistry.js +1 -2
  130. package/lib/util/dataURL.js +2 -3
  131. package/lib/util/deterministicGrouping.js +8 -13
  132. package/lib/util/findGraphRoots.js +6 -13
  133. package/lib/util/globUtils.js +1 -1
  134. package/lib/util/hash/wasm-hash.js +3 -4
  135. package/lib/util/internalSerializables.js +1 -1
  136. package/lib/util/semver.js +5 -3
  137. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
  138. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
  139. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +3 -4
  140. package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
  141. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
  142. package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
  143. package/package.json +30 -23
  144. package/types.d.ts +299 -280
@@ -150,10 +150,9 @@ class Profiler {
150
150
  // Avoid coverage problems due indirect changes
151
151
  /* istanbul ignore next */
152
152
  if (profile.startTime < this._startTime || profile.endTime > endTime) {
153
- // In some cases timestamps mismatch and we need to adjust them
154
- // Both process.hrtime and the inspector timestamps claim to be relative
155
- // to a unknown point in time. But they do not guarantee that this is the
156
- // same point in time.
153
+ // `process.hrtime` and the inspector timestamps are each relative to an
154
+ // unknown point in time, with no guarantee it is the same point, so the
155
+ // two are rescaled onto one another here.
157
156
  const duration = profile.endTime - profile.startTime;
158
157
  const ownDuration = endTime - this._startTime;
159
158
  const untracked = Math.max(0, ownDuration - duration);
@@ -273,23 +273,22 @@ class CommonJsExportRequireDependency extends ModuleDependency {
273
273
  const from = moduleGraph.getConnection(this);
274
274
  if (!from) return;
275
275
  if (esmUnwrap) {
276
- // Full re-export `module.exports = require("./esm")` of a module
277
- // with a `"module.exports"` named export: the wrapping module's
278
- // `module.exports` becomes the unwrapped value, whose own
279
- // properties webpack cannot enumerate statically.
276
+ // In `module.exports = require("./esm")` of a module carrying a
277
+ // `"module.exports"` export, this module's own exports become the
278
+ // unwrapped value, whose properties cannot be enumerated statically.
280
279
  return {
281
280
  exports: true,
282
281
  canMangle: false,
283
282
  dependencies: [from.module]
284
283
  };
285
284
  }
286
- // The imported namespace ESM hasn't been flagged by
287
- // FlagDependencyExportsPlugin yet (no exports determined), so its
288
- // `"module.exports"` unwrap eligibility is still unknown. Star-reexporting
289
- // now would add `__esModule` (and names) the monotonic merge can't retract
290
- // once the module turns out to unwrap, making the result order-dependent
291
- // across runtimes; defer — the `from.module` dependency re-queues us once
292
- // its exports (owned names, or dynamic `other`) become known.
285
+ // WHY: the imported namespace ESM has not been flagged by
286
+ // FlagDependencyExportsPlugin yet, so its `"module.exports"` unwrap
287
+ // eligibility is still unknown. Star-reexporting now would add `__esModule`,
288
+ // and names, that the monotonic merge cannot retract once the module turns
289
+ // out to unwrap, making the result order-dependent across runtimes. Deferring
290
+ // is safe: the `from.module` dependency re-queues this once its exports —
291
+ // owned names, or a dynamic `other` — become known.
293
292
  if (
294
293
  importedModule &&
295
294
  importedModule.getExportsType(moduleGraph, false) === "namespace"
@@ -738,11 +738,10 @@ class CommonJsImportsParserPlugin {
738
738
  // #endregion
739
739
 
740
740
  // #region Require bound to a const variable
741
- // Track `const NAME = require(LITERAL)` so that static member accesses on
742
- // `NAME` (e.g. `NAME.foo`, `NAME.foo()`) are forwarded to the same
743
- // `CommonJsRequireDependency` as referenced exports — enabling tree
744
- // shaking of CommonJS modules that are imported into a named binding
745
- // rather than destructured.
741
+
742
+ // Track `const NAME = require(LITERAL)`, so a static member access on `NAME`
743
+ // forwards to the same dependency as a referenced export and a CommonJS
744
+ // module bound to a name still tree-shakes.
746
745
  parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator, statement) => {
747
746
  if (statement.kind !== "const") return;
748
747
  if (declarator.id.type !== "Identifier") return;
@@ -207,10 +207,8 @@ CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependency
207
207
  }
208
208
 
209
209
  if (base === dep.base && equals(used, dep.names)) {
210
- // Nothing has to be changed
211
- // We don't use a replacement for compat reasons
212
- // for plugins that update `module._source` which they
213
- // shouldn't do!
210
+ // Nothing has to change, and no replacement is emitted: plugins that
211
+ // update `module._source`, which they should not, depend on that.
214
212
  return;
215
213
  }
216
214
 
@@ -15,7 +15,7 @@ const getCriticalDependencyWarning = memoize(() =>
15
15
  );
16
16
 
17
17
  /** @import { Range } from "../javascript/JavascriptParser" */
18
- /** @import { ContextOptions } from "../ContextModule" */
18
+ /** @import { ContextOptions } from "../context/ContextModule" */
19
19
  /** @import { TRANSITIVE } from "../Dependency" */
20
20
  /** @import ModuleGraph from "../ModuleGraph" */
21
21
  /** @import WebpackError from "../errors/WebpackError" */
@@ -107,15 +107,9 @@ module.exports.create = (
107
107
  )
108
108
  .join("");
109
109
 
110
- // Example: `./context/pre${e}inner${e}inner2${e}post?query#frag`
111
- // context: "./context"
112
- // prefix: "./pre"
113
- // innerQuasis: [BEE("inner"), BEE("inner2")]
114
- // (BEE = BasicEvaluatedExpression)
115
- // postfix: "post"
116
- // query: "?query"
117
- // fragment: "#frag"
118
- // regExp: /^\.\/pre.*inner.*inner2.*post$/
110
+ // The template's quasis become the literal anchors of the regexp and its
111
+ // expressions the gaps between them, so `./context/pre${e}inner${e}post`
112
+ // matches `/^\.\/pre.*inner.*post$/` under the context `./context`.
119
113
  const regExp = new RegExp(
120
114
  `^${quoteMeta(prefix)}${innerRegExp}${quoteMeta(postfix)}$`
121
115
  );
@@ -9,7 +9,7 @@ const Dependency = require("../Dependency");
9
9
  const makeSerializable = require("../util/makeSerializable");
10
10
  const ModuleDependency = require("./ModuleDependency");
11
11
 
12
- /** @import ContextModule from "../ContextModule" */
12
+ /** @import ContextModule from "../context/ContextModule" */
13
13
  /** @import { RawReferencedExports, ReferencedExports } from "../Dependency" */
14
14
  /** @import Module from "../Module" */
15
15
  /** @import ModuleGraph from "../ModuleGraph" */
@@ -370,10 +370,9 @@ class CssIcssExportDependency extends NullDependency {
370
370
  * @returns {ReferencedExports} referenced exports
371
371
  */
372
372
  getReferencedExports(moduleGraph, runtime) {
373
- // `composes: foo;` (SELF_REFERENCE) references the composed class
374
- // (`entry.value`), not the composing class. Every other entry mode
375
- // keeps the whole exports object referenced (legacy behaviour), so the
376
- // presence of any such entry subsumes the self-reference names.
373
+ // `composes: foo;` references the composed class, not the composing one.
374
+ // Every other entry mode references the whole exports object, so one such
375
+ // entry subsumes the self-reference names.
377
376
  let hasNonSelfReference = false;
378
377
  /** @type {ReferencedExports} */
379
378
  const referenced = [];
@@ -850,10 +849,9 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
850
849
  if (!entry.interpolate) return value;
851
850
  const { moduleGraph, module, chunkGraph, runtimeTemplate } =
852
851
  templateContext;
853
- // Key order is by rising cardinality: `moduleGraph.cached` is a trie that
854
- // allocates a node per level per new prefix, so the per-export `value` goes
855
- // last — otherwise every export name forks the trie and re-allocates the
856
- // three elements below it, which are constant for the whole compilation.
852
+ // Keys are ordered by rising cardinality, since `moduleGraph.cached` is a
853
+ // trie allocating a node per level per prefix: the per-export `value` last,
854
+ // or every name forks the trie above the parts constant for the build.
857
855
  return moduleGraph.cached(
858
856
  computeInterpolatedIdentifier,
859
857
  /** @type {CssModule} */ (module),
@@ -100,12 +100,9 @@ class CssIcssImportDependency extends CssImportDependency {
100
100
 
101
101
  if (!module) return null;
102
102
 
103
- // The target module stores exports under the names produced by its
104
- // `exportsConvention`, so a raw `isExportProvided(this.importName)`
105
- // would false-positive against `camel-case-only` / `dashes-only` (and
106
- // any custom function that drops the original spelling). Expand
107
- // `importName` through the *target* module's convention and accept
108
- // if any alias is provided.
103
+ // The target stores exports under its own `exportsConvention`, so asking for
104
+ // the raw name misses under `camel-case-only` or any convention dropping the
105
+ // original spelling. Expand through that convention and accept any alias.
109
106
  const generator =
110
107
  /** @type {CssGenerator | undefined} */
111
108
  (module.generator);
@@ -84,11 +84,9 @@ class CssUrlDependency extends ModuleDependency {
84
84
  * @returns {void}
85
85
  */
86
86
  updateHash(hash, context) {
87
- // The dependency template substitutes the referenced asset's hashed
88
- // filename into the rendered CSS at code-generation time. Folding the
89
- // asset module's content hash into the dependency hash ensures the
90
- // CSS module's hash invalidates — and the CSS chunk's contenthash
91
- // updates — whenever the referenced asset's content changes.
87
+ // The template substitutes the asset's hashed filename into the rendered CSS,
88
+ // so folding that asset's content hash in here is what makes the CSS module's
89
+ // hash, and the chunk's contenthash, follow the asset.
92
90
  const { chunkGraph } = context;
93
91
  const module = chunkGraph.moduleGraph.getModule(this);
94
92
  if (!module) return;
@@ -13,11 +13,8 @@ const makeSerializable = require("../util/makeSerializable");
13
13
  const memoize = require("../util/memoize");
14
14
  const NullDependency = require("./NullDependency");
15
15
 
16
- // Required here rather than at the top: the plugin reaches back into the dependencies.
17
- const getJavascriptModulesPlugin = memoize(() =>
18
- require("../javascript/JavascriptModulesPlugin")
19
- );
20
- // Same reason: the deferred-namespace runtime imports dependencies from here.
16
+ // Required here rather than at the top: the deferred-namespace runtime imports
17
+ // dependencies from here.
21
18
  const getDeferredCycleHelpers = memoize(() =>
22
19
  require("../runtime/MakeDeferredNamespaceObjectRuntime")
23
20
  );
@@ -99,7 +96,8 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
99
96
  initFragments,
100
97
  runtimeRequirements,
101
98
  runtime,
102
- concatenationScope
99
+ concatenationScope,
100
+ getData
103
101
  }
104
102
  ) {
105
103
  // a wrapped module has a real exports object that still needs `__esModule`
@@ -113,20 +111,13 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
113
111
  exportsArgument: module.exportsArgument,
114
112
  runtimeRequirements
115
113
  });
116
- // A library exporting the same bindings natively never reads the marker back
117
- // off the exports object, so it takes the call over and emits it where wrapped.
118
- const hooks = getJavascriptModulesPlugin().getCompilationHooks(
119
- runtimeTemplate.compilation
120
- );
121
- const takenOver =
122
- hooks.onDemandExportsGeneration.isUsed() &&
123
- hooks.onDemandExportsGeneration.call(
124
- module,
125
- runtime,
126
- content,
127
- false
128
- ) === true;
129
- if (!takenOver) {
114
+
115
+ const meta = moduleGraph.getMetaIfExisting(module);
116
+ if (!concatenationScope && meta && meta.onDemandExports && getData) {
117
+ const data = getData();
118
+ const before = data.get("exportsSource");
119
+ data.set("exportsSource", before ? `${before}${content}` : content);
120
+ } else {
130
121
  initFragments.push(
131
122
  new InitFragment(
132
123
  content,
@@ -109,10 +109,9 @@ module.exports = class HarmonyDetectionParserPlugin {
109
109
  }
110
110
  });
111
111
 
112
- // Using `import.meta` only parses as a module, so it marks the module ESM.
113
- // Non-bailing; staged before the bailing DefinePlugin and ImportMetaPlugin
114
- // replacement taps so it observes every access; unknown members go
115
- // through `unhandledExpressionMemberChain`.
112
+ // `import.meta` parses only as a module, so it marks this one ESM. Staged
113
+ // before the bailing DefinePlugin and ImportMetaPlugin taps, so it observes
114
+ // every access without ending the chain.
116
115
  const onImportMeta = () => {
117
116
  enableHarmony(false);
118
117
  };
@@ -112,10 +112,8 @@ module.exports = class HarmonyExportDependencyParserPlugin {
112
112
  return true;
113
113
  });
114
114
  // `export default <namespace binding>` is the same export as
115
- // `export { ns as default }`, so it is claimed here and rewritten into the
116
- // same re-export. Stage -10 runs before the inner-graph tap, which would
117
- // otherwise wrap the identifier in a pure-expression guard whose insertions
118
- // outlive the statement this removes.
115
+ // `export { ns as default }`, so it becomes the same re-export. Stage -10
116
+ // beats the inner-graph tap, whose guard would outlive the removed statement.
119
117
  parser.hooks.statement.tap(
120
118
  { name: PLUGIN_NAME, stage: -10 },
121
119
  (statement) => {
@@ -293,10 +293,9 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla
293
293
  } else if (used) {
294
294
  defaultIsUsed = true;
295
295
  runtimeRequirements.add(RuntimeGlobals.exports);
296
- // This is a little bit incorrect as TDZ is not correct, but we can't use const.
297
- // No local `__WEBPACK_DEFAULT_EXPORT__` binding is created in this path,
298
- // so the anonymous-default `.name` fix-up below must reference the actual
299
- // assignment target instead. See issue #20793.
296
+ // The TDZ is not reproduced here, `const` being unavailable. No local
297
+ // binding is created either, so the anonymous-default `.name` fix-up
298
+ // below names the assignment target instead. See issue #20793.
300
299
  name = `${exportsName}${propertyAccess(
301
300
  typeof used === "string" ? [used] : used
302
301
  )}`;
@@ -1547,10 +1547,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1547
1547
  }
1548
1548
 
1549
1549
  case "reexport-fake-namespace-object":
1550
- // `${name}_namespace_cache` needs an identifier to suffix, but an
1551
- // in-scope target is an expression. The concatenation already builds
1552
- // the same object, memoized: its interop namespace picks the mode from
1553
- // the exports type, which is what `fakeType` mirrors.
1550
+ // `${name}_namespace_cache` needs an identifier to suffix, and an in-scope
1551
+ // target is an expression. The concatenation already memoizes the same
1552
+ // object, its interop namespace taking the mode `fakeType` mirrors.
1554
1553
  if (inScope) {
1555
1554
  initFragments.push(
1556
1555
  this.getReexportFragment(
@@ -43,12 +43,6 @@ const ExportBindingType = Object.freeze({
43
43
  /** @typedef {Map<UsedName, { value: string, type: typeof ExportBindingType.Getter | typeof ExportBindingType.Value }>} ExportMap */
44
44
  /** @typedef {Set<string>} UnusedExports */
45
45
 
46
- /**
47
- * Lets a consumer take over the rendered `d()` call at its required position.
48
- * End-position value bindings cannot move before the module body.
49
- * @typedef {(source: string, placeAtEnd: boolean) => boolean} OnDemandGeneration
50
- */
51
-
52
46
  /** @type {ExportMap} */
53
47
  const EMPTY_MAP = new Map();
54
48
  /** @type {UnusedExports} */
@@ -64,13 +58,13 @@ class HarmonyExportInitFragment extends InitFragment {
64
58
  * @param {string} exportsArgument the exports identifier
65
59
  * @param {ExportMap} exportMap mapping from used name to exposed variable name
66
60
  * @param {UnusedExports} unusedExports list of unused export names
67
- * @param {OnDemandGeneration=} onDemand offered the call instead of emitting it
61
+ * @param {boolean} onDemand leave the call out of the source and hand it over in the code generation data (see `KnownMeta.onDemandExports`)
68
62
  */
69
63
  constructor(
70
64
  exportsArgument,
71
65
  exportMap = EMPTY_MAP,
72
66
  unusedExports = EMPTY_SET,
73
- onDemand = undefined
67
+ onDemand = false
74
68
  ) {
75
69
  super(undefined, InitFragment.STAGE_HARMONY_EXPORTS, 1, "harmony-exports");
76
70
  /** @type {string} */
@@ -79,7 +73,7 @@ class HarmonyExportInitFragment extends InitFragment {
79
73
  this.exportMap = exportMap;
80
74
  /** @type {UnusedExports} */
81
75
  this.unusedExports = unusedExports;
82
- /** @type {OnDemandGeneration | undefined} */
76
+ /** @type {boolean} */
83
77
  this.onDemand = onDemand;
84
78
 
85
79
  this._generated = false;
@@ -138,8 +132,8 @@ class HarmonyExportInitFragment extends InitFragment {
138
132
  /** @type {undefined | UnusedExports} */
139
133
  let unusedExports;
140
134
  let unusedExportsOwned = false;
141
- /** @type {OnDemandGeneration=} */
142
- let onDemand;
135
+ /** @type {boolean} */
136
+ let onDemand = false;
143
137
 
144
138
  for (const fragment of fragments) {
145
139
  if (fragment.exportMap.size !== 0) {
@@ -227,7 +221,7 @@ class HarmonyExportInitFragment extends InitFragment {
227
221
  getContent(context) {
228
222
  this._generate(context);
229
223
 
230
- const { runtimeRequirements } = context;
224
+ const { runtimeRequirements, getData } = context;
231
225
  const unusedPart =
232
226
  this.unusedExports.size > 1
233
227
  ? `/* unused harmony exports ${joinIterableWithComma(
@@ -248,7 +242,13 @@ class HarmonyExportInitFragment extends InitFragment {
248
242
  }(${this.exportsArgument}, {${this._defsGetter.join(
249
243
  ","
250
244
  )}\n/* harmony export */ });\n`;
251
- if (this.onDemand !== undefined && this.onDemand(definePart, false)) {
245
+ if (this.onDemand && getData !== undefined) {
246
+ const data = getData();
247
+ const before = data.get("exportsSource");
248
+ data.set(
249
+ "exportsSource",
250
+ before ? `${before}${definePart}` : definePart
251
+ );
252
252
  definePart = "";
253
253
  }
254
254
  }
@@ -261,7 +261,7 @@ class HarmonyExportInitFragment extends InitFragment {
261
261
  * @param {GenerateContext} context context
262
262
  * @returns {string | Source | undefined} the source code that will be included at the end of the module
263
263
  */
264
- getEndContent({ runtimeRequirements }) {
264
+ getEndContent({ runtimeRequirements, getData }) {
265
265
  let definePart = "";
266
266
 
267
267
  if (this._defsValue && this._defsValue.length) {
@@ -272,14 +272,21 @@ class HarmonyExportInitFragment extends InitFragment {
272
272
  // Only this fragment emits the array form, so the runtime helper drops the
273
273
  // branch reading it unless this asks for it.
274
274
  runtimeRequirements.add(RuntimeGlobals.definePropertyGettersFromArray);
275
- const definition = `/* harmony export */ ${
275
+ definePart = `/* harmony export */ ${
276
276
  RuntimeGlobals.definePropertyGetters
277
277
  }(${this.exportsArgument}, [${this._defsValue.join(",")}\n/* harmony export */ ]);\n`;
278
278
 
279
- definePart =
280
- this.onDemand !== undefined && this.onDemand(definition, true)
281
- ? definePart
282
- : `\n${definition}`;
279
+ if (this.onDemand && getData !== undefined) {
280
+ const data = getData();
281
+ const before = data.get("exportsBindingSource");
282
+ data.set(
283
+ "exportsBindingSource",
284
+ before ? `${before}${definePart}` : definePart
285
+ );
286
+ definePart = "";
287
+ } else {
288
+ definePart = `\n${definePart}`;
289
+ }
283
290
  }
284
291
 
285
292
  return definePart;
@@ -8,7 +8,6 @@
8
8
  const Dependency = require("../Dependency");
9
9
  const { InlinedUsedName } = require("../optimize/InlineExports");
10
10
  const makeSerializable = require("../util/makeSerializable");
11
- const memoize = require("../util/memoize");
12
11
  const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
13
12
 
14
13
  const { ExportBindingType } = HarmonyExportInitFragment;
@@ -30,11 +29,6 @@ const NullDependency = require("./NullDependency");
30
29
  * } from "../javascript/JavascriptModule"
31
30
  */
32
31
 
33
- // Required here rather than at the top: the plugin reaches back into the dependencies.
34
- const getJavascriptModulesPlugin = memoize(() =>
35
- require("../javascript/JavascriptModulesPlugin")
36
- );
37
-
38
32
  class HarmonyExportSpecifierDependency extends NullDependency {
39
33
  /**
40
34
  * Creates an instance of HarmonyExportSpecifierDependency.
@@ -149,14 +143,7 @@ HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependen
149
143
  apply(
150
144
  dependency,
151
145
  source,
152
- {
153
- module,
154
- moduleGraph,
155
- initFragments,
156
- runtime,
157
- runtimeTemplate,
158
- concatenationScope
159
- }
146
+ { module, moduleGraph, initFragments, runtime, concatenationScope }
160
147
  ) {
161
148
  const dep = /** @type {HarmonyExportSpecifierDependency} */ (dependency);
162
149
  // a wrapped module's bindings stay inside the wrapper, not in the shared scope
@@ -187,20 +174,12 @@ HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependen
187
174
  /** @type {import("../Module").BuildInfo} */ (module.buildInfo)
188
175
  .isCircular === false;
189
176
 
190
- // A library exporting the same bindings natively reads none of them back off the
191
- // exports object, so it takes the call over and emits it only where wrapped.
192
- const hooks = getJavascriptModulesPlugin().getCompilationHooks(
193
- runtimeTemplate.compilation
194
- );
195
- const onDemand = hooks.onDemandExportsGeneration.isUsed()
196
- ? (/** @type {string} */ definition, /** @type {boolean} */ placeAtEnd) =>
197
- hooks.onDemandExportsGeneration.call(
198
- module,
199
- runtime,
200
- definition,
201
- placeAtEnd
202
- ) === true
203
- : undefined;
177
+ const meta = moduleGraph.getMetaIfExisting(module);
178
+
179
+ const onDemand =
180
+ !concatenationScope &&
181
+ meta !== undefined &&
182
+ meta.onDemandExports === true;
204
183
 
205
184
  /** @type {ExportMap} */
206
185
  const map = new Map();