From 9bce51f651aad297ef9eb6df832bfdaf1de05d84 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期三, 22 四月 2026 14:27:54 +0800
Subject: [PATCH] 青岛推送
---
node_modules/webpack/lib/library/ModuleLibraryPlugin.js | 246 ++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 212 insertions(+), 34 deletions(-)
diff --git a/node_modules/webpack/lib/library/ModuleLibraryPlugin.js b/node_modules/webpack/lib/library/ModuleLibraryPlugin.js
index 065428f..db2d7fe 100644
--- a/node_modules/webpack/lib/library/ModuleLibraryPlugin.js
+++ b/node_modules/webpack/lib/library/ModuleLibraryPlugin.js
@@ -7,11 +7,13 @@
const { ConcatSource } = require("webpack-sources");
const { UsageState } = require("../ExportsInfo");
+const ExternalModule = require("../ExternalModule");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
+const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
const ConcatenatedModule = require("../optimize/ConcatenatedModule");
-const propertyAccess = require("../util/propertyAccess");
-const { getEntryRuntime } = require("../util/runtime");
+const { propertyAccess } = require("../util/property");
+const { getEntryRuntime, getRuntimeKey } = require("../util/runtime");
const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
/** @typedef {import("webpack-sources").Source} Source */
@@ -20,22 +22,29 @@
/** @typedef {import("../../declarations/WebpackOptions").LibraryExport} LibraryExport */
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
/** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/**
+ * Defines the shared type used by this module.
* @template T
* @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
*/
/**
+ * Defines the module library plugin options type used by this module.
* @typedef {object} ModuleLibraryPluginOptions
* @property {LibraryType} type
*/
/**
+ * Defines the module library plugin parsed type used by this module.
* @typedef {object} ModuleLibraryPluginParsed
* @property {string} name
* @property {LibraryExport=} export
@@ -44,11 +53,13 @@
const PLUGIN_NAME = "ModuleLibraryPlugin";
/**
+ * Represents the module library plugin runtime component.
* @typedef {ModuleLibraryPluginParsed} T
* @extends {AbstractLibraryPlugin<ModuleLibraryPluginParsed>}
*/
class ModuleLibraryPlugin extends AbstractLibraryPlugin {
/**
+ * Creates an instance of ModuleLibraryPlugin.
* @param {ModuleLibraryPluginOptions} options the plugin options
*/
constructor(options) {
@@ -59,7 +70,7 @@
}
/**
- * Apply the plugin
+ * Applies the plugin by registering its hooks on the compiler.
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
@@ -69,11 +80,36 @@
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
const { onDemandExportsGeneration } =
ConcatenatedModule.getCompilationHooks(compilation);
- onDemandExportsGeneration.tap(PLUGIN_NAME, (_module) => true);
+ onDemandExportsGeneration.tap(
+ PLUGIN_NAME,
+ (module, runtimes, source, finalName) => {
+ /** @type {BuildMeta} */
+ const buildMeta = module.buildMeta || (module.buildMeta = {});
+
+ /** @type {BuildMeta["exportsSourceByRuntime"]} */
+ const exportsSourceByRuntime =
+ buildMeta.exportsSourceByRuntime ||
+ (buildMeta.exportsSourceByRuntime = new Map());
+
+ /** @type {BuildMeta["exportsFinalNameByRuntime"]} */
+ const exportsFinalNameByRuntime =
+ buildMeta.exportsFinalNameByRuntime ||
+ (buildMeta.exportsFinalNameByRuntime = new Map());
+
+ for (const runtime of runtimes) {
+ const key = getRuntimeKey(runtime);
+ exportsSourceByRuntime.set(key, source);
+ exportsFinalNameByRuntime.set(key, finalName);
+ }
+
+ return true;
+ }
+ );
});
}
/**
+ * Finish entry module.
* @param {Module} module the exporting entry module
* @param {string} entryName the name of the entrypoint
* @param {LibraryContext<T>} libraryContext context
@@ -94,8 +130,13 @@
exportsInfo.canMangleUse = false;
} else {
const exportsInfo = moduleGraph.getExportsInfo(module);
- // If the entry module is commonjs, its exports cannot be mangled
- if (module.buildMeta && module.buildMeta.treatAsCommonJs) {
+
+ if (
+ // If the entry module is commonjs, its exports cannot be mangled
+ (module.buildMeta && module.buildMeta.treatAsCommonJs) ||
+ // The entry module provides unknown exports
+ exportsInfo._otherExportsInfo.provided === null
+ ) {
exportsInfo.setUsedInUnknownWay(runtime);
} else {
exportsInfo.setAllKnownExportsUsed(runtime);
@@ -105,8 +146,9 @@
}
/**
+ * Returns preprocess as needed by overriding.
* @param {LibraryOptions} library normalized library option
- * @returns {T | false} preprocess as needed by overriding
+ * @returns {T} preprocess as needed by overriding
*/
parseOptions(library) {
const { name } = library;
@@ -123,28 +165,114 @@
}
/**
+ * Analyze unknown provided exports.
+ * @param {Source} source source
+ * @param {Module} module module
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @param {RuntimeSpec} runtime chunk runtime
+ * @param {[string, string][]} exports exports
+ * @param {Set<string>} alreadyRenderedExports already rendered exports
+ * @returns {ConcatSource} source with null provided exports
+ */
+ _analyzeUnknownProvidedExports(
+ source,
+ module,
+ moduleGraph,
+ runtime,
+ exports,
+ alreadyRenderedExports
+ ) {
+ const result = new ConcatSource(source);
+ /** @type {Set<string>} */
+ const moduleRequests = new Set();
+ /** @type {Map<string, string>} */
+ const unknownProvidedExports = new Map();
+
+ /**
+ * Resolves dynamic star reexport.
+ * @param {Module} module the module
+ * @param {boolean} isDynamicReexport if module is dynamic reexported
+ */
+ const resolveDynamicStarReexport = (module, isDynamicReexport) => {
+ for (const connection of moduleGraph.getOutgoingConnections(module)) {
+ const dep = connection.dependency;
+
+ // Only handle star-reexport statement
+ if (
+ dep instanceof HarmonyExportImportedSpecifierDependency &&
+ dep.name === null
+ ) {
+ const importedModule = connection.resolvedModule;
+ const importedModuleExportsInfo =
+ moduleGraph.getExportsInfo(importedModule);
+
+ // The imported module provides unknown exports
+ // So keep the reexports rendered in the bundle
+ if (
+ dep.getMode(moduleGraph, runtime).type === "dynamic-reexport" &&
+ importedModuleExportsInfo._otherExportsInfo.provided === null
+ ) {
+ // Handle export * from 'external'
+ if (importedModule instanceof ExternalModule) {
+ moduleRequests.add(importedModule.userRequest);
+ } else {
+ resolveDynamicStarReexport(importedModule, true);
+ }
+ }
+ // If importer modules existing `dynamic-reexport` dependency
+ // We should keep export statement rendered in the bundle
+ else if (isDynamicReexport) {
+ for (const exportInfo of importedModuleExportsInfo.orderedExports) {
+ if (!exportInfo.provided || exportInfo.name === "default") {
+ continue;
+ }
+ const originalName = exportInfo.name;
+ const usedName = exportInfo.getUsedName(originalName, runtime);
+
+ if (!alreadyRenderedExports.has(originalName) && usedName) {
+ unknownProvidedExports.set(originalName, usedName);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ resolveDynamicStarReexport(module, false);
+
+ for (const request of moduleRequests) {
+ result.add(`export * from "${request}";\n`);
+ }
+
+ for (const [origin, used] of unknownProvidedExports) {
+ exports.push([
+ origin,
+ `${RuntimeGlobals.exports}${propertyAccess([used])}`
+ ]);
+ }
+
+ return result;
+ }
+
+ /**
+ * Renders source with library export.
* @param {Source} source source
* @param {Module} module module
* @param {StartupRenderContext} renderContext render context
* @param {LibraryContext<T>} libraryContext context
* @returns {Source} source with library export
*/
- renderStartup(
- source,
- module,
- {
+ renderStartup(source, module, renderContext, { options, compilation }) {
+ const {
moduleGraph,
chunk,
codeGenerationResults,
inlined,
inlinedInIIFE,
runtimeTemplate
- },
- { options, compilation }
- ) {
- const result = new ConcatSource(source);
-
- const exportsInfo = options.export
+ } = renderContext;
+ let result = new ConcatSource(source);
+ const exportInfos = options.export
? [
moduleGraph.getExportInfo(
module,
@@ -152,19 +280,46 @@
)
]
: moduleGraph.getExportsInfo(module).orderedExports;
- const definitions =
- inlined && !inlinedInIIFE
- ? (module.buildMeta && module.buildMeta.exportsFinalName) || {}
- : {};
+
+ const exportsFinalNameByRuntime =
+ (module.buildMeta &&
+ module.buildMeta.exportsFinalNameByRuntime &&
+ module.buildMeta.exportsFinalNameByRuntime.get(
+ getRuntimeKey(chunk.runtime)
+ )) ||
+ {};
+
+ const isInlinedEntryWithoutIIFE = inlined && !inlinedInIIFE;
+ // Direct export bindings from on-demand concatenation
+ const definitions = isInlinedEntryWithoutIIFE
+ ? exportsFinalNameByRuntime
+ : {};
+
/** @type {string[]} */
const shortHandedExports = [];
/** @type {[string, string][]} */
const exports = [];
+ /** @type {Set<string>} */
+ const alreadyRenderedExports = new Set();
+
const isAsync = moduleGraph.isAsync(module);
const treatAsCommonJs =
module.buildMeta && module.buildMeta.treatAsCommonJs;
const skipRenderDefaultExport = Boolean(treatAsCommonJs);
+
+ const moduleExportsInfo = moduleGraph.getExportsInfo(module);
+
+ // Define ESM compatibility flag will rely on `__webpack_exports__`
+ const needHarmonyCompatibilityFlag =
+ moduleExportsInfo.otherExportsInfo.getUsed(chunk.runtime) !==
+ UsageState.Unused ||
+ moduleExportsInfo
+ .getReadOnlyExportInfo("__esModule")
+ .getUsed(chunk.runtime) !== UsageState.Unused;
+
+ let needExportsDeclaration =
+ !isInlinedEntryWithoutIIFE || isAsync || needHarmonyCompatibilityFlag;
if (isAsync) {
result.add(
@@ -172,17 +327,18 @@
);
}
- outer: for (const exportInfo of exportsInfo) {
+ // Try to find all known exports of the entry module
+ outer: for (const exportInfo of exportInfos) {
if (!exportInfo.provided) continue;
const originalName = exportInfo.name;
-
+ // Skip rendering the default export in some cases
if (skipRenderDefaultExport && originalName === "default") continue;
+ // Try to find all exports from the reexported modules
const target = exportInfo.findTarget(moduleGraph, (_m) => true);
if (target) {
const reexportsInfo = moduleGraph.getExportsInfo(target.module);
-
for (const reexportInfo of reexportsInfo.orderedExports) {
if (
reexportInfo.provided === false &&
@@ -199,14 +355,16 @@
(exportInfo.getUsedName(originalName, chunk.runtime));
/** @type {string | undefined} */
const definition = definitions[usedName];
-
/** @type {string | undefined} */
let finalName;
if (definition) {
finalName = definition;
} else {
+ // Fallback to `__webpack_exports__` property access
+ // when no direct export binding was found
finalName = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
+ needExportsDeclaration = true;
result.add(
`${runtimeTemplate.renderConst()} ${finalName} = ${RuntimeGlobals.exports}${propertyAccess(
[usedName]
@@ -215,6 +373,7 @@
}
if (
+ // If the name includes `property access` and `call expressions`
finalName &&
(finalName.includes(".") ||
finalName.includes("[") ||
@@ -245,9 +404,13 @@
: `${finalName} as ${originalName}`
);
}
+
+ alreadyRenderedExports.add(originalName);
}
+ // Add default export `__webpack_exports__` statement to keep better compatibility
if (treatAsCommonJs) {
+ needExportsDeclaration = true;
shortHandedExports.push(`${RuntimeGlobals.exports} as default`);
}
@@ -255,36 +418,51 @@
result.add(`export { ${shortHandedExports.join(", ")} };\n`);
}
+ result = this._analyzeUnknownProvidedExports(
+ result,
+ module,
+ moduleGraph,
+ chunk.runtime,
+ exports,
+ alreadyRenderedExports
+ );
+
for (const [exportName, final] of exports) {
result.add(
`export ${runtimeTemplate.renderConst()} ${exportName} = ${final};\n`
);
}
+ if (!needExportsDeclaration) {
+ renderContext.needExportsDeclaration = false;
+ }
+
return result;
}
/**
+ * Renders module content.
* @param {Source} source source
* @param {Module} module module
* @param {ModuleRenderContext} renderContext render context
- * @param {Omit<LibraryContext<T>, 'options'>} libraryContext context
+ * @param {Omit<LibraryContext<T>, "options">} libraryContext context
* @returns {Source} source with library export
*/
renderModuleContent(
source,
module,
- { factory, inlinedInIIFE },
+ { factory, inlinedInIIFE, chunk },
libraryContext
) {
- // Re-add `factoryExportsBinding` to the source
- // when the module is rendered as a factory or treated as an inlined (startup) module but wrapped in an IIFE
- if (
- (inlinedInIIFE || factory) &&
+ const exportsSource =
module.buildMeta &&
- module.buildMeta.factoryExportsBinding
- ) {
- return new ConcatSource(module.buildMeta.factoryExportsBinding, source);
+ module.buildMeta.exportsSourceByRuntime &&
+ module.buildMeta.exportsSourceByRuntime.get(getRuntimeKey(chunk.runtime));
+
+ // Re-add the module's exports source when rendered in factory
+ // or as an inlined startup module wrapped in an IIFE
+ if ((inlinedInIIFE || factory) && exportsSource) {
+ return new ConcatSource(exportsSource, source);
}
return source;
}
--
Gitblit v1.9.3