| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- */
- "use strict";
- const RuntimeGlobals = require("../RuntimeGlobals");
- const Template = require("../Template");
- const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
- const HelperRuntimeModule = require("./HelperRuntimeModule");
- /** @import { ModuleId } from "../ChunkGraph" */
- /** @import Module, { RuntimeRequirements, ExportsType } from "../Module" */
- /** @import ModuleGraph from "../ModuleGraph" */
- /**
- * @typedef {object} DeferredCycleState
- * @property {Map<Module, Set<Module>>} sccOf strongly-connected component per module (shared object per component)
- * @property {Map<Module, Set<Module> | null>} peers memoized SCC peers (component minus the module) per deferred module
- */
- /** @type {WeakMap<ModuleGraph, DeferredCycleState>} */
- const deferredCycleCache = new WeakMap();
- /**
- * Materializes the active harmony-import targets of a module (deferred edges
- * included, matching the spec's `RequestedModules` recursion).
- * @param {ModuleGraph} moduleGraph the module graph
- * @param {Module} module the module
- * @returns {Module[]} imported modules
- */
- function harmonyImportTargets(moduleGraph, module) {
- const connections = moduleGraph.getOutgoingConnectionsByModule(module);
- if (!connections) return [];
- /** @type {Module[]} */
- const targets = [];
- for (const [dep, moduleConnections] of connections) {
- if (
- dep &&
- moduleConnections.some(
- (c) =>
- c.dependency instanceof HarmonyImportDependency &&
- c.isTargetActive(undefined)
- )
- ) {
- targets.push(dep);
- }
- }
- return targets;
- }
- /**
- * Assigns every module reachable from `seed` (through active harmony imports)
- * to its strongly-connected component via an iterative Tarjan pass, writing the
- * results into `sccOf`. Modules already assigned by an earlier pass are treated
- * as finished, so across all deferred imports every edge is visited once
- * (O(V + E) total) rather than re-walked per import.
- * @param {ModuleGraph} moduleGraph the module graph
- * @param {Module} seed the module to explore from
- * @param {Map<Module, Set<Module>>} sccOf module-to-component map to populate
- * @returns {void}
- */
- function assignStronglyConnectedComponents(moduleGraph, seed, sccOf) {
- if (sccOf.has(seed)) return;
- /** @type {Map<Module, number>} */
- const index = new Map();
- /** @type {Map<Module, number>} */
- const low = new Map();
- /** @type {Set<Module>} */
- const onStack = new Set();
- /** @type {Module[]} */
- const componentStack = [];
- /** @type {{ node: Module, targets: Module[], i: number }[]} */
- const work = [];
- let counter = 0;
- /**
- * @param {Module} node node to open
- */
- const open = (node) => {
- index.set(node, counter);
- low.set(node, counter);
- counter++;
- componentStack.push(node);
- onStack.add(node);
- work.push({ node, targets: harmonyImportTargets(moduleGraph, node), i: 0 });
- };
- open(seed);
- while (work.length > 0) {
- const frame = work[work.length - 1];
- if (frame.i < frame.targets.length) {
- const next = frame.targets[frame.i++];
- // Already in a finished component (from this or a prior pass): skip.
- if (sccOf.has(next)) continue;
- if (!index.has(next)) {
- open(next);
- } else if (onStack.has(next)) {
- const nodeLow = /** @type {number} */ (low.get(frame.node));
- const nextIndex = /** @type {number} */ (index.get(next));
- if (nextIndex < nodeLow) low.set(frame.node, nextIndex);
- }
- continue;
- }
- work.pop();
- const node = frame.node;
- const nodeLow = /** @type {number} */ (low.get(node));
- if (work.length > 0) {
- const parent = work[work.length - 1].node;
- if (nodeLow < /** @type {number} */ (low.get(parent))) {
- low.set(parent, nodeLow);
- }
- }
- if (nodeLow === index.get(node)) {
- /** @type {Set<Module>} */
- const component = new Set();
- let member;
- do {
- member = /** @type {Module} */ (componentStack.pop());
- onStack.delete(member);
- component.add(member);
- } while (member !== node);
- for (const m of component) sccOf.set(m, component);
- }
- }
- }
- /**
- * Per the TC39 import-defer spec's `ReadyForSyncExecution`, forcing evaluation
- * of a deferred module must throw when any module in its transitive static
- * import closure is currently evaluating. Only a module in `module`'s own
- * strongly-connected component can be evaluating at that point (anything else it
- * imports is either already evaluated or not started), so we emit just the SCC
- * peers instead of the whole (potentially huge) forward closure.
- * @param {ModuleGraph} moduleGraph the module graph
- * @param {Module} module the deferred module
- * @returns {Set<Module> | null} the SCC peers when cyclic, otherwise null
- */
- function getDeferredCycleModules(moduleGraph, module) {
- let state = deferredCycleCache.get(moduleGraph);
- if (state === undefined) {
- state = { sccOf: new Map(), peers: new Map() };
- deferredCycleCache.set(moduleGraph, state);
- }
- const cached = state.peers.get(module);
- if (cached !== undefined) return cached;
- assignStronglyConnectedComponents(moduleGraph, module, state.sccOf);
- const component = state.sccOf.get(module);
- // A trivial component (size 1, no self-cycle peers) means no cycle; a direct
- // self-loop is already covered by the `evaluating` check on `module` itself.
- let result = null;
- if (component !== undefined && component.size > 1) {
- result = new Set(component);
- result.delete(module);
- }
- state.peers.set(module, result);
- return result;
- }
- /**
- * Maps a defer-cycle closure to the runtime module ids whose `evaluating` flag
- * the deferred namespace must check. `resolveId` maps a closure module to the
- * runtime id that carries its evaluation state (its own id, or the id of the
- * concatenated module that absorbed it); unresolved (`null`) members are
- * dropped. Returns `null` when there is nothing to check.
- * @param {Set<Module> | null} closure closure modules, or null when not cyclic
- * @param {(module: Module) => ModuleId | null} resolveId maps a module to its runtime id
- * @returns {ModuleId[] | null} deduplicated runtime ids, or null
- */
- function getDeferredCycleModuleIds(closure, resolveId) {
- if (closure === null) return null;
- /** @type {Set<ModuleId>} */
- const ids = new Set();
- for (const module of closure) {
- const id = resolveId(module);
- if (id !== null) ids.add(id);
- }
- return ids.size > 0 ? [...ids] : null;
- }
- /**
- * @param {ExportsType} exportsType exports type
- * @returns {string} mode
- */
- function getMakeDeferredNamespaceModeFromExportsType(exportsType) {
- // number is from createFakeNamespaceObject mode ^ 1
- if (exportsType === "namespace") return `/* ${exportsType} */ 8`;
- if (exportsType === "default-only") return `/* ${exportsType} */ 0`;
- if (exportsType === "default-with-named") return `/* ${exportsType} */ 2`;
- if (exportsType === "dynamic") return `/* ${exportsType} */ 6`;
- throw new Error(`Unknown exports type: ${exportsType}`);
- }
- /**
- * @param {string} moduleId moduleId
- * @param {ExportsType} exportsType exportsType
- * @param {(ModuleId | null)[]} asyncDepsIds asyncDepsIds
- * @param {ModuleId[] | null} syncCycleDepsIds transitive static closure ids when the module is part of a defer cycle
- * @param {RuntimeRequirements} runtimeRequirements runtime requirements
- * @returns {string} call make optimized deferred namespace object
- */
- function getOptimizedDeferredModule(
- moduleId,
- exportsType,
- asyncDepsIds,
- syncCycleDepsIds,
- runtimeRequirements
- ) {
- runtimeRequirements.add(RuntimeGlobals.makeOptimizedDeferredNamespaceObject);
- const mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
- const asyncDeps = asyncDepsIds.filter((x) => x !== null);
- const hasSync = syncCycleDepsIds !== null && syncCycleDepsIds.length > 0;
- // `syncDeps` is passed positionally after `asyncDeps`, so a `0` placeholder
- // keeps the slot when the module has cycle deps but no async deps.
- const args = [moduleId, mode];
- if (asyncDeps.length > 0 || hasSync) {
- args.push(asyncDeps.length > 0 ? JSON.stringify(asyncDeps) : "0");
- }
- if (hasSync) args.push(JSON.stringify(syncCycleDepsIds));
- return `${RuntimeGlobals.makeOptimizedDeferredNamespaceObject}(${args.join(
- ", "
- )})`;
- }
- class MakeOptimizedDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
- /**
- * Returns true, if the runtime module should get it's own scope.
- * When false, `generate()` must emit complete statements ending with `;`
- * so a following runtime IIFE is not parsed as a call (ASI).
- * @returns {boolean} true, if the runtime module should get it's own scope
- */
- shouldIsolate() {
- return false;
- }
- /**
- * @param {boolean} hasAsyncRuntime if async module is used.
- */
- constructor(hasAsyncRuntime) {
- super("make optimized deferred namespace object");
- /** @type {boolean} */
- this.hasAsyncRuntime = hasAsyncRuntime;
- }
- /**
- * Generates runtime code for this runtime module.
- * @returns {string | null} runtime code
- */
- generate() {
- if (!this.compilation) return null;
- const { runtimeTemplate } = this.compilation;
- const cst = runtimeTemplate.renderConst();
- const lt = runtimeTemplate.renderLet();
- const fn = RuntimeGlobals.makeOptimizedDeferredNamespaceObject;
- const hasAsync = this.hasAsyncRuntime;
- return Template.asString([
- // Note: must be a function (not arrow), because this is used in body!
- // `asyncDeps` keeps a fixed positional slot even without async runtime
- // so the trailing `syncDeps` (defer-cycle closure) always lines up.
- `${fn} = function(moduleId, mode, asyncDeps, syncDeps) {`,
- Template.indent([
- `${cst} r = this;`,
- hasAsync ? `${cst} isAsync = asyncDeps && asyncDeps.length;` : "",
- `${cst} obj = {`,
- Template.indent([
- "get a() {",
- Template.indent([
- // Forcing evaluation of a module that is currently evaluating
- // (a cycle reached through a deferred import) must throw rather
- // than expose its partial exports. `syncDeps` (present only for
- // cyclic deferred modules) carries the transitive static closure,
- // so an evaluating dependency is caught before any evaluation.
- `${cst} cachedModule = __webpack_module_cache__[moduleId];`,
- 'if (cachedModule !== undefined && (cachedModule.evaluating || cachedModule.evaluatingAsync)) throw new TypeError("Cannot access a deferred module namespace while the module is being evaluated");',
- "if (syncDeps) for (var i = 0; i < syncDeps.length; i++) {",
- Template.indent([
- `${cst} depModule = __webpack_module_cache__[syncDeps[i]];`,
- 'if (depModule !== undefined && (depModule.evaluating || depModule.evaluatingAsync)) throw new TypeError("Cannot access a deferred module namespace while a dependency is being evaluated");'
- ]),
- "}",
- `${lt} exports = r(moduleId);`,
- hasAsync
- ? `if(isAsync) exports = exports[${RuntimeGlobals.asyncModuleExportSymbol}];`
- : "",
- // if exportsType is "namespace" we can generate the most optimized code,
- // on the second access, we can avoid trigger the getter.
- // we can also do this if exportsType is "dynamic" and there is a "__esModule" property on it.
- 'if(mode & 8 || (mode & 4 && exports.__esModule)) Object.defineProperty(this, "a", { value: exports });',
- "return exports;"
- ]),
- "}"
- ]),
- "};",
- hasAsync
- ? `if(isAsync) obj[${RuntimeGlobals.deferredModuleAsyncTransitiveDependenciesSymbol}] = asyncDeps;`
- : "",
- "return obj;"
- ]),
- "};"
- ]);
- }
- }
- class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
- /**
- * Returns true, if the runtime module should get it's own scope.
- * When false, `generate()` must emit complete statements ending with `;`
- * so a following runtime IIFE is not parsed as a call (ASI).
- * @returns {boolean} true, if the runtime module should get it's own scope
- */
- shouldIsolate() {
- return false;
- }
- /**
- * @param {boolean} hasAsyncRuntime if async module is used.
- */
- constructor(hasAsyncRuntime) {
- super("make deferred namespace object");
- /** @type {boolean} */
- this.hasAsyncRuntime = hasAsyncRuntime;
- }
- /**
- * Generates runtime code for this runtime module.
- * @returns {string | null} runtime code
- */
- generate() {
- if (!this.compilation) return null;
- const { runtimeTemplate } = this.compilation;
- const cst = runtimeTemplate.renderConst();
- const lt = runtimeTemplate.renderLet();
- const fn = RuntimeGlobals.makeDeferredNamespaceObject;
- const hasAsync = this.hasAsyncRuntime;
- const init = `${runtimeTemplate.optionalChaining("init", "()")};`;
- return `${fn} = ${runtimeTemplate.basicFunction("moduleId, mode", [
- // Per the TC39 import-defer spec, deferred namespaces are
- // distinct from their eager counterparts and the same module
- // referenced from multiple defer-import sites must yield the
- // same object. Cache the Proxy / fake namespace per-moduleId so
- // repeated calls (including across files) share identity.
- //
- // Bit 16 (`createFakeNamespaceObject`'s "return value when
- // it's Promise-like" flag added by
- // `RuntimeTemplate.moduleNamespacePromise` for dynamic
- // imports) is irrelevant for deferred namespaces — the value
- // passed into `createFakeNamespaceObject` here is always the
- // resolved module exports (after unwrapping the async-module
- // export symbol when present), never a Promise. Strip it
- // once so all downstream behavior, the cache key, and the
- // `createFakeNamespaceObject` call below see the same shape
- // mode. This keeps static defer (mode 8) and dynamic
- // `await import.defer` (mode 8 | 16) sharing the same
- // Deferred Module Namespace object, while still keying by
- // `(moduleId, mode)` so distinct exports-type shapes
- // (e.g. one importer treats a CJS module as
- // "default-with-named", another as "namespace") get
- // distinct cache entries.
- "mode &= ~16;",
- `${lt} byMode = __webpack_module_deferred_namespace_cache__[moduleId];`,
- "if (byMode && byMode[mode] !== undefined) return byMode[mode];",
- "if (!byMode) byMode = __webpack_module_deferred_namespace_cache__[moduleId] = {};",
- `${cst} cachedModule = __webpack_module_cache__[moduleId];`,
- "if (cachedModule && cachedModule.error === undefined && !(mode & 8)) {",
- Template.indent([
- `${lt} exports = cachedModule.exports;`,
- hasAsync
- ? `if (${RuntimeGlobals.asyncModuleExportSymbol} in exports) exports = exports[${RuntimeGlobals.asyncModuleExportSymbol}];`
- : "",
- `return byMode[mode] = ${RuntimeGlobals.createFakeNamespaceObject}(exports, mode);`
- ]),
- "}",
- "",
- `${lt} init = ${runtimeTemplate.basicFunction("", [
- // A deferred namespace that forces evaluation of a module that is
- // already evaluating (a cycle) must throw rather than expose its
- // partial exports.
- `${cst} evaluatingModule = __webpack_module_cache__[moduleId];`,
- 'if (evaluatingModule !== undefined && (evaluatingModule.evaluating || evaluatingModule.evaluatingAsync)) throw new TypeError("Cannot access a deferred module namespace while the module is being evaluated");',
- `ns = ${RuntimeGlobals.require}(moduleId);`,
- hasAsync
- ? `if (${RuntimeGlobals.asyncModuleExportSymbol} in ns) ns = ns[${RuntimeGlobals.asyncModuleExportSymbol}];`
- : "",
- "init = null;",
- "if (mode & 8 || mode & 4 && ns.__esModule && typeof ns === 'object') {",
- Template.indent([
- // Drop only the read-side traps after init: with the
- // resolved namespace's own keys mirrored onto
- // `ns_target` below, the default `Reflect` behavior
- // returns the right values via the live-binding
- // getters, so we no longer need to intercept `get` /
- // `has` / `ownKeys` / `getOwnPropertyDescriptor`.
- //
- // The mutation traps (`set`, `deleteProperty`,
- // `defineProperty`) are kept because per the TC39
- // import-defer spec, `[[Set]]` / `[[Delete]]` /
- // `[[DefineOwnProperty]]` on a Deferred Module
- // Namespace Exotic Object never succeed — and the
- // proxy target itself remains extensible
- // (architecturally we cannot freeze it up-front),
- // so without these traps `ns.notExported = "x"`
- // after evaluation would silently create a property
- // on the target instead of returning false.
- "delete handler.get;",
- "delete handler.has;",
- "delete handler.ownKeys;",
- "delete handler.getOwnPropertyDescriptor;"
- ]),
- "} else {",
- Template.indent([
- `ns = ${RuntimeGlobals.createFakeNamespaceObject}(ns, mode);`
- ]),
- "}",
- // Mirror own properties from the resolved namespace onto the proxy
- // target so that proxy invariants hold for callers that structurally
- // introspect via `Object.keys` / `Object.getOwnPropertyNames` /
- // `Object.getOwnPropertyDescriptor`: when our trap reports a
- // non-configurable descriptor for a key, the target must also have
- // that key with a matching descriptor.
- //
- // `__esModule` and `Symbol.toStringTag` are intentionally skipped:
- // the proxy synthesizes "Deferred Module" / true regardless of what
- // the underlying namespace exposes (per the TC39 import-defer
- // proposal, the [[StringTag]] of a Deferred Module Namespace
- // Exotic Object is "Deferred Module"), and the target was already
- // pre-populated with those values below.
- `${cst} keys = Reflect.ownKeys(ns);`,
- "for (var i = 0; i < keys.length; i++) {",
- Template.indent([
- `${cst} k = keys[i];`,
- 'if (k === "__esModule" || k === Symbol.toStringTag) continue;',
- `if (!${runtimeTemplate.objectHasOwn("ns_target", "k")}) {`,
- Template.indent([
- "try { Object.defineProperty(ns_target, k, Reflect.getOwnPropertyDescriptor(ns, k)); } catch (_) {}"
- ]),
- "}"
- ]),
- "}"
- ])};`,
- "",
- // The proxy target is a fresh placeholder, separate from
- // `__webpack_module_deferred_exports__[moduleId]` (which is reused
- // by `__webpack_require__` as `module.exports` for deferred-loaded
- // modules and would conflict with our pre-populated synthetic
- // `__esModule` / `Symbol.toStringTag` non-configurable properties).
- // Using a dedicated target keeps the proxy invariant-compliant
- // without interfering with the module's own exports object.
- `${cst} ns_target = { __proto__: null };`,
- // Pre-populate the synthetic deferred-namespace properties with
- // fully non-configurable, non-writable, non-enumerable descriptors
- // (matching the TC39 import-defer spec for Module Namespace
- // Exotic Objects). The trap returns the same descriptors below.
- 'Object.defineProperty(ns_target, "__esModule", { value: true });',
- 'Object.defineProperty(ns_target, Symbol.toStringTag, { value: "Deferred Module" });',
- `${lt} ns = ns_target;`,
- `${cst} handler = {`,
- Template.indent([
- "__proto__: null,",
- // Per the TC39 import-defer proposal, `IsSymbolLikeNamespaceKey`
- // returns true for any Symbol-keyed access (and for "then"); such
- // accesses go through `OrdinaryGetOwnProperty` and must not
- // trigger evaluation of the deferred module. The Symbol checks
- // below short-circuit to the pre-populated target without
- // running `init()`.
- `${runtimeTemplate.method("get", "_, name", [
- "switch (name) {",
- Template.indent([
- 'case "__esModule": return true;',
- 'case Symbol.toStringTag: return "Deferred Module";',
- 'case "then": return undefined;'
- ]),
- "}",
- 'if (typeof name === "symbol") return ns_target[name];',
- init,
- "return ns[name];"
- ])},`,
- `${runtimeTemplate.method("has", "_, name", [
- "switch (name) {",
- Template.indent(
- [
- 'case "__esModule":',
- "case Symbol.toStringTag:",
- hasAsync
- ? `case ${RuntimeGlobals.deferredModuleAsyncTransitiveDependenciesSymbol}:`
- : "",
- Template.indent("return true;"),
- 'case "then":',
- Template.indent("return false;")
- ].filter(Boolean)
- ),
- "}",
- 'if (typeof name === "symbol") return name in ns_target;',
- init,
- "return name in ns;"
- ])},`,
- `${runtimeTemplate.method("ownKeys", "", [
- init,
- `${cst} filtered = Reflect.ownKeys(ns).filter(${runtimeTemplate.expressionFunction(
- 'x !== "then" && x !== Symbol.toStringTag',
- "x"
- )});`,
- `${cst} keys = ${
- runtimeTemplate.supportsSpread()
- ? "[...filtered, Symbol.toStringTag]"
- : "filtered.concat([Symbol.toStringTag])"
- };`,
- "return keys;"
- ])},`,
- `${runtimeTemplate.method("getOwnPropertyDescriptor", "_, name", [
- "switch (name) {",
- Template.indent([
- // Match the descriptors actually defined on `ns_target`
- // (non-configurable, non-writable, non-enumerable) so the
- // proxy invariant holds for both the trap result and any
- // post-init forwarding via the deleted-handler path.
- 'case "__esModule": return { value: true, writable: false, enumerable: false, configurable: false };',
- 'case Symbol.toStringTag: return { value: "Deferred Module", writable: false, enumerable: false, configurable: false };',
- 'case "then": return undefined;'
- ]),
- "}",
- 'if (typeof name === "symbol") return Reflect.getOwnPropertyDescriptor(ns_target, name);',
- init,
- `${lt} desc = Reflect.getOwnPropertyDescriptor(ns, name);`,
- 'if (mode & 2 && name == "default" && !desc) {',
- Template.indent("desc = { value: ns, configurable: true };"),
- "}",
- "return desc;"
- ])},`,
- // `defineProperty` always rejects, but per the TC39 spec it
- // must still trigger evaluation for string keys (the spec
- // algorithm calls `[[GetOwnProperty]]` first, which forces
- // evaluation on a deferred namespace). Symbol keys go through
- // OrdinaryDefineOwnProperty and do not trigger eval.
- `${runtimeTemplate.method("defineProperty", "_, name", [
- 'if (typeof name === "symbol" || name === "then") return false;',
- init,
- "return false;"
- ])},`,
- // `deleteProperty` rejects, but per the TC39 spec it must
- // still trigger evaluation for string keys (the spec
- // algorithm calls `GetModuleExportsList` for non-symbol-like
- // keys, forcing evaluation on a deferred namespace).
- `${runtimeTemplate.method("deleteProperty", "_, name", [
- 'if (typeof name === "symbol" || name === "then") return false;',
- init,
- "return false;"
- ])},`,
- // `set` always returns false without triggering evaluation —
- // the spec [[Set]] algorithm for Module Namespaces is just
- // "return false" (no [[GetOwnProperty]], no eval).
- `set: ${runtimeTemplate.returningFunction("false")},`
- ]),
- "}",
- // we don't fully emulate ES Module semantics in this Proxy to align with normal webpack esm namespace object.
- "return byMode[mode] = new Proxy(ns_target, handler);"
- ])};`;
- }
- }
- module.exports.MakeDeferredNamespaceObjectRuntimeModule =
- MakeDeferredNamespaceObjectRuntimeModule;
- module.exports.MakeOptimizedDeferredNamespaceObjectRuntimeModule =
- MakeOptimizedDeferredNamespaceObjectRuntimeModule;
- module.exports.getDeferredCycleModuleIds = getDeferredCycleModuleIds;
- module.exports.getDeferredCycleModules = getDeferredCycleModules;
- module.exports.getMakeDeferredNamespaceModeFromExportsType =
- getMakeDeferredNamespaceModeFromExportsType;
- module.exports.getOptimizedDeferredModule = getOptimizedDeferredModule;
|