Merge pull request #15515 from webpack/feat/concatenate-assets

add asset modules concatenation
This commit is contained in:
Tobias Koppers 2022-04-04 16:04:20 +02:00 committed by GitHub
commit c38caa2d82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 373 additions and 76 deletions

View File

@ -85,14 +85,17 @@ const getModuleRuntimes = chunks => {
};
/**
* @param {SortableSet<Module>} set the set
* @returns {Map<string, SortableSet<Module>>} modules by source type
* @param {WeakMap<Module, Set<string>> | undefined} sourceTypesByModule sourceTypesByModule
* @returns {function (SortableSet<Module>): Map<string, SortableSet<Module>>} modules by source type
*/
const modulesBySourceType = set => {
const modulesBySourceType = sourceTypesByModule => set => {
/** @type {Map<string, SortableSet<Module>>} */
const map = new Map();
for (const module of set) {
for (const sourceType of module.getSourceTypes()) {
const sourceTypes =
(sourceTypesByModule && sourceTypesByModule.get(module)) ||
module.getSourceTypes();
for (const sourceType of sourceTypes) {
let innerSet = map.get(sourceType);
if (innerSet === undefined) {
innerSet = new SortableSet();
@ -110,6 +113,7 @@ const modulesBySourceType = set => {
}
return map;
};
const defaultModulesBySourceType = modulesBySourceType(undefined);
/** @type {WeakMap<Function, any>} */
const createOrderedArrayFunctionMap = new WeakMap();
@ -201,6 +205,8 @@ class ChunkGraphChunk {
constructor() {
/** @type {SortableSet<Module>} */
this.modules = new SortableSet();
/** @type {WeakMap<Module, Set<string>> | undefined} */
this.sourceTypesByModule = undefined;
/** @type {Map<Module, Entrypoint>} */
this.entryModules = new Map();
/** @type {SortableSet<RuntimeModule>} */
@ -213,6 +219,8 @@ class ChunkGraphChunk {
this.runtimeRequirements = undefined;
/** @type {Set<string>} */
this.runtimeRequirementsInTree = new Set();
this._modulesBySourceType = defaultModulesBySourceType;
}
}
@ -315,6 +323,8 @@ class ChunkGraph {
const cgm = this._getChunkGraphModule(module);
const cgc = this._getChunkGraphChunk(chunk);
cgc.modules.delete(module);
// No need to invalidate cgc._modulesBySourceType because we modified cgc.modules anyway
if (cgc.sourceTypesByModule) cgc.sourceTypesByModule.delete(module);
cgm.chunks.delete(chunk);
}
@ -568,11 +578,84 @@ class ChunkGraph {
getChunkModulesIterableBySourceType(chunk, sourceType) {
const cgc = this._getChunkGraphChunk(chunk);
const modulesWithSourceType = cgc.modules
.getFromUnorderedCache(modulesBySourceType)
.getFromUnorderedCache(cgc._modulesBySourceType)
.get(sourceType);
return modulesWithSourceType;
}
/**
* @param {Chunk} chunk chunk
* @param {Module} module chunk module
* @param {Set<string>} sourceTypes source types
*/
setChunkModuleSourceTypes(chunk, module, sourceTypes) {
const cgc = this._getChunkGraphChunk(chunk);
if (cgc.sourceTypesByModule === undefined) {
cgc.sourceTypesByModule = new WeakMap();
}
cgc.sourceTypesByModule.set(module, sourceTypes);
// Update cgc._modulesBySourceType to invalidate the cache
cgc._modulesBySourceType = modulesBySourceType(cgc.sourceTypesByModule);
}
/**
* @param {Chunk} chunk chunk
* @param {Module} module chunk module
* @returns {Set<string>} 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<string>} source types
*/
getModuleSourceTypes(module) {
return (
this._getOverwrittenModuleSourceTypes(module) || module.getSourceTypes()
);
}
/**
* @param {Module} module module
* @returns {Set<string> | undefined} source types
*/
_getOverwrittenModuleSourceTypes(module) {
let newSet = false;
let sourceTypes;
for (const chunk of this.getModuleChunksIterable(module)) {
const cgc = this._getChunkGraphChunk(chunk);
if (cgc.sourceTypesByModule === undefined) return;
const st = cgc.sourceTypesByModule.get(module);
if (st === undefined) return;
if (!sourceTypes) {
sourceTypes = st;
continue;
} else if (!newSet) {
for (const type of st) {
if (!newSet) {
if (!sourceTypes.has(type)) {
newSet = true;
sourceTypes = new Set(sourceTypes);
sourceTypes.add(type);
}
} else {
sourceTypes.add(type);
}
}
} else {
for (const type of st) sourceTypes.add(type);
}
}
return sourceTypes;
}
/**
* @param {Chunk} chunk the chunk
* @param {function(Module, Module): -1|0|1} comparator comparator function
@ -593,7 +676,7 @@ class ChunkGraph {
getOrderedChunkModulesIterableBySourceType(chunk, sourceType, comparator) {
const cgc = this._getChunkGraphChunk(chunk);
const modulesWithSourceType = cgc.modules
.getFromUnorderedCache(modulesBySourceType)
.getFromUnorderedCache(cgc._modulesBySourceType)
.get(sourceType);
if (modulesWithSourceType === undefined) return undefined;
modulesWithSourceType.sortWith(comparator);
@ -1473,6 +1556,10 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
const graphHash = cgm.graphHashes.provide(runtime, () => {
const hash = createHash(this._hashFunction);
hash.update(`${cgm.id}${this.moduleGraph.isAsync(module)}`);
const sourceTypes = this._getOverwrittenModuleSourceTypes(module);
if (sourceTypes !== undefined) {
for (const type of sourceTypes) hash.update(type);
}
this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime);
return BigInt(`0x${/** @type {string} */ (hash.digest("hex"))}`);
});

View File

@ -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 {ReadonlySet<string>=} sourceTypes source types
*/
/**

View File

@ -1176,7 +1176,8 @@ class NormalModule extends Module {
chunkGraph,
runtime,
concatenationScope,
codeGenerationResults
codeGenerationResults,
sourceTypes
}) {
/** @type {Set<string>} */
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) + ");"

View File

@ -8,6 +8,7 @@
const mimeTypes = require("mime-types");
const path = require("path");
const { RawSource } = require("webpack-sources");
const ConcatenationScope = require("../ConcatenationScope");
const Generator = require("../Generator");
const RuntimeGlobals = require("../RuntimeGlobals");
const createHash = require("../util/createHash");
@ -23,6 +24,7 @@ const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
/** @typedef {import("../NormalModule")} NormalModule */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../util/Hash")} Hash */
@ -145,6 +147,15 @@ class AssetGenerator extends Generator {
).replace(/^\.\//, "");
}
/**
* @param {NormalModule} module module for which the bailout reason should be determined
* @param {ConcatenationBailoutReasonContext} context context
* @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
*/
getConcatenationBailoutReason(module, context) {
return undefined;
}
/**
* @param {NormalModule} module module
* @returns {string} mime type
@ -198,14 +209,21 @@ class AssetGenerator extends Generator {
*/
generate(
module,
{ runtime, chunkGraph, runtimeTemplate, runtimeRequirements, type, getData }
{
runtime,
concatenationScope,
chunkGraph,
runtimeTemplate,
runtimeRequirements,
type,
getData
}
) {
switch (type) {
case "asset":
return module.originalSource();
default: {
runtimeRequirements.add(RuntimeGlobals.module);
let content;
const originalSource = module.originalSource();
if (module.buildInfo.dataUrl) {
let encodedSource;
@ -255,11 +273,7 @@ class AssetGenerator extends Generator {
}
const data = getData();
data.set("url", Buffer.from(encodedSource));
return new RawSource(
`${RuntimeGlobals.module}.exports = ${JSON.stringify(
encodedSource
)};`
);
content = JSON.stringify(encodedSource);
} else {
const assetModuleFilename =
this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
@ -343,9 +357,22 @@ class AssetGenerator extends Generator {
data.set("filename", filename);
data.set("assetInfo", assetInfo);
}
content = assetPath;
}
if (concatenationScope) {
concatenationScope.registerNamespaceExport(
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
);
return new RawSource(
`${RuntimeGlobals.module}.exports = ${assetPath};`
`${runtimeTemplate.supportsConst() ? "const" : "var"} ${
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
} = ${content};`
);
} else {
runtimeRequirements.add(RuntimeGlobals.module);
return new RawSource(
`${RuntimeGlobals.module}.exports = ${content};`
);
}
}

View File

@ -31,6 +31,7 @@ class AssetParser extends Parser {
}
state.module.buildInfo.strict = true;
state.module.buildMeta.exportsType = "default";
state.module.buildMeta.defaultObject = false;
if (typeof this.dataUrlCondition === "function") {
state.module.buildInfo.dataUrl = this.dataUrlCondition(source, {

View File

@ -6,11 +6,13 @@
"use strict";
const { RawSource } = require("webpack-sources");
const ConcatenationScope = require("../ConcatenationScope");
const Generator = require("../Generator");
const RuntimeGlobals = require("../RuntimeGlobals");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
/** @typedef {import("../NormalModule")} NormalModule */
const TYPES = new Set(["javascript"]);
@ -21,9 +23,10 @@ class AssetSourceGenerator extends Generator {
* @param {GenerateContext} generateContext context for generate
* @returns {Source} generated code
*/
generate(module, { chunkGraph, runtimeTemplate, runtimeRequirements }) {
runtimeRequirements.add(RuntimeGlobals.module);
generate(
module,
{ concatenationScope, chunkGraph, runtimeTemplate, runtimeRequirements }
) {
const originalSource = module.originalSource();
if (!originalSource) {
@ -38,9 +41,31 @@ class AssetSourceGenerator extends Generator {
} else {
encodedSource = content.toString("utf-8");
}
return new RawSource(
`${RuntimeGlobals.module}.exports = ${JSON.stringify(encodedSource)};`
);
let sourceContent;
if (concatenationScope) {
concatenationScope.registerNamespaceExport(
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
);
sourceContent = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
} = ${JSON.stringify(encodedSource)};`;
} else {
runtimeRequirements.add(RuntimeGlobals.module);
sourceContent = `${RuntimeGlobals.module}.exports = ${JSON.stringify(
encodedSource
)};`;
}
return new RawSource(sourceContent);
}
/**
* @param {NormalModule} module module for which the bailout reason should be determined
* @param {ConcatenationBailoutReasonContext} context context
* @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
*/
getConcatenationBailoutReason(module, context) {
return undefined;
}
/**

View File

@ -23,6 +23,7 @@ class AssetSourceParser extends Parser {
const { module } = state;
module.buildInfo.strict = true;
module.buildMeta.exportsType = "default";
state.module.buildMeta.defaultObject = false;
return state;
}

View File

@ -1669,7 +1669,8 @@ ${defineGetters}`
chunkGraph,
runtime,
concatenationScope,
codeGenerationResults
codeGenerationResults,
sourceTypes: TYPES
});
const source = codeGenResult.sources.get("javascript");
const data = codeGenResult.data;

View File

@ -425,7 +425,21 @@ class ModuleConcatenationPlugin {
for (const chunk of chunkGraph.getModuleChunksIterable(
rootModule
)) {
chunkGraph.disconnectChunkAndModule(chunk, m);
const sourceTypes = chunkGraph.getChunkModuleSourceTypes(
chunk,
m
);
if (sourceTypes.size === 1) {
chunkGraph.disconnectChunkAndModule(chunk, m);
} else {
const newSourceTypes = new Set(sourceTypes);
newSourceTypes.delete("javascript");
chunkGraph.setChunkModuleSourceTypes(
chunk,
m,
newSourceTypes
);
}
}
}
}

View File

@ -152,25 +152,41 @@ webpack/runtime/make namespace object 274 bytes {main} [code generated]
[no exports]
[used exports unknown]
1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (d0d97703a88fdf5418be)"
1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (64df70d049be415e3e5e)"
`;
exports[`StatsTestCases should print correct stats for asset 1`] = `
"asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main)
asset bundle.js 13.1 KiB [emitted] (name: main)
asset bundle.js 13.4 KiB [emitted] (name: main)
asset static/file.html 12 bytes [emitted] [from: static/file.html] (auxiliary name: main)
runtime modules 1.06 KiB 2 modules
asset modules 9.07 KiB (javascript) 14.6 KiB (asset)
modules by path ./ 8.9 KiB (javascript) 14.6 KiB (asset)
modules by path ./ 9.36 KiB (javascript) 14.6 KiB (asset)
modules by path ./images/ 8.86 KiB (javascript) 14.6 KiB (asset)
./images/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated]
./images/file.svg 915 bytes [built] [code generated]
./images/file.jpg 7.92 KiB [built] [code generated]
./static/file.html 42 bytes (javascript) 12 bytes (asset) [built] [code generated]
modules by mime type text/plain 172 bytes
data:text/plain;base64,szsaAAdsadasdfaf.. 72.2 bytes [built] [code generated]
data:text/plain,asd= 41.4 bytes [built] [code generated]
data:text/plain,XXXXXXXXXXXXXXX.. 58.8 bytes [built] [code generated]
./index.js 339 bytes [built] [code generated]
modules by path ./*.js 427 bytes
./index.js 402 bytes [built] [code generated]
./a.source.js 25 bytes [built] [code generated]
./static/file.html 42 bytes (javascript) 12 bytes (asset) [built] [code generated]
./a.css 41.4 bytes [built] [code generated]
modules by mime type text/plain 172 bytes
data:text/plain;base64,szsaAAdsadasdfaf.. 72.2 bytes [built] [code generated]
data:text/plain,asd= 41.4 bytes [built] [code generated]
data:text/plain,XXXXXXXXXXXXXXX.. 58.8 bytes [built] [code generated]
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 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
cacheable modules 9.6 KiB (javascript) 14.6 KiB (asset)
./index.js + 9 modules 9.52 KiB [built] [code generated]
./images/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated]
./static/file.html 42 bytes (javascript) 12 bytes (asset) [built] [code generated]
webpack x.x.x compiled successfully in X ms"
`;
@ -2565,26 +2581,26 @@ LOG from webpack.FileSystemInfo
exports[`StatsTestCases should print correct stats for real-content-hash 1`] = `
"a-normal:
assets by path *.js 3.23 KiB
asset 9690d063d027560c1900-9690d0.js 2.75 KiB [emitted] [immutable] [minimized] (name: runtime)
asset a6d438a0676f93383d79-a6d438.js 262 bytes [emitted] [immutable] [minimized] (name: lazy)
asset cbb9c74e42f00ada40f7-cbb9c7.js 212 bytes [emitted] [immutable] [minimized] (name: index)
assets by path *.js 3.2 KiB
asset e9785128a82e17f93bc4-e97851.js 2.75 KiB [emitted] [immutable] [minimized] (name: runtime)
asset f96e917feecf51c4fc5c-f96e91.js 232 bytes [emitted] [immutable] [minimized] (name: lazy)
asset f17033ffbf027f2d71b7-f17033.js 212 bytes [emitted] [immutable] [minimized] (name: index)
asset 666f2b8847021ccc7608-666f2b.js 21 bytes [emitted] [immutable] [minimized] (name: a, b)
assets by chunk 20.4 KiB (auxiliary name: lazy)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index)
Entrypoint index 2.96 KiB (5.89 KiB) = 9690d063d027560c1900-9690d0.js 2.75 KiB cbb9c74e42f00ada40f7-cbb9c7.js 212 bytes 1 auxiliary asset
Entrypoint index 2.96 KiB (5.89 KiB) = e9785128a82e17f93bc4-e97851.js 2.75 KiB f17033ffbf027f2d71b7-f17033.js 212 bytes 1 auxiliary asset
Entrypoint a 21 bytes = 666f2b8847021ccc7608-666f2b.js
Entrypoint b 21 bytes = 666f2b8847021ccc7608-666f2b.js
runtime modules 7.28 KiB 9 modules
orphan modules 23 bytes [orphan] 1 module
cacheable modules 514 bytes (javascript) 26.3 KiB (asset)
javascript modules 388 bytes
cacheable modules 556 bytes (javascript) 26.3 KiB (asset)
javascript modules 430 bytes
./a/index.js 150 bytes [built] [code generated]
./a/a.js 22 bytes [built] [code generated]
./a/b.js 66 bytes [built] [code generated]
./a/lazy.js + 1 modules 150 bytes [built] [code generated]
./a/lazy.js + 2 modules 192 bytes [built] [code generated]
asset modules 126 bytes (javascript) 26.3 KiB (asset)
./a/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated]
./a/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated]
@ -2592,26 +2608,26 @@ exports[`StatsTestCases should print correct stats for real-content-hash 1`] = `
a-normal (webpack x.x.x) compiled successfully in X ms
b-normal:
assets by path *.js 3.23 KiB
asset 1eb63f19f5ec7a706311-1eb63f.js 2.75 KiB [emitted] [immutable] [minimized] (name: runtime)
asset a6d438a0676f93383d79-a6d438.js 262 bytes [emitted] [immutable] [minimized] (name: lazy)
asset cbb9c74e42f00ada40f7-cbb9c7.js 212 bytes [emitted] [immutable] [minimized] (name: index)
assets by path *.js 3.2 KiB
asset 165a2ea225896183fda9-165a2e.js 2.75 KiB [emitted] [immutable] [minimized] (name: runtime)
asset f96e917feecf51c4fc5c-f96e91.js 232 bytes [emitted] [immutable] [minimized] (name: lazy)
asset f17033ffbf027f2d71b7-f17033.js 212 bytes [emitted] [immutable] [minimized] (name: index)
asset 666f2b8847021ccc7608-666f2b.js 21 bytes [emitted] [immutable] [minimized] (name: a, b)
assets by chunk 20.4 KiB (auxiliary name: lazy)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index)
Entrypoint index 2.96 KiB (5.89 KiB) = 1eb63f19f5ec7a706311-1eb63f.js 2.75 KiB cbb9c74e42f00ada40f7-cbb9c7.js 212 bytes 1 auxiliary asset
Entrypoint index 2.96 KiB (5.89 KiB) = 165a2ea225896183fda9-165a2e.js 2.75 KiB f17033ffbf027f2d71b7-f17033.js 212 bytes 1 auxiliary asset
Entrypoint a 21 bytes = 666f2b8847021ccc7608-666f2b.js
Entrypoint b 21 bytes = 666f2b8847021ccc7608-666f2b.js
runtime modules 7.28 KiB 9 modules
orphan modules 19 bytes [orphan] 1 module
cacheable modules 469 bytes (javascript) 26.3 KiB (asset)
javascript modules 343 bytes
cacheable modules 511 bytes (javascript) 26.3 KiB (asset)
javascript modules 385 bytes
./b/index.js 109 bytes [built] [code generated]
./b/a.js 22 bytes [built] [code generated]
./b/b.js 66 bytes [built] [code generated]
./b/lazy.js + 1 modules 146 bytes [built] [code generated]
./b/lazy.js + 2 modules 188 bytes [built] [code generated]
asset modules 126 bytes (javascript) 26.3 KiB (asset)
./b/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated]
./b/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated]
@ -2619,30 +2635,30 @@ b-normal:
b-normal (webpack x.x.x) compiled successfully in X ms
a-source-map:
assets by path *.js 3.45 KiB
asset 3c4c8b6907eb902d46e3-3c4c8b.js 2.8 KiB [emitted] [immutable] [minimized] (name: runtime)
sourceMap 3c4c8b6907eb902d46e3-3c4c8b.js.map 14.5 KiB [emitted] [dev] (auxiliary name: runtime)
asset da6ceedb86c86e79a49a-da6cee.js 318 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap da6ceedb86c86e79a49a-da6cee.js.map 401 bytes [emitted] [dev] (auxiliary name: lazy)
asset 9e0ae6ff74fb2c3c821b-9e0ae6.js 268 bytes [emitted] [immutable] [minimized] (name: index)
sourceMap 9e0ae6ff74fb2c3c821b-9e0ae6.js.map 366 bytes [emitted] [dev] (auxiliary name: index)
assets by path *.js 3.42 KiB
asset 1289a35df2e6455ef167-1289a3.js 2.8 KiB [emitted] [immutable] [minimized] (name: runtime)
sourceMap 1289a35df2e6455ef167-1289a3.js.map 14.5 KiB [emitted] [dev] (auxiliary name: runtime)
asset 0a8aef384737d9f64f44-0a8aef.js 288 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap 0a8aef384737d9f64f44-0a8aef.js.map 409 bytes [emitted] [dev] (auxiliary name: lazy)
asset da629d4acf5998c06668-da629d.js 268 bytes [emitted] [immutable] [minimized] (name: index)
sourceMap da629d4acf5998c06668-da629d.js.map 366 bytes [emitted] [dev] (auxiliary name: index)
asset 222c2acc68675174e6b2-222c2a.js 77 bytes [emitted] [immutable] [minimized] (name: a, b)
sourceMap 222c2acc68675174e6b2-222c2a.js.map 254 bytes [emitted] [dev] (auxiliary name: a, b)
assets by chunk 20.4 KiB (auxiliary name: lazy)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index)
Entrypoint index 3.06 KiB (20.7 KiB) = 3c4c8b6907eb902d46e3-3c4c8b.js 2.8 KiB 9e0ae6ff74fb2c3c821b-9e0ae6.js 268 bytes 3 auxiliary assets
Entrypoint index 3.06 KiB (20.7 KiB) = 1289a35df2e6455ef167-1289a3.js 2.8 KiB da629d4acf5998c06668-da629d.js 268 bytes 3 auxiliary assets
Entrypoint a 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset
Entrypoint b 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset
runtime modules 7.28 KiB 9 modules
orphan modules 23 bytes [orphan] 1 module
cacheable modules 514 bytes (javascript) 26.3 KiB (asset)
javascript modules 388 bytes
cacheable modules 556 bytes (javascript) 26.3 KiB (asset)
javascript modules 430 bytes
./a/index.js 150 bytes [built] [code generated]
./a/a.js 22 bytes [built] [code generated]
./a/b.js 66 bytes [built] [code generated]
./a/lazy.js + 1 modules 150 bytes [built] [code generated]
./a/lazy.js + 2 modules 192 bytes [built] [code generated]
asset modules 126 bytes (javascript) 26.3 KiB (asset)
./a/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated]
./a/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated]
@ -2650,30 +2666,30 @@ a-source-map:
a-source-map (webpack x.x.x) compiled successfully in X ms
b-source-map:
assets by path *.js 3.45 KiB
asset 3c4c8b6907eb902d46e3-3c4c8b.js 2.8 KiB [emitted] [immutable] [minimized] (name: runtime)
sourceMap 3c4c8b6907eb902d46e3-3c4c8b.js.map 14.5 KiB [emitted] [dev] (auxiliary name: runtime)
asset da6ceedb86c86e79a49a-da6cee.js 318 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap da6ceedb86c86e79a49a-da6cee.js.map 397 bytes [emitted] [dev] (auxiliary name: lazy)
asset 9e0ae6ff74fb2c3c821b-9e0ae6.js 268 bytes [emitted] [immutable] [minimized] (name: index)
sourceMap 9e0ae6ff74fb2c3c821b-9e0ae6.js.map 323 bytes [emitted] [dev] (auxiliary name: index)
assets by path *.js 3.42 KiB
asset 1289a35df2e6455ef167-1289a3.js 2.8 KiB [emitted] [immutable] [minimized] (name: runtime)
sourceMap 1289a35df2e6455ef167-1289a3.js.map 14.5 KiB [emitted] [dev] (auxiliary name: runtime)
asset 0a8aef384737d9f64f44-0a8aef.js 288 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap 0a8aef384737d9f64f44-0a8aef.js.map 405 bytes [emitted] [dev] (auxiliary name: lazy)
asset da629d4acf5998c06668-da629d.js 268 bytes [emitted] [immutable] [minimized] (name: index)
sourceMap da629d4acf5998c06668-da629d.js.map 323 bytes [emitted] [dev] (auxiliary name: index)
asset 222c2acc68675174e6b2-222c2a.js 77 bytes [emitted] [immutable] [minimized] (name: a, b)
sourceMap 222c2acc68675174e6b2-222c2a.js.map 254 bytes [emitted] [dev] (auxiliary name: a, b)
assets by chunk 20.4 KiB (auxiliary name: lazy)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy)
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index)
Entrypoint index 3.06 KiB (20.7 KiB) = 3c4c8b6907eb902d46e3-3c4c8b.js 2.8 KiB 9e0ae6ff74fb2c3c821b-9e0ae6.js 268 bytes 3 auxiliary assets
Entrypoint index 3.06 KiB (20.7 KiB) = 1289a35df2e6455ef167-1289a3.js 2.8 KiB da629d4acf5998c06668-da629d.js 268 bytes 3 auxiliary assets
Entrypoint a 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset
Entrypoint b 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset
runtime modules 7.28 KiB 9 modules
orphan modules 19 bytes [orphan] 1 module
cacheable modules 469 bytes (javascript) 26.3 KiB (asset)
javascript modules 343 bytes
cacheable modules 511 bytes (javascript) 26.3 KiB (asset)
javascript modules 385 bytes
./b/index.js 109 bytes [built] [code generated]
./b/a.js 22 bytes [built] [code generated]
./b/b.js 66 bytes [built] [code generated]
./b/lazy.js + 1 modules 146 bytes [built] [code generated]
./b/lazy.js + 2 modules 188 bytes [built] [code generated]
asset modules 126 bytes (javascript) 26.3 KiB (asset)
./b/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated]
./b/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated]

View File

@ -0,0 +1 @@
a{}

View File

@ -0,0 +1 @@
const b = 1;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><title>icon-square-small</title><path fill="#FFF" d="M300 .1L565 150v299.9L300 599.8 35 449.9V150z"/><path fill="#8ED6FB" d="M517.7 439.5L308.8 557.8v-92L439 394.1l78.7 45.4zm14.3-12.9V179.4l-76.4 44.1v159l76.4 44.1zM81.5 439.5l208.9 118.2v-92l-130.2-71.6-78.7 45.4zm-14.3-12.9V179.4l76.4 44.1v159l-76.4 44.1zm8.9-263.2L290.4 42.2v89l-137.3 75.5-1.1.6-75.9-43.9zm446.9 0L308.8 42.2v89L446 206.8l1.1.6 75.9-44z"/><path fill="#1C78C0" d="M290.4 444.8L162 374.1V234.2l128.4 74.1v136.5zm18.4 0l128.4-70.6v-140l-128.4 74.1v136.5zM299.6 303zm-129-85l129-70.9L428.5 218l-128.9 74.4-129-74.4z"/></svg>

After

Width:  |  Height:  |  Size: 656 B

View File

@ -0,0 +1,9 @@
import png from "./images/file.png";
import svg from "./images/file.svg";
import jpg from "./images/file.jpg";
import html from "./static/file.html";
import text1 from "data:text/plain;base64,szsaAAdsadasdfafasfasAADas123aasdasd=="
import text2 from "data:text/plain,asd="
import text3 from "data:text/plain,XXXXXXXXXXXXXXXXX" // 17 chars
import css from "./a.css";
import source from "./a.source";

View File

@ -0,0 +1 @@
<div></div>

View File

@ -0,0 +1,35 @@
/** @type {import("../../../").Configuration} */
module.exports = {
mode: "production",
entry: "./index.js",
module: {
rules: [
{
test: /\.(png|jpg|svg)$/,
type: "asset"
},
{
test: /\.html$/,
type: "asset/resource",
generator: {
filename: "static/[name][ext]"
}
},
{
test: /\.css$/,
type: "asset/inline"
},
{
test: /\.source\.js$/,
type: "asset/source"
},
{
mimetype: "text/plain",
type: "asset"
}
]
},
output: {
filename: "bundle.js"
}
};

View File

@ -0,0 +1 @@
a{}

View File

@ -0,0 +1 @@
const b = 1;

View File

@ -2,6 +2,8 @@ import png from "./images/file.png";
import svg from "./images/file.svg";
import jpg from "./images/file.jpg";
import html from "./static/file.html";
import text1 from "data:text/plain;base64,szsaAAdsadasdfafasfasAADas123aasdasd=="
import text2 from "data:text/plain,asd="
import text3 from "data:text/plain,XXXXXXXXXXXXXXXXX" // 17 chars
import text1 from "data:text/plain;base64,szsaAAdsadasdfafasfasAADas123aasdasd==";
import text2 from "data:text/plain,asd=";
import text3 from "data:text/plain,XXXXXXXXXXXXXXXXX"; // 17 chars
import css from "./a.css";
import source from "./a.source";

View File

@ -15,12 +15,23 @@ module.exports = {
filename: "static/[name][ext]"
}
},
{
test: /\.css$/,
type: "asset/inline"
},
{
test: /\.source\.js$/,
type: "asset/source"
},
{
mimetype: "text/plain",
type: "asset"
}
]
},
optimization: {
concatenateModules: false
},
output: {
filename: "bundle.js"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><title>icon-square-small</title><path fill="#FFF" d="M300 .1L565 150v299.9L300 599.8 35 449.9V150z"/><path fill="#8ED6FB" d="M517.7 439.5L308.8 557.8v-92L439 394.1l78.7 45.4zm14.3-12.9V179.4l-76.4 44.1v159l76.4 44.1zM81.5 439.5l208.9 118.2v-92l-130.2-71.6-78.7 45.4zm-14.3-12.9V179.4l76.4 44.1v159l-76.4 44.1zm8.9-263.2L290.4 42.2v89l-137.3 75.5-1.1.6-75.9-43.9zm446.9 0L308.8 42.2v89L446 206.8l1.1.6 75.9-44z"/><path fill="#1C78C0" d="M290.4 444.8L162 374.1V234.2l128.4 74.1v136.5zm18.4 0l128.4-70.6v-140l-128.4 74.1v136.5zM299.6 303zm-129-85l129-70.9L428.5 218l-128.9 74.4-129-74.4z"/></svg>

After

Width:  |  Height:  |  Size: 656 B

View File

@ -0,0 +1,9 @@
import png from "./images/file.png";
import svg from "./images/file.svg";
import jpg from "./images/file.jpg";
it("should generate assets correctly", () => {
expect(png).toMatch(/^data:image\/png;base64,/);
expect(svg).toMatch(/^data:image\/svg\+xml;base64,/);
expect(jpg).toMatch(/\.jpg$/);
});

View File

@ -0,0 +1,9 @@
it("should generate assets correctly", () => {
const png = require("./images/file.png");
const svg = require("./images/file.svg");
const jpg = require("./images/file.jpg");
expect(png).toMatch(/^data:image\/png;base64,/);
expect(svg).toMatch(/^data:image\/svg\+xml;base64,/);
expect(jpg).toMatch(/\.jpg$/);
});

View File

@ -0,0 +1,3 @@
module.exports = function (config) {
return !(config.experiments && config.experiments.cacheUnaffected);
};

View File

@ -0,0 +1,26 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
mode: "development",
cache: {
type: "memory"
},
module: {
rules: [
{
test: /\.png$/,
type: "asset/inline"
},
{
test: /\.jpg$/,
type: "asset/resource"
},
{
test: /\.svg$/,
type: "asset"
}
]
},
optimization: {
concatenateModules: true
}
};

12
types.d.ts vendored
View File

@ -817,6 +817,13 @@ declare class ChunkGraph {
chunk: Chunk,
sourceType: string
): undefined | Iterable<Module>;
setChunkModuleSourceTypes(
chunk: Chunk,
module: Module,
sourceTypes: Set<string>
): void;
getChunkModuleSourceTypes(chunk: Chunk, module: Module): Set<string>;
getModuleSourceTypes(module: Module): Set<string>;
getOrderedChunkModulesIterable(
chunk: Chunk,
comparator: (arg0: Module, arg1: Module) => 0 | 1 | -1
@ -1252,6 +1259,11 @@ declare interface CodeGenerationContext {
* the compilation
*/
compilation?: Compilation;
/**
* source types
*/
sourceTypes?: ReadonlySet<string>;
}
declare interface CodeGenerationResult {
/**