diff --git a/lib/ChunkGraph.js b/lib/ChunkGraph.js index d42490d42..256317328 100644 --- a/lib/ChunkGraph.js +++ b/lib/ChunkGraph.js @@ -113,6 +113,7 @@ const modulesBySourceType = sourceTypesByModule => set => { } return map; }; +const defaultModulesBySourceType = modulesBySourceType(undefined); /** @type {WeakMap} */ const createOrderedArrayFunctionMap = new WeakMap(); @@ -218,6 +219,21 @@ class ChunkGraphChunk { this.runtimeRequirements = undefined; /** @type {Set} */ this.runtimeRequirementsInTree = new Set(); + + this._modulesBySourceType = undefined; + } + + get modulesBySourceType() { + if (!this._modulesBySourceType) { + if (this.sourceTypesByModule) { + this._modulesBySourceType = modulesBySourceType( + this.sourceTypesByModule + ); + } else { + return defaultModulesBySourceType; + } + } + return this._modulesBySourceType; } } @@ -574,7 +590,7 @@ class ChunkGraph { getChunkModulesIterableBySourceType(chunk, sourceType) { const cgc = this._getChunkGraphChunk(chunk); const modulesWithSourceType = cgc.modules - .getFromUnorderedCache(modulesBySourceType(cgc.sourceTypesByModule)) + .getFromUnorderedCache(cgc.modulesBySourceType) .get(sourceType); return modulesWithSourceType; } @@ -592,6 +608,45 @@ class ChunkGraph { cgc.sourceTypesByModule.set(module, sourceTypes); } + /** + * @param {Chunk} chunk chunk + * @param {Module} module chunk module + * @returns {Set} source types + */ + getChunkModuleSourceTypes(chunk, module) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.sourceTypesByModule === undefined) { + return module.getSourceTypes(); + } + return cgc.sourceTypesByModule.get(module) || module.getSourceTypes(); + } + + /** + * @param {Module} module module + * @returns {Set} source types + */ + getModuleSourceTypes(module) { + let newSet = false; + let sourceTypes; + for (const chunk of this.getModuleChunksIterable(module)) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.sourceTypesByModule === undefined) continue; + const st = cgc.sourceTypesByModule.get(module); + if (st) { + if (!sourceTypes) { + sourceTypes = st; + continue; + } else if (!newSet) { + newSet = true; + sourceTypes = new Set(sourceTypes); + } + for (const type of st) sourceTypes.add(type); + } + } + + return sourceTypes || module.getSourceTypes(); + } + /** * @param {Chunk} chunk the chunk * @param {function(Module, Module): -1|0|1} comparator comparator function @@ -612,7 +667,7 @@ class ChunkGraph { getOrderedChunkModulesIterableBySourceType(chunk, sourceType, comparator) { const cgc = this._getChunkGraphChunk(chunk); const modulesWithSourceType = cgc.modules - .getFromUnorderedCache(modulesBySourceType(cgc.sourceTypesByModule)) + .getFromUnorderedCache(cgc.modulesBySourceType) .get(sourceType); if (modulesWithSourceType === undefined) return undefined; modulesWithSourceType.sortWith(comparator); diff --git a/lib/Module.js b/lib/Module.js index 4e0410ff0..781fdc17a 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -60,6 +60,7 @@ const makeSerializable = require("./util/makeSerializable"); * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules * @property {CodeGenerationResults} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that) * @property {Compilation=} compilation the compilation + * @property {Omit, "delete"|"add">=} sourceTypes source types */ /** diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 5484e1957..e90acd0b9 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -1176,7 +1176,8 @@ class NormalModule extends Module { chunkGraph, runtime, concatenationScope, - codeGenerationResults + codeGenerationResults, + sourceTypes }) { /** @type {Set} */ const runtimeRequirements = new Set(); @@ -1195,7 +1196,7 @@ class NormalModule extends Module { }; const sources = new Map(); - for (const type of this.generator.getTypes(this)) { + for (const type of sourceTypes || chunkGraph.getModuleSourceTypes(this)) { const source = this.error ? new RawSource( "throw new Error(" + JSON.stringify(this.error.message) + ");" diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index cfe6c1ca4..fd88ecaea 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -1669,7 +1669,8 @@ ${defineGetters}` chunkGraph, runtime, concatenationScope, - codeGenerationResults + codeGenerationResults, + sourceTypes: TYPES }); const source = codeGenResult.sources.get("javascript"); const data = codeGenResult.data; diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 361f53c12..68b9404a7 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -425,7 +425,10 @@ class ModuleConcatenationPlugin { for (const chunk of chunkGraph.getModuleChunksIterable( rootModule )) { - const sourceTypes = m.getSourceTypes(); + const sourceTypes = chunkGraph.getChunkModuleSourceTypes( + chunk, + m + ); if (sourceTypes.size === 1) { chunkGraph.disconnectChunkAndModule(chunk, m); } else { diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap index f48063016..90f8b8876 100644 --- a/test/__snapshots__/StatsTestCases.basictest.js.snap +++ b/test/__snapshots__/StatsTestCases.basictest.js.snap @@ -179,7 +179,7 @@ webpack x.x.x compiled successfully in X ms" exports[`StatsTestCases should print correct stats for asset-concat 1`] = ` "asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) -asset bundle.js 12.5 KiB [emitted] (name: main) +asset bundle.js 11.7 KiB [emitted] (name: main) asset static/file.html 12 bytes [emitted] [from: static/file.html] (auxiliary name: main) orphan modules 9.05 KiB [orphan] 7 modules runtime modules 1.06 KiB 2 modules diff --git a/types.d.ts b/types.d.ts index cfaa6d486..504db1793 100644 --- a/types.d.ts +++ b/types.d.ts @@ -814,6 +814,8 @@ declare class ChunkGraph { module: Module, sourceTypes: Set ): void; + getChunkModuleSourceTypes(chunk: Chunk, module: Module): Set; + getModuleSourceTypes(module: Module): Set; getOrderedChunkModulesIterable( chunk: Chunk, comparator: (arg0: Module, arg1: Module) => 0 | 1 | -1 @@ -1249,6 +1251,11 @@ declare interface CodeGenerationContext { * the compilation */ compilation?: Compilation; + + /** + * source types + */ + sourceTypes?: Omit, "delete" | "add">; } declare interface CodeGenerationResult { /**