Buckets:
ktongue/docker_container / CAD_kevin /frontend /node_modules /webpack /lib /FlagDependencyExportsPlugin.js
| /* | |
| MIT License http://www.opensource.org/licenses/mit-license.php | |
| Author Tobias Koppers @sokra | |
| */ | |
| ; | |
| const asyncLib = require("neo-async"); | |
| const Queue = require("./util/Queue"); | |
| /** @typedef {import("./Compiler")} Compiler */ | |
| /** @typedef {import("./DependenciesBlock")} DependenciesBlock */ | |
| /** @typedef {import("./Dependency")} Dependency */ | |
| /** @typedef {import("./Dependency").ExportSpec} ExportSpec */ | |
| /** @typedef {import("./Dependency").ExportsSpec} ExportsSpec */ | |
| /** @typedef {import("./ExportsInfo")} ExportsInfo */ | |
| /** @typedef {import("./ExportsInfo").ExportInfoName} ExportInfoName */ | |
| /** @typedef {import("./ExportsInfo").RestoreProvidedData} RestoreProvidedData */ | |
| /** @typedef {import("./Module")} Module */ | |
| /** @typedef {import("./Module").BuildInfo} BuildInfo */ | |
| const PLUGIN_NAME = "FlagDependencyExportsPlugin"; | |
| const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`; | |
| class FlagDependencyExportsPlugin { | |
| /** | |
| * Apply the plugin | |
| * @param {Compiler} compiler the compiler instance | |
| * @returns {void} | |
| */ | |
| apply(compiler) { | |
| compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => { | |
| const moduleGraph = compilation.moduleGraph; | |
| const cache = compilation.getCache(PLUGIN_NAME); | |
| compilation.hooks.finishModules.tapAsync( | |
| PLUGIN_NAME, | |
| (modules, callback) => { | |
| const logger = compilation.getLogger(PLUGIN_LOGGER_NAME); | |
| let statRestoredFromMemCache = 0; | |
| let statRestoredFromCache = 0; | |
| let statNoExports = 0; | |
| let statFlaggedUncached = 0; | |
| let statNotCached = 0; | |
| let statQueueItemsProcessed = 0; | |
| const { moduleMemCaches } = compilation; | |
| /** @type {Queue<Module>} */ | |
| const queue = new Queue(); | |
| // Step 1: Try to restore cached provided export info from cache | |
| logger.time("restore cached provided exports"); | |
| asyncLib.each( | |
| /** @type {import("neo-async").IterableCollection<Module>} */ ( | |
| /** @type {unknown} */ (modules) | |
| ), | |
| (module, callback) => { | |
| const exportsInfo = moduleGraph.getExportsInfo(module); | |
| // If the module doesn't have an exportsType, it's a module | |
| // without declared exports. | |
| if ( | |
| (!module.buildMeta || !module.buildMeta.exportsType) && | |
| exportsInfo.otherExportsInfo.provided !== null | |
| ) { | |
| // It's a module without declared exports | |
| statNoExports++; | |
| exportsInfo.setHasProvideInfo(); | |
| exportsInfo.setUnknownExportsProvided(); | |
| return callback(); | |
| } | |
| // If the module has no hash, it's uncacheable | |
| if ( | |
| typeof (/** @type {BuildInfo} */ (module.buildInfo).hash) !== | |
| "string" | |
| ) { | |
| statFlaggedUncached++; | |
| // Enqueue uncacheable module for determining the exports | |
| queue.enqueue(module); | |
| exportsInfo.setHasProvideInfo(); | |
| return callback(); | |
| } | |
| const memCache = moduleMemCaches && moduleMemCaches.get(module); | |
| const memCacheValue = memCache && memCache.get(this); | |
| if (memCacheValue !== undefined) { | |
| statRestoredFromMemCache++; | |
| exportsInfo.restoreProvided(memCacheValue); | |
| return callback(); | |
| } | |
| cache.get( | |
| module.identifier(), | |
| /** @type {BuildInfo} */ | |
| (module.buildInfo).hash, | |
| (err, result) => { | |
| if (err) return callback(err); | |
| if (result !== undefined) { | |
| statRestoredFromCache++; | |
| exportsInfo.restoreProvided(result); | |
| } else { | |
| statNotCached++; | |
| // Without cached info enqueue module for determining the exports | |
| queue.enqueue(module); | |
| exportsInfo.setHasProvideInfo(); | |
| } | |
| callback(); | |
| } | |
| ); | |
| }, | |
| (err) => { | |
| logger.timeEnd("restore cached provided exports"); | |
| if (err) return callback(err); | |
| /** @type {Set<Module>} */ | |
| const modulesToStore = new Set(); | |
| /** @type {Map<Module, Set<Module>>} */ | |
| const dependencies = new Map(); | |
| /** @type {Module} */ | |
| let module; | |
| /** @type {ExportsInfo} */ | |
| let exportsInfo; | |
| /** @type {Map<Dependency, ExportsSpec>} */ | |
| const exportsSpecsFromDependencies = new Map(); | |
| let cacheable = true; | |
| let changed = false; | |
| /** | |
| * @param {DependenciesBlock} depBlock the dependencies block | |
| * @returns {void} | |
| */ | |
| const processDependenciesBlock = (depBlock) => { | |
| for (const dep of depBlock.dependencies) { | |
| processDependency(dep); | |
| } | |
| for (const block of depBlock.blocks) { | |
| processDependenciesBlock(block); | |
| } | |
| }; | |
| /** | |
| * @param {Dependency} dep the dependency | |
| * @returns {void} | |
| */ | |
| const processDependency = (dep) => { | |
| const exportDesc = dep.getExports(moduleGraph); | |
| if (!exportDesc) return; | |
| exportsSpecsFromDependencies.set(dep, exportDesc); | |
| }; | |
| /** | |
| * @param {Dependency} dep dependency | |
| * @param {ExportsSpec} exportDesc info | |
| * @returns {void} | |
| */ | |
| const processExportsSpec = (dep, exportDesc) => { | |
| const exports = exportDesc.exports; | |
| const globalCanMangle = exportDesc.canMangle; | |
| const globalFrom = exportDesc.from; | |
| const globalPriority = exportDesc.priority; | |
| const globalTerminalBinding = | |
| exportDesc.terminalBinding || false; | |
| const exportDeps = exportDesc.dependencies; | |
| if (exportDesc.hideExports) { | |
| for (const name of exportDesc.hideExports) { | |
| const exportInfo = exportsInfo.getExportInfo(name); | |
| exportInfo.unsetTarget(dep); | |
| } | |
| } | |
| if (exports === true) { | |
| // unknown exports | |
| if ( | |
| exportsInfo.setUnknownExportsProvided( | |
| globalCanMangle, | |
| exportDesc.excludeExports, | |
| globalFrom && dep, | |
| globalFrom, | |
| globalPriority | |
| ) | |
| ) { | |
| changed = true; | |
| } | |
| } else if (Array.isArray(exports)) { | |
| /** | |
| * merge in new exports | |
| * @param {ExportsInfo} exportsInfo own exports info | |
| * @param {(ExportSpec | string)[]} exports list of exports | |
| */ | |
| const mergeExports = (exportsInfo, exports) => { | |
| for (const exportNameOrSpec of exports) { | |
| /** @type {ExportInfoName} */ | |
| let name; | |
| let canMangle = globalCanMangle; | |
| let terminalBinding = globalTerminalBinding; | |
| /** @type {ExportSpec["exports"]} */ | |
| let exports; | |
| let from = globalFrom; | |
| /** @type {ExportSpec["export"]} */ | |
| let fromExport; | |
| let priority = globalPriority; | |
| let hidden = false; | |
| if (typeof exportNameOrSpec === "string") { | |
| name = exportNameOrSpec; | |
| } else { | |
| name = exportNameOrSpec.name; | |
| if (exportNameOrSpec.canMangle !== undefined) { | |
| canMangle = exportNameOrSpec.canMangle; | |
| } | |
| if (exportNameOrSpec.export !== undefined) { | |
| fromExport = exportNameOrSpec.export; | |
| } | |
| if (exportNameOrSpec.exports !== undefined) { | |
| exports = exportNameOrSpec.exports; | |
| } | |
| if (exportNameOrSpec.from !== undefined) { | |
| from = exportNameOrSpec.from; | |
| } | |
| if (exportNameOrSpec.priority !== undefined) { | |
| priority = exportNameOrSpec.priority; | |
| } | |
| if (exportNameOrSpec.terminalBinding !== undefined) { | |
| terminalBinding = exportNameOrSpec.terminalBinding; | |
| } | |
| if (exportNameOrSpec.hidden !== undefined) { | |
| hidden = exportNameOrSpec.hidden; | |
| } | |
| } | |
| const exportInfo = exportsInfo.getExportInfo(name); | |
| if ( | |
| exportInfo.provided === false || | |
| exportInfo.provided === null | |
| ) { | |
| exportInfo.provided = true; | |
| changed = true; | |
| } | |
| if ( | |
| exportInfo.canMangleProvide !== false && | |
| canMangle === false | |
| ) { | |
| exportInfo.canMangleProvide = false; | |
| changed = true; | |
| } | |
| if (terminalBinding && !exportInfo.terminalBinding) { | |
| exportInfo.terminalBinding = true; | |
| changed = true; | |
| } | |
| if (exports) { | |
| const nestedExportsInfo = | |
| exportInfo.createNestedExportsInfo(); | |
| mergeExports( | |
| /** @type {ExportsInfo} */ (nestedExportsInfo), | |
| exports | |
| ); | |
| } | |
| if ( | |
| from && | |
| (hidden | |
| ? exportInfo.unsetTarget(dep) | |
| : exportInfo.setTarget( | |
| dep, | |
| from, | |
| fromExport === undefined ? [name] : fromExport, | |
| priority | |
| )) | |
| ) { | |
| changed = true; | |
| } | |
| // Recalculate target exportsInfo | |
| const target = exportInfo.getTarget(moduleGraph); | |
| /** @type {undefined | ExportsInfo} */ | |
| let targetExportsInfo; | |
| if (target) { | |
| const targetModuleExportsInfo = | |
| moduleGraph.getExportsInfo(target.module); | |
| targetExportsInfo = | |
| targetModuleExportsInfo.getNestedExportsInfo( | |
| target.export | |
| ); | |
| // add dependency for this module | |
| const set = dependencies.get(target.module); | |
| if (set === undefined) { | |
| dependencies.set(target.module, new Set([module])); | |
| } else { | |
| set.add(module); | |
| } | |
| } | |
| if (exportInfo.exportsInfoOwned) { | |
| if ( | |
| /** @type {ExportsInfo} */ | |
| (exportInfo.exportsInfo).setRedirectNamedTo( | |
| targetExportsInfo | |
| ) | |
| ) { | |
| changed = true; | |
| } | |
| } else if (exportInfo.exportsInfo !== targetExportsInfo) { | |
| exportInfo.exportsInfo = targetExportsInfo; | |
| changed = true; | |
| } | |
| } | |
| }; | |
| mergeExports(exportsInfo, exports); | |
| } | |
| // store dependencies | |
| if (exportDeps) { | |
| cacheable = false; | |
| for (const exportDependency of exportDeps) { | |
| // add dependency for this module | |
| const set = dependencies.get(exportDependency); | |
| if (set === undefined) { | |
| dependencies.set(exportDependency, new Set([module])); | |
| } else { | |
| set.add(module); | |
| } | |
| } | |
| } | |
| }; | |
| const notifyDependencies = () => { | |
| const deps = dependencies.get(module); | |
| if (deps !== undefined) { | |
| for (const dep of deps) { | |
| queue.enqueue(dep); | |
| } | |
| } | |
| }; | |
| logger.time("figure out provided exports"); | |
| while (queue.length > 0) { | |
| module = /** @type {Module} */ (queue.dequeue()); | |
| statQueueItemsProcessed++; | |
| exportsInfo = moduleGraph.getExportsInfo(module); | |
| cacheable = true; | |
| changed = false; | |
| exportsSpecsFromDependencies.clear(); | |
| moduleGraph.freeze(); | |
| processDependenciesBlock(module); | |
| moduleGraph.unfreeze(); | |
| for (const [dep, exportsSpec] of exportsSpecsFromDependencies) { | |
| processExportsSpec(dep, exportsSpec); | |
| } | |
| if (cacheable) { | |
| modulesToStore.add(module); | |
| } | |
| if (changed) { | |
| notifyDependencies(); | |
| } | |
| } | |
| logger.timeEnd("figure out provided exports"); | |
| logger.log( | |
| `${Math.round( | |
| (100 * (statFlaggedUncached + statNotCached)) / | |
| (statRestoredFromMemCache + | |
| statRestoredFromCache + | |
| statNotCached + | |
| statFlaggedUncached + | |
| statNoExports) | |
| )}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${statRestoredFromMemCache} from mem cache, ${ | |
| statQueueItemsProcessed - statNotCached - statFlaggedUncached | |
| } additional calculations due to dependencies)` | |
| ); | |
| logger.time("store provided exports into cache"); | |
| asyncLib.each( | |
| modulesToStore, | |
| (module, callback) => { | |
| if ( | |
| typeof ( | |
| /** @type {BuildInfo} */ | |
| (module.buildInfo).hash | |
| ) !== "string" | |
| ) { | |
| // not cacheable | |
| return callback(); | |
| } | |
| const cachedData = moduleGraph | |
| .getExportsInfo(module) | |
| .getRestoreProvidedData(); | |
| const memCache = | |
| moduleMemCaches && moduleMemCaches.get(module); | |
| if (memCache) { | |
| memCache.set(this, cachedData); | |
| } | |
| cache.store( | |
| module.identifier(), | |
| /** @type {BuildInfo} */ | |
| (module.buildInfo).hash, | |
| cachedData, | |
| callback | |
| ); | |
| }, | |
| (err) => { | |
| logger.timeEnd("store provided exports into cache"); | |
| callback(err); | |
| } | |
| ); | |
| } | |
| ); | |
| } | |
| ); | |
| /** @type {WeakMap<Module, RestoreProvidedData>} */ | |
| const providedExportsCache = new WeakMap(); | |
| compilation.hooks.rebuildModule.tap(PLUGIN_NAME, (module) => { | |
| providedExportsCache.set( | |
| module, | |
| moduleGraph.getExportsInfo(module).getRestoreProvidedData() | |
| ); | |
| }); | |
| compilation.hooks.finishRebuildingModule.tap(PLUGIN_NAME, (module) => { | |
| moduleGraph.getExportsInfo(module).restoreProvided( | |
| /** @type {RestoreProvidedData} */ | |
| (providedExportsCache.get(module)) | |
| ); | |
| }); | |
| }); | |
| } | |
| } | |
| module.exports = FlagDependencyExportsPlugin; | |
Xet Storage Details
- Size:
- 13.9 kB
- Xet hash:
- 609ee783865267d70b110f0262333fa29695e988a832e49e5d4bcf4a89e62fd8
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.