| 1 | /*
|
|---|
| 2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
|---|
| 3 | Author Tobias Koppers @sokra
|
|---|
| 4 | */
|
|---|
| 5 |
|
|---|
| 6 | "use strict";
|
|---|
| 7 |
|
|---|
| 8 | const { ConcatSource } = require("webpack-sources");
|
|---|
| 9 | const { UsageState } = require("../ExportsInfo");
|
|---|
| 10 | const ExternalModule = require("../ExternalModule");
|
|---|
| 11 | const RuntimeGlobals = require("../RuntimeGlobals");
|
|---|
| 12 | const Template = require("../Template");
|
|---|
| 13 | const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
|
|---|
| 14 | const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
|
|---|
| 15 | const ConcatenatedModule = require("../optimize/ConcatenatedModule");
|
|---|
| 16 | const { propertyAccess } = require("../util/property");
|
|---|
| 17 | const { getEntryRuntime, getRuntimeKey } = require("../util/runtime");
|
|---|
| 18 | const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
|
|---|
| 19 |
|
|---|
| 20 | /** @typedef {import("webpack-sources").Source} Source */
|
|---|
| 21 | /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
|
|---|
| 22 | /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
|
|---|
| 23 | /** @typedef {import("../../declarations/WebpackOptions").LibraryExport} LibraryExport */
|
|---|
| 24 | /** @typedef {import("../Chunk")} Chunk */
|
|---|
| 25 | /** @typedef {import("../Compiler")} Compiler */
|
|---|
| 26 | /** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|---|
| 27 | /** @typedef {import("../Module")} Module */
|
|---|
| 28 | /** @typedef {import("../Module").BuildMeta} BuildMeta */
|
|---|
| 29 | /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
|
|---|
| 30 | /** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
|
|---|
| 31 | /** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
|
|---|
| 32 | /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
|---|
| 33 | /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
|
|---|
| 34 |
|
|---|
| 35 | /**
|
|---|
| 36 | * Defines the shared type used by this module.
|
|---|
| 37 | * @template T
|
|---|
| 38 | * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
|
|---|
| 39 | */
|
|---|
| 40 |
|
|---|
| 41 | /**
|
|---|
| 42 | * Defines the module library plugin options type used by this module.
|
|---|
| 43 | * @typedef {object} ModuleLibraryPluginOptions
|
|---|
| 44 | * @property {LibraryType} type
|
|---|
| 45 | */
|
|---|
| 46 |
|
|---|
| 47 | /**
|
|---|
| 48 | * Defines the module library plugin parsed type used by this module.
|
|---|
| 49 | * @typedef {object} ModuleLibraryPluginParsed
|
|---|
| 50 | * @property {string} name
|
|---|
| 51 | * @property {LibraryExport=} export
|
|---|
| 52 | */
|
|---|
| 53 |
|
|---|
| 54 | const PLUGIN_NAME = "ModuleLibraryPlugin";
|
|---|
| 55 |
|
|---|
| 56 | /**
|
|---|
| 57 | * Represents the module library plugin runtime component.
|
|---|
| 58 | * @typedef {ModuleLibraryPluginParsed} T
|
|---|
| 59 | * @extends {AbstractLibraryPlugin<ModuleLibraryPluginParsed>}
|
|---|
| 60 | */
|
|---|
| 61 | class ModuleLibraryPlugin extends AbstractLibraryPlugin {
|
|---|
| 62 | /**
|
|---|
| 63 | * Creates an instance of ModuleLibraryPlugin.
|
|---|
| 64 | * @param {ModuleLibraryPluginOptions} options the plugin options
|
|---|
| 65 | */
|
|---|
| 66 | constructor(options) {
|
|---|
| 67 | super({
|
|---|
| 68 | pluginName: "ModuleLibraryPlugin",
|
|---|
| 69 | type: options.type
|
|---|
| 70 | });
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|
| 73 | /**
|
|---|
| 74 | * Applies the plugin by registering its hooks on the compiler.
|
|---|
| 75 | * @param {Compiler} compiler the compiler instance
|
|---|
| 76 | * @returns {void}
|
|---|
| 77 | */
|
|---|
| 78 | apply(compiler) {
|
|---|
| 79 | super.apply(compiler);
|
|---|
| 80 |
|
|---|
| 81 | compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|---|
| 82 | const { onDemandExportsGeneration } =
|
|---|
| 83 | ConcatenatedModule.getCompilationHooks(compilation);
|
|---|
| 84 | const javascriptHooks =
|
|---|
| 85 | JavascriptModulesPlugin.getCompilationHooks(compilation);
|
|---|
| 86 | onDemandExportsGeneration.tap(
|
|---|
| 87 | PLUGIN_NAME,
|
|---|
| 88 | (module, runtimes, source, finalName) => {
|
|---|
| 89 | /** @type {BuildMeta} */
|
|---|
| 90 | const buildMeta = module.buildMeta || (module.buildMeta = {});
|
|---|
| 91 |
|
|---|
| 92 | /** @type {BuildMeta["exportsSourceByRuntime"]} */
|
|---|
| 93 | const exportsSourceByRuntime =
|
|---|
| 94 | buildMeta.exportsSourceByRuntime ||
|
|---|
| 95 | (buildMeta.exportsSourceByRuntime = new Map());
|
|---|
| 96 |
|
|---|
| 97 | /** @type {BuildMeta["exportsFinalNameByRuntime"]} */
|
|---|
| 98 | const exportsFinalNameByRuntime =
|
|---|
| 99 | buildMeta.exportsFinalNameByRuntime ||
|
|---|
| 100 | (buildMeta.exportsFinalNameByRuntime = new Map());
|
|---|
| 101 |
|
|---|
| 102 | for (const runtime of runtimes) {
|
|---|
| 103 | const key = getRuntimeKey(runtime);
|
|---|
| 104 | exportsSourceByRuntime.set(key, source);
|
|---|
| 105 | exportsFinalNameByRuntime.set(key, finalName);
|
|---|
| 106 | }
|
|---|
| 107 |
|
|---|
| 108 | return true;
|
|---|
| 109 | }
|
|---|
| 110 | );
|
|---|
| 111 |
|
|---|
| 112 | // `ModuleLibraryPlugin` stashes the on-demand exports source via
|
|---|
| 113 | // `onDemandExportsGeneration` and only re-emits it when the
|
|---|
| 114 | // module is wrapped in an IIFE/factory. When a single concatenated
|
|---|
| 115 | // entry is inlined directly, the stashed source — and the
|
|---|
| 116 | // `definePropertyGetters` / `requireScope` runtime helpers it
|
|---|
| 117 | // pulled in — never make it into the output. Drop those helpers
|
|---|
| 118 | // from the chunk's set in that simple shape so the bundle stays
|
|---|
| 119 | // clean.
|
|---|
| 120 | compilation.hooks.additionalChunkRuntimeRequirements.tap(
|
|---|
| 121 | PLUGIN_NAME,
|
|---|
| 122 | (chunk, set, { chunkGraph, codeGenerationResults }) => {
|
|---|
| 123 | if (!set.has(RuntimeGlobals.definePropertyGetters)) return;
|
|---|
| 124 |
|
|---|
| 125 | // Only handle the simple "single concatenated entry"
|
|---|
| 126 | // shape. Anything else (additional modules, multiple
|
|---|
| 127 | // entries, sibling runtime chunks, or chunk-level
|
|---|
| 128 | // requirements that disable inline startup) forces the
|
|---|
| 129 | // module through factory/IIFE rendering, which re-emits
|
|---|
| 130 | // the source.
|
|---|
| 131 | if (chunkGraph.getNumberOfChunkModules(chunk) !== 1) return;
|
|---|
| 132 | if (chunkGraph.getNumberOfEntryModules(chunk) !== 1) return;
|
|---|
| 133 | if (chunkGraph.hasChunkEntryDependentChunks(chunk)) return;
|
|---|
| 134 | if (
|
|---|
| 135 | set.has(RuntimeGlobals.moduleFactories) ||
|
|---|
| 136 | set.has(RuntimeGlobals.moduleCache) ||
|
|---|
| 137 | set.has(RuntimeGlobals.interceptModuleExecution) ||
|
|---|
| 138 | set.has(RuntimeGlobals.module) ||
|
|---|
| 139 | set.has(RuntimeGlobals.thisAsExports)
|
|---|
| 140 | ) {
|
|---|
| 141 | return;
|
|---|
| 142 | }
|
|---|
| 143 | // Anyone tapping `inlineInRuntimeBailout` may force factory
|
|---|
| 144 | // rendering at render time, so conservatively bail out.
|
|---|
| 145 | if (javascriptHooks.inlineInRuntimeBailout.isUsed()) return;
|
|---|
| 146 |
|
|---|
| 147 | const [module] = chunkGraph.getChunkEntryModulesIterable(chunk);
|
|---|
| 148 | const exportsSourceByRuntime =
|
|---|
| 149 | module.buildMeta && module.buildMeta.exportsSourceByRuntime;
|
|---|
| 150 | if (
|
|---|
| 151 | !exportsSourceByRuntime ||
|
|---|
| 152 | !exportsSourceByRuntime.has(getRuntimeKey(chunk.runtime))
|
|---|
| 153 | ) {
|
|---|
| 154 | return;
|
|---|
| 155 | }
|
|---|
| 156 | // If the generated source references any
|
|---|
| 157 | // `__webpack_require__.<helper>` (the on-demand `.d(...)`
|
|---|
| 158 | // is stashed, but `.r(__webpack_exports__)` from the ESM
|
|---|
| 159 | // compat flag, namespace objects, deferred externals, ...
|
|---|
| 160 | // stay in the result) the helpers and the require scope
|
|---|
| 161 | // they live in are still needed. The dot in the substring
|
|---|
| 162 | // avoids matching the bare `"__webpack_require__"` string
|
|---|
| 163 | // literals that some test fixtures include.
|
|---|
| 164 | const codeGenResult = codeGenerationResults.get(
|
|---|
| 165 | module,
|
|---|
| 166 | chunk.runtime
|
|---|
| 167 | );
|
|---|
| 168 | const jsSource =
|
|---|
| 169 | codeGenResult && codeGenResult.sources.get("javascript");
|
|---|
| 170 | if (
|
|---|
| 171 | jsSource &&
|
|---|
| 172 | String(jsSource.source()).includes(`${RuntimeGlobals.require}.`)
|
|---|
| 173 | ) {
|
|---|
| 174 | return;
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | set.delete(RuntimeGlobals.definePropertyGetters);
|
|---|
| 178 | set.delete(RuntimeGlobals.exports);
|
|---|
| 179 | set.delete(RuntimeGlobals.requireScope);
|
|---|
| 180 | }
|
|---|
| 181 | );
|
|---|
| 182 | });
|
|---|
| 183 | }
|
|---|
| 184 |
|
|---|
| 185 | /**
|
|---|
| 186 | * Finish entry module.
|
|---|
| 187 | * @param {Module} module the exporting entry module
|
|---|
| 188 | * @param {string} entryName the name of the entrypoint
|
|---|
| 189 | * @param {LibraryContext<T>} libraryContext context
|
|---|
| 190 | * @returns {void}
|
|---|
| 191 | */
|
|---|
| 192 | finishEntryModule(
|
|---|
| 193 | module,
|
|---|
| 194 | entryName,
|
|---|
| 195 | { options, compilation, compilation: { moduleGraph } }
|
|---|
| 196 | ) {
|
|---|
| 197 | const runtime = getEntryRuntime(compilation, entryName);
|
|---|
| 198 | if (options.export) {
|
|---|
| 199 | const exportsInfo = moduleGraph.getExportInfo(
|
|---|
| 200 | module,
|
|---|
| 201 | Array.isArray(options.export) ? options.export[0] : options.export
|
|---|
| 202 | );
|
|---|
| 203 | exportsInfo.setUsed(UsageState.Used, runtime);
|
|---|
| 204 | exportsInfo.canMangleUse = false;
|
|---|
| 205 | } else {
|
|---|
| 206 | const exportsInfo = moduleGraph.getExportsInfo(module);
|
|---|
| 207 |
|
|---|
| 208 | if (
|
|---|
| 209 | // If the entry module is commonjs, its exports cannot be mangled
|
|---|
| 210 | (module.buildMeta && module.buildMeta.treatAsCommonJs) ||
|
|---|
| 211 | // The entry module provides unknown exports
|
|---|
| 212 | exportsInfo._otherExportsInfo.provided === null
|
|---|
| 213 | ) {
|
|---|
| 214 | exportsInfo.setUsedInUnknownWay(runtime);
|
|---|
| 215 | } else {
|
|---|
| 216 | exportsInfo.setAllKnownExportsUsed(runtime);
|
|---|
| 217 | }
|
|---|
| 218 | }
|
|---|
| 219 | moduleGraph.addExtraReason(module, "used as library export");
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | /**
|
|---|
| 223 | * Returns preprocess as needed by overriding.
|
|---|
| 224 | * @param {LibraryOptions} library normalized library option
|
|---|
| 225 | * @returns {T} preprocess as needed by overriding
|
|---|
| 226 | */
|
|---|
| 227 | parseOptions(library) {
|
|---|
| 228 | const { name } = library;
|
|---|
| 229 | if (name) {
|
|---|
| 230 | throw new Error(
|
|---|
| 231 | `Library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
|
|---|
| 232 | );
|
|---|
| 233 | }
|
|---|
| 234 | const _name = /** @type {string} */ (name);
|
|---|
| 235 | return {
|
|---|
| 236 | name: _name,
|
|---|
| 237 | export: library.export
|
|---|
| 238 | };
|
|---|
| 239 | }
|
|---|
| 240 |
|
|---|
| 241 | /**
|
|---|
| 242 | * Analyze unknown provided exports.
|
|---|
| 243 | * @param {Source} source source
|
|---|
| 244 | * @param {Module} module module
|
|---|
| 245 | * @param {ModuleGraph} moduleGraph moduleGraph
|
|---|
| 246 | * @param {RuntimeSpec} runtime chunk runtime
|
|---|
| 247 | * @param {[string, string][]} exports exports
|
|---|
| 248 | * @param {Set<string>} alreadyRenderedExports already rendered exports
|
|---|
| 249 | * @returns {ConcatSource} source with null provided exports
|
|---|
| 250 | */
|
|---|
| 251 | _analyzeUnknownProvidedExports(
|
|---|
| 252 | source,
|
|---|
| 253 | module,
|
|---|
| 254 | moduleGraph,
|
|---|
| 255 | runtime,
|
|---|
| 256 | exports,
|
|---|
| 257 | alreadyRenderedExports
|
|---|
| 258 | ) {
|
|---|
| 259 | const result = new ConcatSource(source);
|
|---|
| 260 | /** @type {Set<string>} */
|
|---|
| 261 | const moduleRequests = new Set();
|
|---|
| 262 | /** @type {Map<string, string>} */
|
|---|
| 263 | const unknownProvidedExports = new Map();
|
|---|
| 264 |
|
|---|
| 265 | /**
|
|---|
| 266 | * Resolves dynamic star reexport.
|
|---|
| 267 | * @param {Module} module the module
|
|---|
| 268 | * @param {boolean} isDynamicReexport if module is dynamic reexported
|
|---|
| 269 | */
|
|---|
| 270 | const resolveDynamicStarReexport = (module, isDynamicReexport) => {
|
|---|
| 271 | for (const connection of moduleGraph.getOutgoingConnections(module)) {
|
|---|
| 272 | const dep = connection.dependency;
|
|---|
| 273 |
|
|---|
| 274 | // Only handle star-reexport statement
|
|---|
| 275 | if (
|
|---|
| 276 | dep instanceof HarmonyExportImportedSpecifierDependency &&
|
|---|
| 277 | dep.name === null
|
|---|
| 278 | ) {
|
|---|
| 279 | const importedModule = connection.resolvedModule;
|
|---|
| 280 | const importedModuleExportsInfo =
|
|---|
| 281 | moduleGraph.getExportsInfo(importedModule);
|
|---|
| 282 |
|
|---|
| 283 | // The imported module provides unknown exports
|
|---|
| 284 | // So keep the reexports rendered in the bundle
|
|---|
| 285 | if (
|
|---|
| 286 | dep.getMode(moduleGraph, runtime).type === "dynamic-reexport" &&
|
|---|
| 287 | importedModuleExportsInfo._otherExportsInfo.provided === null
|
|---|
| 288 | ) {
|
|---|
| 289 | // Handle export * from 'external'
|
|---|
| 290 | if (importedModule instanceof ExternalModule) {
|
|---|
| 291 | moduleRequests.add(importedModule.userRequest);
|
|---|
| 292 | } else {
|
|---|
| 293 | resolveDynamicStarReexport(importedModule, true);
|
|---|
| 294 | }
|
|---|
| 295 | }
|
|---|
| 296 | // If importer modules existing `dynamic-reexport` dependency
|
|---|
| 297 | // We should keep export statement rendered in the bundle
|
|---|
| 298 | else if (isDynamicReexport) {
|
|---|
| 299 | for (const exportInfo of importedModuleExportsInfo.orderedExports) {
|
|---|
| 300 | if (!exportInfo.provided || exportInfo.name === "default") {
|
|---|
| 301 | continue;
|
|---|
| 302 | }
|
|---|
| 303 | const originalName = exportInfo.name;
|
|---|
| 304 | const usedName = exportInfo.getUsedName(originalName, runtime);
|
|---|
| 305 |
|
|---|
| 306 | if (!alreadyRenderedExports.has(originalName) && usedName) {
|
|---|
| 307 | unknownProvidedExports.set(originalName, usedName);
|
|---|
| 308 | }
|
|---|
| 309 | }
|
|---|
| 310 | }
|
|---|
| 311 | }
|
|---|
| 312 | }
|
|---|
| 313 | };
|
|---|
| 314 |
|
|---|
| 315 | resolveDynamicStarReexport(module, false);
|
|---|
| 316 |
|
|---|
| 317 | for (const request of moduleRequests) {
|
|---|
| 318 | result.add(`export * from "${request}";\n`);
|
|---|
| 319 | }
|
|---|
| 320 |
|
|---|
| 321 | for (const [origin, used] of unknownProvidedExports) {
|
|---|
| 322 | exports.push([
|
|---|
| 323 | origin,
|
|---|
| 324 | `${RuntimeGlobals.exports}${propertyAccess([used])}`
|
|---|
| 325 | ]);
|
|---|
| 326 | }
|
|---|
| 327 |
|
|---|
| 328 | return result;
|
|---|
| 329 | }
|
|---|
| 330 |
|
|---|
| 331 | /**
|
|---|
| 332 | * Renders source with library export.
|
|---|
| 333 | * @param {Source} source source
|
|---|
| 334 | * @param {Module} module module
|
|---|
| 335 | * @param {StartupRenderContext} renderContext render context
|
|---|
| 336 | * @param {LibraryContext<T>} libraryContext context
|
|---|
| 337 | * @returns {Source} source with library export
|
|---|
| 338 | */
|
|---|
| 339 | renderStartup(source, module, renderContext, { options, compilation }) {
|
|---|
| 340 | const {
|
|---|
| 341 | moduleGraph,
|
|---|
| 342 | chunk,
|
|---|
| 343 | codeGenerationResults,
|
|---|
| 344 | inlined,
|
|---|
| 345 | inlinedInIIFE,
|
|---|
| 346 | runtimeTemplate
|
|---|
| 347 | } = renderContext;
|
|---|
| 348 | let result = new ConcatSource(source);
|
|---|
| 349 | const exportInfos = options.export
|
|---|
| 350 | ? [
|
|---|
| 351 | moduleGraph.getExportInfo(
|
|---|
| 352 | module,
|
|---|
| 353 | Array.isArray(options.export) ? options.export[0] : options.export
|
|---|
| 354 | )
|
|---|
| 355 | ]
|
|---|
| 356 | : moduleGraph.getExportsInfo(module).orderedExports;
|
|---|
| 357 |
|
|---|
| 358 | const exportsFinalNameByRuntime =
|
|---|
| 359 | (module.buildMeta &&
|
|---|
| 360 | module.buildMeta.exportsFinalNameByRuntime &&
|
|---|
| 361 | module.buildMeta.exportsFinalNameByRuntime.get(
|
|---|
| 362 | getRuntimeKey(chunk.runtime)
|
|---|
| 363 | )) ||
|
|---|
| 364 | {};
|
|---|
| 365 |
|
|---|
| 366 | const isInlinedEntryWithoutIIFE = inlined && !inlinedInIIFE;
|
|---|
| 367 | // Direct export bindings from on-demand concatenation
|
|---|
| 368 | const definitions = isInlinedEntryWithoutIIFE
|
|---|
| 369 | ? exportsFinalNameByRuntime
|
|---|
| 370 | : {};
|
|---|
| 371 |
|
|---|
| 372 | /** @type {string[]} */
|
|---|
| 373 | const shortHandedExports = [];
|
|---|
| 374 | /** @type {[string, string][]} */
|
|---|
| 375 | const exports = [];
|
|---|
| 376 | /** @type {Set<string>} */
|
|---|
| 377 | const alreadyRenderedExports = new Set();
|
|---|
| 378 |
|
|---|
| 379 | const isAsync = moduleGraph.isAsync(module);
|
|---|
| 380 |
|
|---|
| 381 | const treatAsCommonJs =
|
|---|
| 382 | module.buildMeta && module.buildMeta.treatAsCommonJs;
|
|---|
| 383 | const skipRenderDefaultExport = Boolean(treatAsCommonJs);
|
|---|
| 384 |
|
|---|
| 385 | const moduleExportsInfo = moduleGraph.getExportsInfo(module);
|
|---|
| 386 |
|
|---|
| 387 | // Define ESM compatibility flag will rely on `__webpack_exports__`
|
|---|
| 388 | const needHarmonyCompatibilityFlag =
|
|---|
| 389 | moduleExportsInfo.otherExportsInfo.getUsed(chunk.runtime) !==
|
|---|
| 390 | UsageState.Unused ||
|
|---|
| 391 | moduleExportsInfo
|
|---|
| 392 | .getReadOnlyExportInfo("__esModule")
|
|---|
| 393 | .getUsed(chunk.runtime) !== UsageState.Unused;
|
|---|
| 394 |
|
|---|
| 395 | let needExportsDeclaration =
|
|---|
| 396 | !isInlinedEntryWithoutIIFE || isAsync || needHarmonyCompatibilityFlag;
|
|---|
| 397 |
|
|---|
| 398 | if (isAsync) {
|
|---|
| 399 | result.add(
|
|---|
| 400 | `${RuntimeGlobals.exports} = await ${RuntimeGlobals.exports};\n`
|
|---|
| 401 | );
|
|---|
| 402 | }
|
|---|
| 403 |
|
|---|
| 404 | // Try to find all known exports of the entry module
|
|---|
| 405 | outer: for (const exportInfo of exportInfos) {
|
|---|
| 406 | if (!exportInfo.provided) continue;
|
|---|
| 407 |
|
|---|
| 408 | const originalName = exportInfo.name;
|
|---|
| 409 | // Skip rendering the default export in some cases
|
|---|
| 410 | if (skipRenderDefaultExport && originalName === "default") continue;
|
|---|
| 411 |
|
|---|
| 412 | // Try to find all exports from the reexported modules
|
|---|
| 413 | const target = exportInfo.findTarget(moduleGraph, (_m) => true);
|
|---|
| 414 | if (target) {
|
|---|
| 415 | const reexportsInfo = moduleGraph.getExportsInfo(target.module);
|
|---|
| 416 | for (const reexportInfo of reexportsInfo.orderedExports) {
|
|---|
| 417 | if (
|
|---|
| 418 | reexportInfo.provided === false &&
|
|---|
| 419 | reexportInfo.name !== "default" &&
|
|---|
| 420 | reexportInfo.name === /** @type {string[]} */ (target.export)[0]
|
|---|
| 421 | ) {
|
|---|
| 422 | continue outer;
|
|---|
| 423 | }
|
|---|
| 424 | }
|
|---|
| 425 | }
|
|---|
| 426 |
|
|---|
| 427 | const usedName =
|
|---|
| 428 | /** @type {string} */
|
|---|
| 429 | (exportInfo.getUsedName(originalName, chunk.runtime));
|
|---|
| 430 | /** @type {string | undefined} */
|
|---|
| 431 | const definition = definitions[usedName];
|
|---|
| 432 | /** @type {string | undefined} */
|
|---|
| 433 | let finalName;
|
|---|
| 434 |
|
|---|
| 435 | if (definition) {
|
|---|
| 436 | finalName = definition;
|
|---|
| 437 | } else {
|
|---|
| 438 | // Fallback to `__webpack_exports__` property access
|
|---|
| 439 | // when no direct export binding was found
|
|---|
| 440 | finalName = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
|
|---|
| 441 | needExportsDeclaration = true;
|
|---|
| 442 | result.add(
|
|---|
| 443 | `${runtimeTemplate.renderConst()} ${finalName} = ${RuntimeGlobals.exports}${propertyAccess(
|
|---|
| 444 | [usedName]
|
|---|
| 445 | )};\n`
|
|---|
| 446 | );
|
|---|
| 447 | }
|
|---|
| 448 |
|
|---|
| 449 | if (
|
|---|
| 450 | // If the name includes `property access` and `call expressions`
|
|---|
| 451 | finalName &&
|
|---|
| 452 | (finalName.includes(".") ||
|
|---|
| 453 | finalName.includes("[") ||
|
|---|
| 454 | finalName.includes("("))
|
|---|
| 455 | ) {
|
|---|
| 456 | if (exportInfo.isReexport()) {
|
|---|
| 457 | const { data } = codeGenerationResults.get(module, chunk.runtime);
|
|---|
| 458 | const topLevelDeclarations =
|
|---|
| 459 | (data && data.get("topLevelDeclarations")) ||
|
|---|
| 460 | (module.buildInfo && module.buildInfo.topLevelDeclarations);
|
|---|
| 461 |
|
|---|
| 462 | if (topLevelDeclarations && topLevelDeclarations.has(originalName)) {
|
|---|
| 463 | const name = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
|
|---|
| 464 | result.add(
|
|---|
| 465 | `${runtimeTemplate.renderConst()} ${name} = ${finalName};\n`
|
|---|
| 466 | );
|
|---|
| 467 | shortHandedExports.push(`${name} as ${originalName}`);
|
|---|
| 468 | } else {
|
|---|
| 469 | exports.push([originalName, finalName]);
|
|---|
| 470 | }
|
|---|
| 471 | } else {
|
|---|
| 472 | exports.push([originalName, finalName]);
|
|---|
| 473 | }
|
|---|
| 474 | } else {
|
|---|
| 475 | shortHandedExports.push(
|
|---|
| 476 | definition && finalName === originalName
|
|---|
| 477 | ? finalName
|
|---|
| 478 | : `${finalName} as ${originalName}`
|
|---|
| 479 | );
|
|---|
| 480 | }
|
|---|
| 481 |
|
|---|
| 482 | alreadyRenderedExports.add(originalName);
|
|---|
| 483 | }
|
|---|
| 484 |
|
|---|
| 485 | // Add default export `__webpack_exports__` statement to keep better compatibility
|
|---|
| 486 | if (treatAsCommonJs) {
|
|---|
| 487 | needExportsDeclaration = true;
|
|---|
| 488 | shortHandedExports.push(`${RuntimeGlobals.exports} as default`);
|
|---|
| 489 | }
|
|---|
| 490 |
|
|---|
| 491 | if (shortHandedExports.length > 0) {
|
|---|
| 492 | result.add(`export { ${shortHandedExports.join(", ")} };\n`);
|
|---|
| 493 | }
|
|---|
| 494 |
|
|---|
| 495 | result = this._analyzeUnknownProvidedExports(
|
|---|
| 496 | result,
|
|---|
| 497 | module,
|
|---|
| 498 | moduleGraph,
|
|---|
| 499 | chunk.runtime,
|
|---|
| 500 | exports,
|
|---|
| 501 | alreadyRenderedExports
|
|---|
| 502 | );
|
|---|
| 503 |
|
|---|
| 504 | for (const [exportName, final] of exports) {
|
|---|
| 505 | result.add(
|
|---|
| 506 | `export ${runtimeTemplate.renderConst()} ${exportName} = ${final};\n`
|
|---|
| 507 | );
|
|---|
| 508 | }
|
|---|
| 509 |
|
|---|
| 510 | if (!needExportsDeclaration) {
|
|---|
| 511 | renderContext.needExportsDeclaration = false;
|
|---|
| 512 | }
|
|---|
| 513 |
|
|---|
| 514 | return result;
|
|---|
| 515 | }
|
|---|
| 516 |
|
|---|
| 517 | /**
|
|---|
| 518 | * Renders module content.
|
|---|
| 519 | * @param {Source} source source
|
|---|
| 520 | * @param {Module} module module
|
|---|
| 521 | * @param {ModuleRenderContext} renderContext render context
|
|---|
| 522 | * @param {Omit<LibraryContext<T>, "options">} libraryContext context
|
|---|
| 523 | * @returns {Source} source with library export
|
|---|
| 524 | */
|
|---|
| 525 | renderModuleContent(
|
|---|
| 526 | source,
|
|---|
| 527 | module,
|
|---|
| 528 | { factory, inlinedInIIFE, chunk },
|
|---|
| 529 | libraryContext
|
|---|
| 530 | ) {
|
|---|
| 531 | const exportsSource =
|
|---|
| 532 | module.buildMeta &&
|
|---|
| 533 | module.buildMeta.exportsSourceByRuntime &&
|
|---|
| 534 | module.buildMeta.exportsSourceByRuntime.get(getRuntimeKey(chunk.runtime));
|
|---|
| 535 |
|
|---|
| 536 | // Re-add the module's exports source when rendered in factory
|
|---|
| 537 | // or as an inlined startup module wrapped in an IIFE
|
|---|
| 538 | if ((inlinedInIIFE || factory) && exportsSource) {
|
|---|
| 539 | return new ConcatSource(exportsSource, source);
|
|---|
| 540 | }
|
|---|
| 541 | return source;
|
|---|
| 542 | }
|
|---|
| 543 | }
|
|---|
| 544 |
|
|---|
| 545 | module.exports = ModuleLibraryPlugin;
|
|---|