diff options
Diffstat (limited to 'node_modules/webpack/lib/optimize/ConcatenatedModule.js')
| -rw-r--r-- | node_modules/webpack/lib/optimize/ConcatenatedModule.js | 1905 |
1 files changed, 0 insertions, 1905 deletions
diff --git a/node_modules/webpack/lib/optimize/ConcatenatedModule.js b/node_modules/webpack/lib/optimize/ConcatenatedModule.js deleted file mode 100644 index f889b5e2..00000000 --- a/node_modules/webpack/lib/optimize/ConcatenatedModule.js +++ /dev/null @@ -1,1905 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const eslintScope = require("eslint-scope"); -const Referencer = require("eslint-scope/lib/referencer"); -const { - CachedSource, - ConcatSource, - ReplaceSource -} = require("webpack-sources"); -const ConcatenationScope = require("../ConcatenationScope"); -const { UsageState } = require("../ExportsInfo"); -const Module = require("../Module"); -const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants"); -const RuntimeGlobals = require("../RuntimeGlobals"); -const Template = require("../Template"); -const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); -const JavascriptParser = require("../javascript/JavascriptParser"); -const { equals } = require("../util/ArrayHelpers"); -const LazySet = require("../util/LazySet"); -const { concatComparators } = require("../util/comparators"); -const createHash = require("../util/createHash"); -const { makePathsRelative } = require("../util/identifier"); -const makeSerializable = require("../util/makeSerializable"); -const propertyAccess = require("../util/propertyAccess"); -const { propertyName } = require("../util/propertyName"); -const { - filterRuntime, - intersectRuntime, - mergeRuntimeCondition, - mergeRuntimeConditionNonFalse, - runtimeConditionToString, - subtractRuntimeCondition -} = require("../util/runtime"); - -/** @typedef {import("eslint-scope").Scope} Scope */ -/** @typedef {import("webpack-sources").Source} Source */ -/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ -/** @typedef {import("../ChunkGraph")} ChunkGraph */ -/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ -/** @typedef {import("../Compilation")} Compilation */ -/** @typedef {import("../Dependency")} Dependency */ -/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ -/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ -/** @typedef {import("../DependencyTemplates")} DependencyTemplates */ -/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ -/** @template T @typedef {import("../InitFragment")<T>} InitFragment */ -/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */ -/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ -/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ -/** @typedef {import("../ModuleGraph")} ModuleGraph */ -/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ -/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ -/** @typedef {import("../RequestShortener")} RequestShortener */ -/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ -/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ -/** @typedef {import("../WebpackError")} WebpackError */ -/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ -/** @typedef {import("../util/Hash")} Hash */ -/** @typedef {typeof import("../util/Hash")} HashConstructor */ -/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ -/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ - -// fix eslint-scope to support class properties correctly -// cspell:word Referencer -const ReferencerClass = Referencer; -if (!ReferencerClass.prototype.PropertyDefinition) { - ReferencerClass.prototype.PropertyDefinition = - ReferencerClass.prototype.Property; -} - -/** - * @typedef {Object} ReexportInfo - * @property {Module} module - * @property {string[]} export - */ - -/** @typedef {RawBinding | SymbolBinding} Binding */ - -/** - * @typedef {Object} RawBinding - * @property {ModuleInfo} info - * @property {string} rawName - * @property {string=} comment - * @property {string[]} ids - * @property {string[]} exportName - */ - -/** - * @typedef {Object} SymbolBinding - * @property {ConcatenatedModuleInfo} info - * @property {string} name - * @property {string=} comment - * @property {string[]} ids - * @property {string[]} exportName - */ - -/** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo } ModuleInfo */ -/** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo | ReferenceToModuleInfo } ModuleInfoOrReference */ - -/** - * @typedef {Object} ConcatenatedModuleInfo - * @property {"concatenated"} type - * @property {Module} module - * @property {number} index - * @property {Object} ast - * @property {Source} internalSource - * @property {ReplaceSource} source - * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments - * @property {Iterable<string>} runtimeRequirements - * @property {Scope} globalScope - * @property {Scope} moduleScope - * @property {Map<string, string>} internalNames - * @property {Map<string, string>} exportMap - * @property {Map<string, string>} rawExportMap - * @property {string=} namespaceExportSymbol - * @property {string} namespaceObjectName - * @property {boolean} interopNamespaceObjectUsed - * @property {string} interopNamespaceObjectName - * @property {boolean} interopNamespaceObject2Used - * @property {string} interopNamespaceObject2Name - * @property {boolean} interopDefaultAccessUsed - * @property {string} interopDefaultAccessName - */ - -/** - * @typedef {Object} ExternalModuleInfo - * @property {"external"} type - * @property {Module} module - * @property {RuntimeSpec | boolean} runtimeCondition - * @property {number} index - * @property {string} name - * @property {boolean} interopNamespaceObjectUsed - * @property {string} interopNamespaceObjectName - * @property {boolean} interopNamespaceObject2Used - * @property {string} interopNamespaceObject2Name - * @property {boolean} interopDefaultAccessUsed - * @property {string} interopDefaultAccessName - */ - -/** - * @typedef {Object} ReferenceToModuleInfo - * @property {"reference"} type - * @property {RuntimeSpec | boolean} runtimeCondition - * @property {ConcatenatedModuleInfo | ExternalModuleInfo} target - */ - -const RESERVED_NAMES = new Set( - [ - // internal names (should always be renamed) - ConcatenationScope.DEFAULT_EXPORT, - ConcatenationScope.NAMESPACE_OBJECT_EXPORT, - - // keywords - "abstract,arguments,async,await,boolean,break,byte,case,catch,char,class,const,continue", - "debugger,default,delete,do,double,else,enum,eval,export,extends,false,final,finally,float", - "for,function,goto,if,implements,import,in,instanceof,int,interface,let,long,native,new,null", - "package,private,protected,public,return,short,static,super,switch,synchronized,this,throw", - "throws,transient,true,try,typeof,var,void,volatile,while,with,yield", - - // commonjs/amd - "module,__dirname,__filename,exports,require,define", - - // js globals - "Array,Date,eval,function,hasOwnProperty,Infinity,isFinite,isNaN,isPrototypeOf,length,Math", - "NaN,name,Number,Object,prototype,String,toString,undefined,valueOf", - - // browser globals - "alert,all,anchor,anchors,area,assign,blur,button,checkbox,clearInterval,clearTimeout", - "clientInformation,close,closed,confirm,constructor,crypto,decodeURI,decodeURIComponent", - "defaultStatus,document,element,elements,embed,embeds,encodeURI,encodeURIComponent,escape", - "event,fileUpload,focus,form,forms,frame,innerHeight,innerWidth,layer,layers,link,location", - "mimeTypes,navigate,navigator,frames,frameRate,hidden,history,image,images,offscreenBuffering", - "open,opener,option,outerHeight,outerWidth,packages,pageXOffset,pageYOffset,parent,parseFloat", - "parseInt,password,pkcs11,plugin,prompt,propertyIsEnum,radio,reset,screenX,screenY,scroll", - "secure,select,self,setInterval,setTimeout,status,submit,taint,text,textarea,top,unescape", - "untaint,window", - - // window events - "onblur,onclick,onerror,onfocus,onkeydown,onkeypress,onkeyup,onmouseover,onload,onmouseup,onmousedown,onsubmit" - ] - .join(",") - .split(",") -); - -const createComparator = (property, comparator) => (a, b) => - comparator(a[property], b[property]); -const compareNumbers = (a, b) => { - if (isNaN(a)) { - if (!isNaN(b)) { - return 1; - } - } else { - if (isNaN(b)) { - return -1; - } - if (a !== b) { - return a < b ? -1 : 1; - } - } - return 0; -}; -const bySourceOrder = createComparator("sourceOrder", compareNumbers); -const byRangeStart = createComparator("rangeStart", compareNumbers); - -const joinIterableWithComma = iterable => { - // This is more performant than Array.from().join(", ") - // as it doesn't create an array - let str = ""; - let first = true; - for (const item of iterable) { - if (first) { - first = false; - } else { - str += ", "; - } - str += item; - } - return str; -}; - -/** - * @typedef {Object} ConcatenationEntry - * @property {"concatenated" | "external"} type - * @property {Module} module - * @property {RuntimeSpec | boolean} runtimeCondition - */ - -/** - * @param {ModuleGraph} moduleGraph the module graph - * @param {ModuleInfo} info module info - * @param {string[]} exportName exportName - * @param {Map<Module, ModuleInfo>} moduleToInfoMap moduleToInfoMap - * @param {RuntimeSpec} runtime for which runtime - * @param {RequestShortener} requestShortener the request shortener - * @param {RuntimeTemplate} runtimeTemplate the runtime template - * @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated - * @param {boolean} asCall asCall - * @param {boolean} strictHarmonyModule strictHarmonyModule - * @param {boolean | undefined} asiSafe asiSafe - * @param {Set<ExportInfo>} alreadyVisited alreadyVisited - * @returns {Binding} the final variable - */ -const getFinalBinding = ( - moduleGraph, - info, - exportName, - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - asCall, - strictHarmonyModule, - asiSafe, - alreadyVisited = new Set() -) => { - const exportsType = info.module.getExportsType( - moduleGraph, - strictHarmonyModule - ); - if (exportName.length === 0) { - switch (exportsType) { - case "default-only": - info.interopNamespaceObject2Used = true; - return { - info, - rawName: info.interopNamespaceObject2Name, - ids: exportName, - exportName - }; - case "default-with-named": - info.interopNamespaceObjectUsed = true; - return { - info, - rawName: info.interopNamespaceObjectName, - ids: exportName, - exportName - }; - case "namespace": - case "dynamic": - break; - default: - throw new Error(`Unexpected exportsType ${exportsType}`); - } - } else { - switch (exportsType) { - case "namespace": - break; - case "default-with-named": - switch (exportName[0]) { - case "default": - exportName = exportName.slice(1); - break; - case "__esModule": - return { - info, - rawName: "/* __esModule */true", - ids: exportName.slice(1), - exportName - }; - } - break; - case "default-only": { - const exportId = exportName[0]; - if (exportId === "__esModule") { - return { - info, - rawName: "/* __esModule */true", - ids: exportName.slice(1), - exportName - }; - } - exportName = exportName.slice(1); - if (exportId !== "default") { - return { - info, - rawName: - "/* non-default import from default-exporting module */undefined", - ids: exportName, - exportName - }; - } - break; - } - case "dynamic": - switch (exportName[0]) { - case "default": { - exportName = exportName.slice(1); - info.interopDefaultAccessUsed = true; - const defaultExport = asCall - ? `${info.interopDefaultAccessName}()` - : asiSafe - ? `(${info.interopDefaultAccessName}())` - : asiSafe === false - ? `;(${info.interopDefaultAccessName}())` - : `${info.interopDefaultAccessName}.a`; - return { - info, - rawName: defaultExport, - ids: exportName, - exportName - }; - } - case "__esModule": - return { - info, - rawName: "/* __esModule */true", - ids: exportName.slice(1), - exportName - }; - } - break; - default: - throw new Error(`Unexpected exportsType ${exportsType}`); - } - } - if (exportName.length === 0) { - switch (info.type) { - case "concatenated": - neededNamespaceObjects.add(info); - return { - info, - rawName: info.namespaceObjectName, - ids: exportName, - exportName - }; - case "external": - return { info, rawName: info.name, ids: exportName, exportName }; - } - } - const exportsInfo = moduleGraph.getExportsInfo(info.module); - const exportInfo = exportsInfo.getExportInfo(exportName[0]); - if (alreadyVisited.has(exportInfo)) { - return { - info, - rawName: "/* circular reexport */ Object(function x() { x() }())", - ids: [], - exportName - }; - } - alreadyVisited.add(exportInfo); - switch (info.type) { - case "concatenated": { - const exportId = exportName[0]; - if (exportInfo.provided === false) { - // It's not provided, but it could be on the prototype - neededNamespaceObjects.add(info); - return { - info, - rawName: info.namespaceObjectName, - ids: exportName, - exportName - }; - } - const directExport = info.exportMap && info.exportMap.get(exportId); - if (directExport) { - const usedName = /** @type {string[]} */ ( - exportsInfo.getUsedName(exportName, runtime) - ); - if (!usedName) { - return { - info, - rawName: "/* unused export */ undefined", - ids: exportName.slice(1), - exportName - }; - } - return { - info, - name: directExport, - ids: usedName.slice(1), - exportName - }; - } - const rawExport = info.rawExportMap && info.rawExportMap.get(exportId); - if (rawExport) { - return { - info, - rawName: rawExport, - ids: exportName.slice(1), - exportName - }; - } - const reexport = exportInfo.findTarget(moduleGraph, module => - moduleToInfoMap.has(module) - ); - if (reexport === false) { - throw new Error( - `Target module of reexport from '${info.module.readableIdentifier( - requestShortener - )}' is not part of the concatenation (export '${exportId}')\nModules in the concatenation:\n${Array.from( - moduleToInfoMap, - ([m, info]) => - ` * ${info.type} ${m.readableIdentifier(requestShortener)}` - ).join("\n")}` - ); - } - if (reexport) { - const refInfo = moduleToInfoMap.get(reexport.module); - return getFinalBinding( - moduleGraph, - refInfo, - reexport.export - ? [...reexport.export, ...exportName.slice(1)] - : exportName.slice(1), - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - asCall, - info.module.buildMeta.strictHarmonyModule, - asiSafe, - alreadyVisited - ); - } - if (info.namespaceExportSymbol) { - const usedName = /** @type {string[]} */ ( - exportsInfo.getUsedName(exportName, runtime) - ); - return { - info, - rawName: info.namespaceObjectName, - ids: usedName, - exportName - }; - } - throw new Error( - `Cannot get final name for export '${exportName.join( - "." - )}' of ${info.module.readableIdentifier(requestShortener)}` - ); - } - - case "external": { - const used = /** @type {string[]} */ ( - exportsInfo.getUsedName(exportName, runtime) - ); - if (!used) { - return { - info, - rawName: "/* unused export */ undefined", - ids: exportName.slice(1), - exportName - }; - } - const comment = equals(used, exportName) - ? "" - : Template.toNormalComment(`${exportName.join(".")}`); - return { info, rawName: info.name + comment, ids: used, exportName }; - } - } -}; - -/** - * @param {ModuleGraph} moduleGraph the module graph - * @param {ModuleInfo} info module info - * @param {string[]} exportName exportName - * @param {Map<Module, ModuleInfo>} moduleToInfoMap moduleToInfoMap - * @param {RuntimeSpec} runtime for which runtime - * @param {RequestShortener} requestShortener the request shortener - * @param {RuntimeTemplate} runtimeTemplate the runtime template - * @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated - * @param {boolean} asCall asCall - * @param {boolean} callContext callContext - * @param {boolean} strictHarmonyModule strictHarmonyModule - * @param {boolean | undefined} asiSafe asiSafe - * @returns {string} the final name - */ -const getFinalName = ( - moduleGraph, - info, - exportName, - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - asCall, - callContext, - strictHarmonyModule, - asiSafe -) => { - const binding = getFinalBinding( - moduleGraph, - info, - exportName, - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - asCall, - strictHarmonyModule, - asiSafe - ); - { - const { ids, comment } = binding; - let reference; - let isPropertyAccess; - if ("rawName" in binding) { - reference = `${binding.rawName}${comment || ""}${propertyAccess(ids)}`; - isPropertyAccess = ids.length > 0; - } else { - const { info, name: exportId } = binding; - const name = info.internalNames.get(exportId); - if (!name) { - throw new Error( - `The export "${exportId}" in "${info.module.readableIdentifier( - requestShortener - )}" has no internal name (existing names: ${ - Array.from( - info.internalNames, - ([name, symbol]) => `${name}: ${symbol}` - ).join(", ") || "none" - })` - ); - } - reference = `${name}${comment || ""}${propertyAccess(ids)}`; - isPropertyAccess = ids.length > 1; - } - if (isPropertyAccess && asCall && callContext === false) { - return asiSafe - ? `(0,${reference})` - : asiSafe === false - ? `;(0,${reference})` - : `/*#__PURE__*/Object(${reference})`; - } - return reference; - } -}; - -const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => { - let scope = s; - while (scope) { - if (scopeSet1.has(scope)) break; - if (scopeSet2.has(scope)) break; - scopeSet1.add(scope); - for (const variable of scope.variables) { - nameSet.add(variable.name); - } - scope = scope.upper; - } -}; - -const getAllReferences = variable => { - let set = variable.references; - // Look for inner scope variables too (like in class Foo { t() { Foo } }) - const identifiers = new Set(variable.identifiers); - for (const scope of variable.scope.childScopes) { - for (const innerVar of scope.variables) { - if (innerVar.identifiers.some(id => identifiers.has(id))) { - set = set.concat(innerVar.references); - break; - } - } - } - return set; -}; - -const getPathInAst = (ast, node) => { - if (ast === node) { - return []; - } - - const nr = node.range; - - const enterNode = n => { - if (!n) return undefined; - const r = n.range; - if (r) { - if (r[0] <= nr[0] && r[1] >= nr[1]) { - const path = getPathInAst(n, node); - if (path) { - path.push(n); - return path; - } - } - } - return undefined; - }; - - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - const enterResult = enterNode(ast[i]); - if (enterResult !== undefined) return enterResult; - } - } else if (ast && typeof ast === "object") { - const keys = Object.keys(ast); - for (let i = 0; i < keys.length; i++) { - const value = ast[keys[i]]; - if (Array.isArray(value)) { - const pathResult = getPathInAst(value, node); - if (pathResult !== undefined) return pathResult; - } else if (value && typeof value === "object") { - const enterResult = enterNode(value); - if (enterResult !== undefined) return enterResult; - } - } - } -}; - -const TYPES = new Set(["javascript"]); - -class ConcatenatedModule extends Module { - /** - * @param {Module} rootModule the root module of the concatenation - * @param {Set<Module>} modules all modules in the concatenation (including the root module) - * @param {RuntimeSpec} runtime the runtime - * @param {Object=} associatedObjectForCache object for caching - * @param {string | HashConstructor=} hashFunction hash function to use - * @returns {ConcatenatedModule} the module - */ - static create( - rootModule, - modules, - runtime, - associatedObjectForCache, - hashFunction = "md4" - ) { - const identifier = ConcatenatedModule._createIdentifier( - rootModule, - modules, - associatedObjectForCache, - hashFunction - ); - return new ConcatenatedModule({ - identifier, - rootModule, - modules, - runtime - }); - } - - /** - * @param {Object} options options - * @param {string} options.identifier the identifier of the module - * @param {Module=} options.rootModule the root module of the concatenation - * @param {RuntimeSpec} options.runtime the selected runtime - * @param {Set<Module>=} options.modules all concatenated modules - */ - constructor({ identifier, rootModule, modules, runtime }) { - super(JAVASCRIPT_MODULE_TYPE_ESM, null, rootModule && rootModule.layer); - - // Info from Factory - /** @type {string} */ - this._identifier = identifier; - /** @type {Module} */ - this.rootModule = rootModule; - /** @type {Set<Module>} */ - this._modules = modules; - this._runtime = runtime; - this.factoryMeta = rootModule && rootModule.factoryMeta; - } - - /** - * Assuming this module is in the cache. Update the (cached) module with - * the fresh module from the factory. Usually updates internal references - * and properties. - * @param {Module} module fresh module - * @returns {void} - */ - updateCacheModule(module) { - throw new Error("Must not be called"); - } - - /** - * @returns {Set<string>} types available (do not mutate) - */ - getSourceTypes() { - return TYPES; - } - - get modules() { - return Array.from(this._modules); - } - - /** - * @returns {string} a unique identifier of the module - */ - identifier() { - return this._identifier; - } - - /** - * @param {RequestShortener} requestShortener the request shortener - * @returns {string} a user readable identifier of the module - */ - readableIdentifier(requestShortener) { - return ( - this.rootModule.readableIdentifier(requestShortener) + - ` + ${this._modules.size - 1} modules` - ); - } - - /** - * @param {LibIdentOptions} options options - * @returns {string | null} an identifier for library inclusion - */ - libIdent(options) { - return this.rootModule.libIdent(options); - } - - /** - * @returns {string | null} absolute path which should be used for condition matching (usually the resource path) - */ - nameForCondition() { - return this.rootModule.nameForCondition(); - } - - /** - * @param {ModuleGraph} moduleGraph the module graph - * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only - */ - getSideEffectsConnectionState(moduleGraph) { - return this.rootModule.getSideEffectsConnectionState(moduleGraph); - } - - /** - * @param {WebpackOptions} options webpack options - * @param {Compilation} compilation the compilation - * @param {ResolverWithOptions} resolver the resolver - * @param {InputFileSystem} fs the file system - * @param {function(WebpackError=): void} callback callback function - * @returns {void} - */ - build(options, compilation, resolver, fs, callback) { - const { rootModule } = this; - this.buildInfo = { - strict: true, - cacheable: true, - moduleArgument: rootModule.buildInfo.moduleArgument, - exportsArgument: rootModule.buildInfo.exportsArgument, - fileDependencies: new LazySet(), - contextDependencies: new LazySet(), - missingDependencies: new LazySet(), - topLevelDeclarations: new Set(), - assets: undefined - }; - this.buildMeta = rootModule.buildMeta; - this.clearDependenciesAndBlocks(); - this.clearWarningsAndErrors(); - - for (const m of this._modules) { - // populate cacheable - if (!m.buildInfo.cacheable) { - this.buildInfo.cacheable = false; - } - - // populate dependencies - for (const d of m.dependencies.filter( - dep => - !(dep instanceof HarmonyImportDependency) || - !this._modules.has(compilation.moduleGraph.getModule(dep)) - )) { - this.dependencies.push(d); - } - // populate blocks - for (const d of m.blocks) { - this.blocks.push(d); - } - - // populate warnings - const warnings = m.getWarnings(); - if (warnings !== undefined) { - for (const warning of warnings) { - this.addWarning(warning); - } - } - - // populate errors - const errors = m.getErrors(); - if (errors !== undefined) { - for (const error of errors) { - this.addError(error); - } - } - - // populate topLevelDeclarations - if (m.buildInfo.topLevelDeclarations) { - const topLevelDeclarations = this.buildInfo.topLevelDeclarations; - if (topLevelDeclarations !== undefined) { - for (const decl of m.buildInfo.topLevelDeclarations) { - topLevelDeclarations.add(decl); - } - } - } else { - this.buildInfo.topLevelDeclarations = undefined; - } - - // populate assets - if (m.buildInfo.assets) { - if (this.buildInfo.assets === undefined) { - this.buildInfo.assets = Object.create(null); - } - Object.assign(this.buildInfo.assets, m.buildInfo.assets); - } - if (m.buildInfo.assetsInfo) { - if (this.buildInfo.assetsInfo === undefined) { - this.buildInfo.assetsInfo = new Map(); - } - for (const [key, value] of m.buildInfo.assetsInfo) { - this.buildInfo.assetsInfo.set(key, value); - } - } - } - callback(); - } - - /** - * @param {string=} type the source type for which the size should be estimated - * @returns {number} the estimated size of the module (must be non-zero) - */ - size(type) { - // Guess size from embedded modules - let size = 0; - for (const module of this._modules) { - size += module.size(type); - } - return size; - } - - /** - * @private - * @param {Module} rootModule the root of the concatenation - * @param {Set<Module>} modulesSet a set of modules which should be concatenated - * @param {RuntimeSpec} runtime for this runtime - * @param {ModuleGraph} moduleGraph the module graph - * @returns {ConcatenationEntry[]} concatenation list - */ - _createConcatenationList(rootModule, modulesSet, runtime, moduleGraph) { - /** @type {ConcatenationEntry[]} */ - const list = []; - /** @type {Map<Module, RuntimeSpec | true>} */ - const existingEntries = new Map(); - - /** - * @param {Module} module a module - * @returns {Iterable<{ connection: ModuleGraphConnection, runtimeCondition: RuntimeSpec | true }>} imported modules in order - */ - const getConcatenatedImports = module => { - let connections = Array.from(moduleGraph.getOutgoingConnections(module)); - if (module === rootModule) { - for (const c of moduleGraph.getOutgoingConnections(this)) - connections.push(c); - } - /** - * @type {Array<{ connection: ModuleGraphConnection, sourceOrder: number, rangeStart: number }>} - */ - const references = connections - .filter(connection => { - if (!(connection.dependency instanceof HarmonyImportDependency)) - return false; - return ( - connection && - connection.resolvedOriginModule === module && - connection.module && - connection.isTargetActive(runtime) - ); - }) - .map(connection => { - const dep = /** @type {HarmonyImportDependency} */ ( - connection.dependency - ); - return { - connection, - sourceOrder: dep.sourceOrder, - rangeStart: dep.range && dep.range[0] - }; - }); - /** - * bySourceOrder - * @example - * import a from "a"; // sourceOrder=1 - * import b from "b"; // sourceOrder=2 - * - * byRangeStart - * @example - * import {a, b} from "a"; // sourceOrder=1 - * a.a(); // first range - * b.b(); // second range - * - * If there is no reexport, we have the same source. - * If there is reexport, but module has side effects, this will lead to reexport module only. - * If there is side-effects-free reexport, we can get simple deterministic result with range start comparison. - */ - references.sort(concatComparators(bySourceOrder, byRangeStart)); - /** @type {Map<Module, { connection: ModuleGraphConnection, runtimeCondition: RuntimeSpec | true }>} */ - const referencesMap = new Map(); - for (const { connection } of references) { - const runtimeCondition = filterRuntime(runtime, r => - connection.isTargetActive(r) - ); - if (runtimeCondition === false) continue; - const module = connection.module; - const entry = referencesMap.get(module); - if (entry === undefined) { - referencesMap.set(module, { connection, runtimeCondition }); - continue; - } - entry.runtimeCondition = mergeRuntimeConditionNonFalse( - entry.runtimeCondition, - runtimeCondition, - runtime - ); - } - return referencesMap.values(); - }; - - /** - * @param {ModuleGraphConnection} connection graph connection - * @param {RuntimeSpec | true} runtimeCondition runtime condition - * @returns {void} - */ - const enterModule = (connection, runtimeCondition) => { - const module = connection.module; - if (!module) return; - const existingEntry = existingEntries.get(module); - if (existingEntry === true) { - return; - } - if (modulesSet.has(module)) { - existingEntries.set(module, true); - if (runtimeCondition !== true) { - throw new Error( - `Cannot runtime-conditional concatenate a module (${module.identifier()} in ${this.rootModule.identifier()}, ${runtimeConditionToString( - runtimeCondition - )}). This should not happen.` - ); - } - const imports = getConcatenatedImports(module); - for (const { connection, runtimeCondition } of imports) - enterModule(connection, runtimeCondition); - list.push({ - type: "concatenated", - module: connection.module, - runtimeCondition - }); - } else { - if (existingEntry !== undefined) { - const reducedRuntimeCondition = subtractRuntimeCondition( - runtimeCondition, - existingEntry, - runtime - ); - if (reducedRuntimeCondition === false) return; - runtimeCondition = reducedRuntimeCondition; - existingEntries.set( - connection.module, - mergeRuntimeConditionNonFalse( - existingEntry, - runtimeCondition, - runtime - ) - ); - } else { - existingEntries.set(connection.module, runtimeCondition); - } - if (list.length > 0) { - const lastItem = list[list.length - 1]; - if ( - lastItem.type === "external" && - lastItem.module === connection.module - ) { - lastItem.runtimeCondition = mergeRuntimeCondition( - lastItem.runtimeCondition, - runtimeCondition, - runtime - ); - return; - } - } - list.push({ - type: "external", - get module() { - // We need to use a getter here, because the module in the dependency - // could be replaced by some other process (i. e. also replaced with a - // concatenated module) - return connection.module; - }, - runtimeCondition - }); - } - }; - - existingEntries.set(rootModule, true); - const imports = getConcatenatedImports(rootModule); - for (const { connection, runtimeCondition } of imports) - enterModule(connection, runtimeCondition); - list.push({ - type: "concatenated", - module: rootModule, - runtimeCondition: true - }); - - return list; - } - - /** - * @param {Module} rootModule the root module of the concatenation - * @param {Set<Module>} modules all modules in the concatenation (including the root module) - * @param {Object=} associatedObjectForCache object for caching - * @param {string | HashConstructor=} hashFunction hash function to use - * @returns {string} the identifier - */ - static _createIdentifier( - rootModule, - modules, - associatedObjectForCache, - hashFunction = "md4" - ) { - const cachedMakePathsRelative = makePathsRelative.bindContextCache( - rootModule.context, - associatedObjectForCache - ); - let identifiers = []; - for (const module of modules) { - identifiers.push(cachedMakePathsRelative(module.identifier())); - } - identifiers.sort(); - const hash = createHash(hashFunction); - hash.update(identifiers.join(" ")); - return rootModule.identifier() + "|" + hash.digest("hex"); - } - - /** - * @param {LazySet<string>} fileDependencies set where file dependencies are added to - * @param {LazySet<string>} contextDependencies set where context dependencies are added to - * @param {LazySet<string>} missingDependencies set where missing dependencies are added to - * @param {LazySet<string>} buildDependencies set where build dependencies are added to - */ - addCacheDependencies( - fileDependencies, - contextDependencies, - missingDependencies, - buildDependencies - ) { - for (const module of this._modules) { - module.addCacheDependencies( - fileDependencies, - contextDependencies, - missingDependencies, - buildDependencies - ); - } - } - - /** - * @param {CodeGenerationContext} context context for code generation - * @returns {CodeGenerationResult} result - */ - codeGeneration({ - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - runtime: generationRuntime, - codeGenerationResults - }) { - /** @type {Set<string>} */ - const runtimeRequirements = new Set(); - const runtime = intersectRuntime(generationRuntime, this._runtime); - - const requestShortener = runtimeTemplate.requestShortener; - // Meta info for each module - const [modulesWithInfo, moduleToInfoMap] = this._getModulesWithInfo( - moduleGraph, - runtime - ); - - // Set with modules that need a generated namespace object - /** @type {Set<ConcatenatedModuleInfo>} */ - const neededNamespaceObjects = new Set(); - - // Generate source code and analyse scopes - // Prepare a ReplaceSource for the final source - for (const info of moduleToInfoMap.values()) { - this._analyseModule( - moduleToInfoMap, - info, - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - runtime, - codeGenerationResults - ); - } - - // List of all used names to avoid conflicts - const allUsedNames = new Set(RESERVED_NAMES); - // Updated Top level declarations are created by renaming - const topLevelDeclarations = new Set(); - - // List of additional names in scope for module references - /** @type {Map<string, { usedNames: Set<string>, alreadyCheckedScopes: Set<TODO> }>} */ - const usedNamesInScopeInfo = new Map(); - /** - * @param {string} module module identifier - * @param {string} id export id - * @returns {{ usedNames: Set<string>, alreadyCheckedScopes: Set<TODO> }} info - */ - const getUsedNamesInScopeInfo = (module, id) => { - const key = `${module}-${id}`; - let info = usedNamesInScopeInfo.get(key); - if (info === undefined) { - info = { - usedNames: new Set(), - alreadyCheckedScopes: new Set() - }; - usedNamesInScopeInfo.set(key, info); - } - return info; - }; - - // Set of already checked scopes - const ignoredScopes = new Set(); - - // get all global names - for (const info of modulesWithInfo) { - if (info.type === "concatenated") { - // ignore symbols from moduleScope - if (info.moduleScope) { - ignoredScopes.add(info.moduleScope); - } - - // The super class expression in class scopes behaves weird - // We get ranges of all super class expressions to make - // renaming to work correctly - const superClassCache = new WeakMap(); - const getSuperClassExpressions = scope => { - const cacheEntry = superClassCache.get(scope); - if (cacheEntry !== undefined) return cacheEntry; - const superClassExpressions = []; - for (const childScope of scope.childScopes) { - if (childScope.type !== "class") continue; - const block = childScope.block; - if ( - (block.type === "ClassDeclaration" || - block.type === "ClassExpression") && - block.superClass - ) { - superClassExpressions.push({ - range: block.superClass.range, - variables: childScope.variables - }); - } - } - superClassCache.set(scope, superClassExpressions); - return superClassExpressions; - }; - - // add global symbols - if (info.globalScope) { - for (const reference of info.globalScope.through) { - const name = reference.identifier.name; - if (ConcatenationScope.isModuleReference(name)) { - const match = ConcatenationScope.matchModuleReference(name); - if (!match) continue; - const referencedInfo = modulesWithInfo[match.index]; - if (referencedInfo.type === "reference") - throw new Error("Module reference can't point to a reference"); - const binding = getFinalBinding( - moduleGraph, - referencedInfo, - match.ids, - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - false, - info.module.buildMeta.strictHarmonyModule, - true - ); - if (!binding.ids) continue; - const { usedNames, alreadyCheckedScopes } = - getUsedNamesInScopeInfo( - binding.info.module.identifier(), - "name" in binding ? binding.name : "" - ); - for (const expr of getSuperClassExpressions(reference.from)) { - if ( - expr.range[0] <= reference.identifier.range[0] && - expr.range[1] >= reference.identifier.range[1] - ) { - for (const variable of expr.variables) { - usedNames.add(variable.name); - } - } - } - addScopeSymbols( - reference.from, - usedNames, - alreadyCheckedScopes, - ignoredScopes - ); - } else { - allUsedNames.add(name); - } - } - } - } - } - - // generate names for symbols - for (const info of moduleToInfoMap.values()) { - const { usedNames: namespaceObjectUsedNames } = getUsedNamesInScopeInfo( - info.module.identifier(), - "" - ); - switch (info.type) { - case "concatenated": { - for (const variable of info.moduleScope.variables) { - const name = variable.name; - const { usedNames, alreadyCheckedScopes } = getUsedNamesInScopeInfo( - info.module.identifier(), - name - ); - if (allUsedNames.has(name) || usedNames.has(name)) { - const references = getAllReferences(variable); - for (const ref of references) { - addScopeSymbols( - ref.from, - usedNames, - alreadyCheckedScopes, - ignoredScopes - ); - } - const newName = this.findNewName( - name, - allUsedNames, - usedNames, - info.module.readableIdentifier(requestShortener) - ); - allUsedNames.add(newName); - info.internalNames.set(name, newName); - topLevelDeclarations.add(newName); - const source = info.source; - const allIdentifiers = new Set( - references.map(r => r.identifier).concat(variable.identifiers) - ); - for (const identifier of allIdentifiers) { - const r = identifier.range; - const path = getPathInAst(info.ast, identifier); - if (path && path.length > 1) { - const maybeProperty = - path[1].type === "AssignmentPattern" && - path[1].left === path[0] - ? path[2] - : path[1]; - if ( - maybeProperty.type === "Property" && - maybeProperty.shorthand - ) { - source.insert(r[1], `: ${newName}`); - continue; - } - } - source.replace(r[0], r[1] - 1, newName); - } - } else { - allUsedNames.add(name); - info.internalNames.set(name, name); - topLevelDeclarations.add(name); - } - } - let namespaceObjectName; - if (info.namespaceExportSymbol) { - namespaceObjectName = info.internalNames.get( - info.namespaceExportSymbol - ); - } else { - namespaceObjectName = this.findNewName( - "namespaceObject", - allUsedNames, - namespaceObjectUsedNames, - info.module.readableIdentifier(requestShortener) - ); - allUsedNames.add(namespaceObjectName); - } - info.namespaceObjectName = namespaceObjectName; - topLevelDeclarations.add(namespaceObjectName); - break; - } - case "external": { - const externalName = this.findNewName( - "", - allUsedNames, - namespaceObjectUsedNames, - info.module.readableIdentifier(requestShortener) - ); - allUsedNames.add(externalName); - info.name = externalName; - topLevelDeclarations.add(externalName); - break; - } - } - if (info.module.buildMeta.exportsType !== "namespace") { - const externalNameInterop = this.findNewName( - "namespaceObject", - allUsedNames, - namespaceObjectUsedNames, - info.module.readableIdentifier(requestShortener) - ); - allUsedNames.add(externalNameInterop); - info.interopNamespaceObjectName = externalNameInterop; - topLevelDeclarations.add(externalNameInterop); - } - if ( - info.module.buildMeta.exportsType === "default" && - info.module.buildMeta.defaultObject !== "redirect" - ) { - const externalNameInterop = this.findNewName( - "namespaceObject2", - allUsedNames, - namespaceObjectUsedNames, - info.module.readableIdentifier(requestShortener) - ); - allUsedNames.add(externalNameInterop); - info.interopNamespaceObject2Name = externalNameInterop; - topLevelDeclarations.add(externalNameInterop); - } - if ( - info.module.buildMeta.exportsType === "dynamic" || - !info.module.buildMeta.exportsType - ) { - const externalNameInterop = this.findNewName( - "default", - allUsedNames, - namespaceObjectUsedNames, - info.module.readableIdentifier(requestShortener) - ); - allUsedNames.add(externalNameInterop); - info.interopDefaultAccessName = externalNameInterop; - topLevelDeclarations.add(externalNameInterop); - } - } - - // Find and replace references to modules - for (const info of moduleToInfoMap.values()) { - if (info.type === "concatenated") { - for (const reference of info.globalScope.through) { - const name = reference.identifier.name; - const match = ConcatenationScope.matchModuleReference(name); - if (match) { - const referencedInfo = modulesWithInfo[match.index]; - if (referencedInfo.type === "reference") - throw new Error("Module reference can't point to a reference"); - const finalName = getFinalName( - moduleGraph, - referencedInfo, - match.ids, - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - match.call, - !match.directImport, - info.module.buildMeta.strictHarmonyModule, - match.asiSafe - ); - const r = reference.identifier.range; - const source = info.source; - // range is extended by 2 chars to cover the appended "._" - source.replace(r[0], r[1] + 1, finalName); - } - } - } - } - - // Map with all root exposed used exports - /** @type {Map<string, function(RequestShortener): string>} */ - const exportsMap = new Map(); - - // Set with all root exposed unused exports - /** @type {Set<string>} */ - const unusedExports = new Set(); - - const rootInfo = /** @type {ConcatenatedModuleInfo} */ ( - moduleToInfoMap.get(this.rootModule) - ); - const strictHarmonyModule = rootInfo.module.buildMeta.strictHarmonyModule; - const exportsInfo = moduleGraph.getExportsInfo(rootInfo.module); - for (const exportInfo of exportsInfo.orderedExports) { - const name = exportInfo.name; - if (exportInfo.provided === false) continue; - const used = exportInfo.getUsedName(undefined, runtime); - if (!used) { - unusedExports.add(name); - continue; - } - exportsMap.set(used, requestShortener => { - try { - const finalName = getFinalName( - moduleGraph, - rootInfo, - [name], - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - false, - false, - strictHarmonyModule, - true - ); - return `/* ${ - exportInfo.isReexport() ? "reexport" : "binding" - } */ ${finalName}`; - } catch (e) { - e.message += `\nwhile generating the root export '${name}' (used name: '${used}')`; - throw e; - } - }); - } - - const result = new ConcatSource(); - - // add harmony compatibility flag (must be first because of possible circular dependencies) - if ( - moduleGraph.getExportsInfo(this).otherExportsInfo.getUsed(runtime) !== - UsageState.Unused - ) { - result.add(`// ESM COMPAT FLAG\n`); - result.add( - runtimeTemplate.defineEsModuleFlagStatement({ - exportsArgument: this.exportsArgument, - runtimeRequirements - }) - ); - } - - // define exports - if (exportsMap.size > 0) { - runtimeRequirements.add(RuntimeGlobals.exports); - runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); - const definitions = []; - for (const [key, value] of exportsMap) { - definitions.push( - `\n ${propertyName(key)}: ${runtimeTemplate.returningFunction( - value(requestShortener) - )}` - ); - } - result.add(`\n// EXPORTS\n`); - result.add( - `${RuntimeGlobals.definePropertyGetters}(${ - this.exportsArgument - }, {${definitions.join(",")}\n});\n` - ); - } - - // list unused exports - if (unusedExports.size > 0) { - result.add( - `\n// UNUSED EXPORTS: ${joinIterableWithComma(unusedExports)}\n` - ); - } - - // generate namespace objects - const namespaceObjectSources = new Map(); - for (const info of neededNamespaceObjects) { - if (info.namespaceExportSymbol) continue; - const nsObj = []; - const exportsInfo = moduleGraph.getExportsInfo(info.module); - for (const exportInfo of exportsInfo.orderedExports) { - if (exportInfo.provided === false) continue; - const usedName = exportInfo.getUsedName(undefined, runtime); - if (usedName) { - const finalName = getFinalName( - moduleGraph, - info, - [exportInfo.name], - moduleToInfoMap, - runtime, - requestShortener, - runtimeTemplate, - neededNamespaceObjects, - false, - undefined, - info.module.buildMeta.strictHarmonyModule, - true - ); - nsObj.push( - `\n ${propertyName(usedName)}: ${runtimeTemplate.returningFunction( - finalName - )}` - ); - } - } - const name = info.namespaceObjectName; - const defineGetters = - nsObj.length > 0 - ? `${RuntimeGlobals.definePropertyGetters}(${name}, {${nsObj.join( - "," - )}\n});\n` - : ""; - if (nsObj.length > 0) - runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); - namespaceObjectSources.set( - info, - ` -// NAMESPACE OBJECT: ${info.module.readableIdentifier(requestShortener)} -var ${name} = {}; -${RuntimeGlobals.makeNamespaceObject}(${name}); -${defineGetters}` - ); - runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject); - } - - // define required namespace objects (must be before evaluation modules) - for (const info of modulesWithInfo) { - if (info.type === "concatenated") { - const source = namespaceObjectSources.get(info); - if (!source) continue; - result.add(source); - } - } - - const chunkInitFragments = []; - - // evaluate modules in order - for (const rawInfo of modulesWithInfo) { - let name; - let isConditional = false; - const info = rawInfo.type === "reference" ? rawInfo.target : rawInfo; - switch (info.type) { - case "concatenated": { - result.add( - `\n;// CONCATENATED MODULE: ${info.module.readableIdentifier( - requestShortener - )}\n` - ); - result.add(info.source); - if (info.chunkInitFragments) { - for (const f of info.chunkInitFragments) chunkInitFragments.push(f); - } - if (info.runtimeRequirements) { - for (const r of info.runtimeRequirements) { - runtimeRequirements.add(r); - } - } - name = info.namespaceObjectName; - break; - } - case "external": { - result.add( - `\n// EXTERNAL MODULE: ${info.module.readableIdentifier( - requestShortener - )}\n` - ); - runtimeRequirements.add(RuntimeGlobals.require); - const { runtimeCondition } = - /** @type {ExternalModuleInfo | ReferenceToModuleInfo} */ (rawInfo); - const condition = runtimeTemplate.runtimeConditionExpression({ - chunkGraph, - runtimeCondition, - runtime, - runtimeRequirements - }); - if (condition !== "true") { - isConditional = true; - result.add(`if (${condition}) {\n`); - } - result.add( - `var ${info.name} = ${RuntimeGlobals.require}(${JSON.stringify( - chunkGraph.getModuleId(info.module) - )});` - ); - name = info.name; - break; - } - default: - // @ts-expect-error never is expected here - throw new Error(`Unsupported concatenation entry type ${info.type}`); - } - if (info.interopNamespaceObjectUsed) { - runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject); - result.add( - `\nvar ${info.interopNamespaceObjectName} = /*#__PURE__*/${RuntimeGlobals.createFakeNamespaceObject}(${name}, 2);` - ); - } - if (info.interopNamespaceObject2Used) { - runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject); - result.add( - `\nvar ${info.interopNamespaceObject2Name} = /*#__PURE__*/${RuntimeGlobals.createFakeNamespaceObject}(${name});` - ); - } - if (info.interopDefaultAccessUsed) { - runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport); - result.add( - `\nvar ${info.interopDefaultAccessName} = /*#__PURE__*/${RuntimeGlobals.compatGetDefaultExport}(${name});` - ); - } - if (isConditional) { - result.add("\n}"); - } - } - - const data = new Map(); - if (chunkInitFragments.length > 0) - data.set("chunkInitFragments", chunkInitFragments); - data.set("topLevelDeclarations", topLevelDeclarations); - - /** @type {CodeGenerationResult} */ - const resultEntry = { - sources: new Map([["javascript", new CachedSource(result)]]), - data, - runtimeRequirements - }; - - return resultEntry; - } - - /** - * @param {Map<Module, ModuleInfo>} modulesMap modulesMap - * @param {ModuleInfo} info info - * @param {DependencyTemplates} dependencyTemplates dependencyTemplates - * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate - * @param {ModuleGraph} moduleGraph moduleGraph - * @param {ChunkGraph} chunkGraph chunkGraph - * @param {RuntimeSpec} runtime runtime - * @param {CodeGenerationResults} codeGenerationResults codeGenerationResults - */ - _analyseModule( - modulesMap, - info, - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - runtime, - codeGenerationResults - ) { - if (info.type === "concatenated") { - const m = info.module; - try { - // Create a concatenation scope to track and capture information - const concatenationScope = new ConcatenationScope(modulesMap, info); - - // TODO cache codeGeneration results - const codeGenResult = m.codeGeneration({ - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - runtime, - concatenationScope, - codeGenerationResults, - sourceTypes: TYPES - }); - const source = codeGenResult.sources.get("javascript"); - const data = codeGenResult.data; - const chunkInitFragments = data && data.get("chunkInitFragments"); - const code = source.source().toString(); - let ast; - try { - ast = JavascriptParser._parse(code, { - sourceType: "module" - }); - } catch (err) { - if ( - err.loc && - typeof err.loc === "object" && - typeof err.loc.line === "number" - ) { - const lineNumber = err.loc.line; - const lines = code.split("\n"); - err.message += - "\n| " + - lines - .slice(Math.max(0, lineNumber - 3), lineNumber + 2) - .join("\n| "); - } - throw err; - } - const scopeManager = eslintScope.analyze(ast, { - ecmaVersion: 6, - sourceType: "module", - optimistic: true, - ignoreEval: true, - impliedStrict: true - }); - const globalScope = scopeManager.acquire(ast); - const moduleScope = globalScope.childScopes[0]; - const resultSource = new ReplaceSource(source); - info.runtimeRequirements = codeGenResult.runtimeRequirements; - info.ast = ast; - info.internalSource = source; - info.source = resultSource; - info.chunkInitFragments = chunkInitFragments; - info.globalScope = globalScope; - info.moduleScope = moduleScope; - } catch (err) { - err.message += `\nwhile analyzing module ${m.identifier()} for concatenation`; - throw err; - } - } - } - - /** - * @param {ModuleGraph} moduleGraph the module graph - * @param {RuntimeSpec} runtime the runtime - * @returns {[ModuleInfoOrReference[], Map<Module, ModuleInfo>]} module info items - */ - _getModulesWithInfo(moduleGraph, runtime) { - const orderedConcatenationList = this._createConcatenationList( - this.rootModule, - this._modules, - runtime, - moduleGraph - ); - /** @type {Map<Module, ModuleInfo>} */ - const map = new Map(); - const list = orderedConcatenationList.map((info, index) => { - let item = map.get(info.module); - if (item === undefined) { - switch (info.type) { - case "concatenated": - item = { - type: "concatenated", - module: info.module, - index, - ast: undefined, - internalSource: undefined, - runtimeRequirements: undefined, - source: undefined, - globalScope: undefined, - moduleScope: undefined, - internalNames: new Map(), - exportMap: undefined, - rawExportMap: undefined, - namespaceExportSymbol: undefined, - namespaceObjectName: undefined, - interopNamespaceObjectUsed: false, - interopNamespaceObjectName: undefined, - interopNamespaceObject2Used: false, - interopNamespaceObject2Name: undefined, - interopDefaultAccessUsed: false, - interopDefaultAccessName: undefined - }; - break; - case "external": - item = { - type: "external", - module: info.module, - runtimeCondition: info.runtimeCondition, - index, - name: undefined, - interopNamespaceObjectUsed: false, - interopNamespaceObjectName: undefined, - interopNamespaceObject2Used: false, - interopNamespaceObject2Name: undefined, - interopDefaultAccessUsed: false, - interopDefaultAccessName: undefined - }; - break; - default: - throw new Error( - `Unsupported concatenation entry type ${info.type}` - ); - } - map.set(item.module, item); - return item; - } else { - /** @type {ReferenceToModuleInfo} */ - const ref = { - type: "reference", - runtimeCondition: info.runtimeCondition, - target: item - }; - return ref; - } - }); - return [list, map]; - } - - findNewName(oldName, usedNamed1, usedNamed2, extraInfo) { - let name = oldName; - - if (name === ConcatenationScope.DEFAULT_EXPORT) { - name = ""; - } - if (name === ConcatenationScope.NAMESPACE_OBJECT_EXPORT) { - name = "namespaceObject"; - } - - // Remove uncool stuff - extraInfo = extraInfo.replace( - /\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules/g, - "" - ); - - const splittedInfo = extraInfo.split("/"); - while (splittedInfo.length) { - name = splittedInfo.pop() + (name ? "_" + name : ""); - const nameIdent = Template.toIdentifier(name); - if ( - !usedNamed1.has(nameIdent) && - (!usedNamed2 || !usedNamed2.has(nameIdent)) - ) - return nameIdent; - } - - let i = 0; - let nameWithNumber = Template.toIdentifier(`${name}_${i}`); - while ( - usedNamed1.has(nameWithNumber) || - (usedNamed2 && usedNamed2.has(nameWithNumber)) - ) { - i++; - nameWithNumber = Template.toIdentifier(`${name}_${i}`); - } - return nameWithNumber; - } - - /** - * @param {Hash} hash the hash used to track dependencies - * @param {UpdateHashContext} context context - * @returns {void} - */ - updateHash(hash, context) { - const { chunkGraph, runtime } = context; - for (const info of this._createConcatenationList( - this.rootModule, - this._modules, - intersectRuntime(runtime, this._runtime), - chunkGraph.moduleGraph - )) { - switch (info.type) { - case "concatenated": - info.module.updateHash(hash, context); - break; - case "external": - hash.update(`${chunkGraph.getModuleId(info.module)}`); - // TODO runtimeCondition - break; - } - } - super.updateHash(hash, context); - } - - static deserialize(context) { - const obj = new ConcatenatedModule({ - identifier: undefined, - rootModule: undefined, - modules: undefined, - runtime: undefined - }); - obj.deserialize(context); - return obj; - } -} - -makeSerializable(ConcatenatedModule, "webpack/lib/optimize/ConcatenatedModule"); - -module.exports = ConcatenatedModule; |
