move Module.hash and .renderedHash into ChunkGraph
This commit is contained in:
parent
190a8af6d4
commit
3aa2280498
|
@ -5,13 +5,15 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const validateOptions = require("schema-utils");
|
||||
const { ConcatSource } = require("webpack-sources");
|
||||
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
|
||||
const Template = require("./Template");
|
||||
|
||||
const validateOptions = require("schema-utils");
|
||||
const schema = require("../schemas/plugins/BannerPlugin.json");
|
||||
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
|
||||
const wrapComment = str => {
|
||||
if (!str.includes("\n")) {
|
||||
return Template.toComment(str);
|
||||
|
@ -47,6 +49,10 @@ class BannerPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Compiler} compiler webpack compiler
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const options = this.options;
|
||||
const banner = this.banner;
|
||||
|
|
|
@ -78,7 +78,7 @@ class Chunk {
|
|||
this.rendered = false;
|
||||
/** @type {string=} */
|
||||
this.hash = undefined;
|
||||
/** @type {Object} */
|
||||
/** @type {Record<string, string>} */
|
||||
this.contentHash = Object.create(null);
|
||||
/** @type {string=} */
|
||||
this.renderedHash = undefined;
|
||||
|
@ -359,14 +359,14 @@ class Chunk {
|
|||
this,
|
||||
compareModulesById(compilation.moduleGraph)
|
||||
)) {
|
||||
hash.update(m.hash);
|
||||
hash.update(compilation.chunkGraph.getModuleHash(m));
|
||||
}
|
||||
const entryModules = compilation.chunkGraph.getChunkEntryModulesWithChunkGroupIterable(
|
||||
this
|
||||
);
|
||||
for (const [m, chunkGroup] of entryModules) {
|
||||
hash.update("entry");
|
||||
hash.update(m.hash);
|
||||
hash.update(compilation.chunkGraph.getModuleHash(m));
|
||||
hash.update(chunkGroup.id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@ class ChunkGraphModule {
|
|||
this.chunks = new SortableSet();
|
||||
/** @type {Set<Chunk>} */
|
||||
this.entryInChunks = new Set();
|
||||
/** @type {string} */
|
||||
this.hash = undefined;
|
||||
/** @type {string} */
|
||||
this.renderedHash = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +388,7 @@ class ChunkGraph {
|
|||
chunkModuleIdMap[asyncChunk.id] = array;
|
||||
}
|
||||
array.push(module.id);
|
||||
chunkModuleHashMap[module.id] = module.renderedHash;
|
||||
chunkModuleHashMap[module.id] = this.getRenderedModuleHash(module);
|
||||
}
|
||||
}
|
||||
if (array !== undefined) {
|
||||
|
@ -674,6 +678,36 @@ class ChunkGraph {
|
|||
return cgc.entryModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
* @returns {string} hash
|
||||
*/
|
||||
getModuleHash(module) {
|
||||
const cgm = this._getChunkGraphModule(module);
|
||||
return cgm.hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
* @returns {string} hash
|
||||
*/
|
||||
getRenderedModuleHash(module) {
|
||||
const cgm = this._getChunkGraphModule(module);
|
||||
return cgm.renderedHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
* @param {string} hash the full hash
|
||||
* @param {string} renderedHash the shortened hash for rendering
|
||||
* @returns {void}
|
||||
*/
|
||||
setModuleHashes(module, hash, renderedHash) {
|
||||
const cgm = this._getChunkGraphModule(module);
|
||||
cgm.hash = hash;
|
||||
cgm.renderedHash = renderedHash;
|
||||
}
|
||||
|
||||
// TODO remove in webpack 6
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
|
|
|
@ -105,6 +105,41 @@ const createHash = require("./util/createHash");
|
|||
* @property {AsyncDependenciesBlock[]} blocks
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ChunkPathData
|
||||
* @property {string|number} id
|
||||
* @property {string=} name
|
||||
* @property {string} hash
|
||||
* @property {string} renderedHash
|
||||
* @property {function(number): string=} hashWithLength
|
||||
* @property {(Record<string, string>)=} contentHash
|
||||
* @property {(Record<string, (length: number) => string>)=} contentHashWithLength
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ModulePathData
|
||||
* @property {string|number} id
|
||||
* @property {string} hash
|
||||
* @property {string} renderedHash
|
||||
* @property {function(number): string=} hashWithLength
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} PathData
|
||||
* @property {ChunkGraph=} chunkGraph
|
||||
* @property {string=} hash
|
||||
* @property {function(number): string=} hashWithLength
|
||||
* @property {(Chunk|ChunkPathData)=} chunk
|
||||
* @property {(Module|ModulePathData)=} module
|
||||
* @property {string=} filename
|
||||
* @property {string=} basename
|
||||
* @property {string=} query
|
||||
* @property {string=} contentHashType
|
||||
* @property {string=} contentHash
|
||||
* @property {function(number): string=} contentHashWithLength
|
||||
* @property {boolean=} noChunkHash
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Chunk} a first chunk to sort by id
|
||||
* @param {Chunk} b second chunk to sort by id
|
||||
|
@ -2065,6 +2100,7 @@ class Compilation {
|
|||
}
|
||||
|
||||
createHash() {
|
||||
const chunkGraph = this.chunkGraph;
|
||||
const outputOptions = this.outputOptions;
|
||||
const hashFunction = outputOptions.hashFunction;
|
||||
const hashDigest = outputOptions.hashDigest;
|
||||
|
@ -2092,8 +2128,12 @@ class Compilation {
|
|||
const module = modules[i];
|
||||
const moduleHash = createHash(hashFunction);
|
||||
module.updateHash(moduleHash, this);
|
||||
module.hash = moduleHash.digest(hashDigest);
|
||||
module.renderedHash = module.hash.substr(0, hashDigestLength);
|
||||
const moduleHashDigest = moduleHash.digest(hashDigest);
|
||||
chunkGraph.setModuleHashes(
|
||||
module,
|
||||
moduleHashDigest,
|
||||
moduleHashDigest.substr(0, hashDigestLength)
|
||||
);
|
||||
}
|
||||
// clone needed as sort below is inplace mutation
|
||||
const chunks = this.chunks.slice();
|
||||
|
@ -2151,7 +2191,10 @@ class Compilation {
|
|||
const module = this.modules[i];
|
||||
if (module.buildInfo.assets) {
|
||||
for (const assetName of Object.keys(module.buildInfo.assets)) {
|
||||
const fileName = this.getPath(assetName);
|
||||
const fileName = this.getPath(assetName, {
|
||||
chunkGraph: this.chunkGraph,
|
||||
module
|
||||
});
|
||||
this.assets[fileName] = module.buildInfo.assets[assetName];
|
||||
this.hooks.moduleAsset.call(module, fileName);
|
||||
}
|
||||
|
@ -2261,11 +2304,10 @@ class Compilation {
|
|||
|
||||
/**
|
||||
* @param {string} filename used to get asset path with hash
|
||||
* @param {TODO=} data // TODO: figure out this param type
|
||||
* @param {PathData} data context data
|
||||
* @returns {string} interpolated path
|
||||
*/
|
||||
getPath(filename, data) {
|
||||
data = data || {};
|
||||
data.hash = data.hash || this.hash;
|
||||
return this.mainTemplate.getAssetPath(filename, data);
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ class Compiler {
|
|||
|
||||
this.hooks.emit.callAsync(compilation, err => {
|
||||
if (err) return callback(err);
|
||||
outputPath = compilation.getPath(this.outputPath);
|
||||
outputPath = compilation.getPath(this.outputPath, {});
|
||||
this.outputFileSystem.mkdirp(outputPath, emitFiles);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -212,7 +212,9 @@ module.exports = class HotModuleReplacementPlugin {
|
|||
records.moduleHashs = {};
|
||||
for (const module of compilation.modules) {
|
||||
const identifier = module.identifier();
|
||||
records.moduleHashs[identifier] = module.hash;
|
||||
records.moduleHashs[identifier] = chunkGraph.getModuleHash(
|
||||
module
|
||||
);
|
||||
}
|
||||
records.chunkHashs = {};
|
||||
for (const chunk of compilation.chunks) {
|
||||
|
@ -278,7 +280,7 @@ module.exports = class HotModuleReplacementPlugin {
|
|||
const updatedModules = new Set();
|
||||
for (const module of compilation.modules) {
|
||||
const identifier = module.identifier();
|
||||
const hash = module.hash;
|
||||
const hash = chunkGraph.getModuleHash(module);
|
||||
if (records.moduleHashs[identifier] !== hash) {
|
||||
updatedModules.add(module);
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ class JavascriptModulesPlugin {
|
|||
compareModulesById(moduleGraph)
|
||||
)) {
|
||||
if (typeof m.source === "function") {
|
||||
hash.update(m.hash);
|
||||
hash.update(chunkGraph.getModuleHash(m));
|
||||
}
|
||||
}
|
||||
chunk.contentHash.javascript = hash
|
||||
|
|
|
@ -10,11 +10,17 @@ const path = require("path");
|
|||
const EntryDependency = require("./dependencies/EntryDependency");
|
||||
const { compareModulesById } = require("./util/comparators");
|
||||
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
|
||||
class LibManifestPlugin {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Compiler} compiler webpack compiler
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.emit.tapAsync(
|
||||
"LibManifestPlugin",
|
||||
|
|
|
@ -78,12 +78,6 @@ class Module extends DependenciesBlock {
|
|||
/** @type {number} */
|
||||
this.debugId = debugId++;
|
||||
|
||||
// Hash
|
||||
/** @type {string} */
|
||||
this.hash = undefined;
|
||||
/** @type {string} */
|
||||
this.renderedHash = undefined;
|
||||
|
||||
// Info from Factory
|
||||
/** @type {TODO} */
|
||||
this.resolveOptions = EMPTY_RESOLVE_OPTIONS;
|
||||
|
@ -110,6 +104,25 @@ class Module extends DependenciesBlock {
|
|||
|
||||
// TODO remove in webpack 6
|
||||
// BACKWARD-COMPAT START
|
||||
/**
|
||||
* @returns {string} the hash of the module
|
||||
*/
|
||||
get hash() {
|
||||
return ChunkGraph.getChunkGraphForModule(this, "Module.hash").getModuleHash(
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} the shortened hash of the module
|
||||
*/
|
||||
get renderedHash() {
|
||||
return ChunkGraph.getChunkGraphForModule(
|
||||
this,
|
||||
"Module.renderedHash"
|
||||
).getRenderedModuleHash(this);
|
||||
}
|
||||
|
||||
get profile() {
|
||||
return ModuleGraph.getModuleGraphForModule(
|
||||
this,
|
||||
|
@ -276,9 +289,6 @@ class Module extends DependenciesBlock {
|
|||
* @returns {void}
|
||||
*/
|
||||
disconnect() {
|
||||
this.hash = undefined;
|
||||
this.renderedHash = undefined;
|
||||
|
||||
this.id = null;
|
||||
|
||||
super.disconnect();
|
||||
|
|
|
@ -24,6 +24,7 @@ const createHash = require("./util/createHash");
|
|||
const contextify = require("./util/identifier").contextify;
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("./Compilation")} Compilation */
|
||||
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
|
||||
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
|
||||
|
@ -494,13 +495,14 @@ class NormalModule extends Module {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @param {DependencyTemplates} dependencyTemplates dependency templates
|
||||
* @returns {string} hash
|
||||
*/
|
||||
getHashDigest(dependencyTemplates) {
|
||||
// TODO webpack 5 refactor
|
||||
let dtHash = dependencyTemplates.getHash();
|
||||
return `${this.hash}-${dtHash}`;
|
||||
getHashDigest(chunkGraph, dependencyTemplates) {
|
||||
const hash = chunkGraph.getModuleHash(this);
|
||||
const dtHash = dependencyTemplates.getHash();
|
||||
return `${hash}-${dtHash}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -511,9 +513,10 @@ class NormalModule extends Module {
|
|||
dependencyTemplates,
|
||||
runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph,
|
||||
type = "javascript"
|
||||
}) {
|
||||
const hashDigest = this.getHashDigest(dependencyTemplates);
|
||||
const hashDigest = this.getHashDigest(chunkGraph, dependencyTemplates);
|
||||
const cacheEntry = this._cachedSources.get(type);
|
||||
if (cacheEntry !== undefined && cacheEntry.hash === hashDigest) {
|
||||
// We can reuse the cached source
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const validateOptions = require("schema-utils");
|
||||
const { ConcatSource, RawSource } = require("webpack-sources");
|
||||
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
|
||||
const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin");
|
||||
const createHash = require("./util/createHash");
|
||||
|
||||
const validateOptions = require("schema-utils");
|
||||
const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json");
|
||||
|
||||
/** @typedef {import("./Chunk")} Chunk */
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
|
||||
const assetsCache = new WeakMap();
|
||||
|
||||
const getTaskForFile = (file, chunk, options, compilation) => {
|
||||
|
@ -65,6 +68,10 @@ class SourceMapDevToolPlugin {
|
|||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Compiler} compiler webpack compiler
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const sourceMapFilename = this.sourceMapFilename;
|
||||
const sourceMappingURLComment = this.sourceMappingURLComment;
|
||||
|
@ -84,11 +91,13 @@ class SourceMapDevToolPlugin {
|
|||
new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation);
|
||||
|
||||
compilation.hooks.afterOptimizeChunkAssets.tap(
|
||||
{
|
||||
/** @type {TODO} */ ({
|
||||
name: "SourceMapDevToolPlugin",
|
||||
context: true
|
||||
},
|
||||
(context, chunks) => {
|
||||
}),
|
||||
/** @type {TODO} */
|
||||
/** @param {any} context @param {Chunk[]} chunks @returns {void} */
|
||||
((context, chunks) => {
|
||||
const moduleToSourceNameMapping = new Map();
|
||||
const reportProgress =
|
||||
context && context.reportProgress
|
||||
|
@ -281,7 +290,7 @@ class SourceMapDevToolPlugin {
|
|||
}
|
||||
});
|
||||
reportProgress(1.0);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ const HotUpdateChunk = require("./HotUpdateChunk");
|
|||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("./Chunk")} Chunk */
|
||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("./Compilation").PathData} PathData */
|
||||
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
|
||||
/** @typedef {import("./Module")} Module */
|
||||
/** @typedef {import("./ModuleGraph")} ModuleGraph */
|
||||
|
@ -48,7 +49,7 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
|
|||
* @typedef {Object} RenderManifestEntry
|
||||
* @property {function(): Source} render
|
||||
* @property {string=} filenameTemplate
|
||||
* @property {TODO=} pathOptions
|
||||
* @property {PathData=} pathOptions
|
||||
* @property {TODO} identifier
|
||||
* @property {TODO=} hash
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const Module = require("./Module");
|
||||
|
||||
/** @typedef {import("./Compilation").PathData} PathData */
|
||||
|
||||
const REGEXP_HASH = /\[hash(?::(\d+))?\]/gi,
|
||||
REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/gi,
|
||||
REGEXP_MODULEHASH = /\[modulehash(?::(\d+))?\]/gi,
|
||||
|
@ -53,25 +57,40 @@ const getReplacer = (value, allowEmpty) => {
|
|||
return fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string | function(PathData): string} path the raw path
|
||||
* @param {PathData} data context data
|
||||
* @returns {string} the interpolated path
|
||||
*/
|
||||
const replacePathVariables = (path, data) => {
|
||||
const chunkGraph = data.chunkGraph;
|
||||
const chunk = data.chunk;
|
||||
const chunkId = chunk && chunk.id;
|
||||
const chunkName = chunk && (chunk.name || chunk.id);
|
||||
const chunkHash = chunk && (chunk.renderedHash || chunk.hash);
|
||||
const chunkHashWithLength = chunk && chunk.hashWithLength;
|
||||
const chunkHashWithLength =
|
||||
chunk && "hashWithLength" in chunk && chunk.hashWithLength;
|
||||
const contentHashType = data.contentHashType;
|
||||
const contentHash =
|
||||
(chunk && chunk.contentHash && chunk.contentHash[contentHashType]) ||
|
||||
data.contentHash;
|
||||
const contentHashWithLength =
|
||||
data.contentHash ||
|
||||
(chunk &&
|
||||
chunk.contentHashWithLength &&
|
||||
chunk.contentHashWithLength[contentHashType]) ||
|
||||
data.contentHashWithLength;
|
||||
contentHashType &&
|
||||
chunk.contentHash &&
|
||||
chunk.contentHash[contentHashType]);
|
||||
const contentHashWithLength =
|
||||
data.contentHashWithLength ||
|
||||
(chunk && "contentHashWithLength" in chunk
|
||||
? chunk.contentHashWithLength[contentHashType]
|
||||
: undefined);
|
||||
const module = data.module;
|
||||
const moduleId = module && module.id;
|
||||
const moduleHash = module && (module.renderedHash || module.hash);
|
||||
const moduleHashWithLength = module && module.hashWithLength;
|
||||
const moduleHash =
|
||||
module &&
|
||||
(module instanceof Module
|
||||
? chunkGraph.getRenderedModuleHash(module)
|
||||
: module.renderedHash || module.hash);
|
||||
const moduleHashWithLength =
|
||||
module && "hashWithLength" in module && module.hashWithLength;
|
||||
|
||||
if (typeof path === "function") {
|
||||
path = path(data);
|
||||
|
|
|
@ -375,18 +375,14 @@ class WasmMainTemplatePlugin {
|
|||
mainTemplate.hooks.hashForChunk.tap(
|
||||
"WasmMainTemplatePlugin",
|
||||
(hash, chunk) => {
|
||||
const chunkModuleMaps = this.compilation.chunkGraph.getChunkModuleMaps(
|
||||
chunk,
|
||||
m => m.type.startsWith("webassembly")
|
||||
const chunkGraph = this.compilation.chunkGraph;
|
||||
const chunkModuleMaps = chunkGraph.getChunkModuleMaps(chunk, m =>
|
||||
m.type.startsWith("webassembly")
|
||||
);
|
||||
hash.update(JSON.stringify(chunkModuleMaps.id));
|
||||
const wasmModules = getAllWasmModules(
|
||||
moduleGraph,
|
||||
this.compilation.chunkGraph,
|
||||
chunk
|
||||
);
|
||||
const wasmModules = getAllWasmModules(moduleGraph, chunkGraph, chunk);
|
||||
for (const module of wasmModules) {
|
||||
hash.update(module.hash);
|
||||
hash.update(chunkGraph.getModuleHash(module));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -92,15 +92,16 @@ class WebAssemblyModulesPlugin {
|
|||
dependencyTemplates,
|
||||
runtimeTemplate: compilation.runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
chunkGraph
|
||||
}
|
||||
),
|
||||
filenameTemplate,
|
||||
pathOptions: {
|
||||
chunkGraph,
|
||||
module
|
||||
},
|
||||
identifier: `webassemblyModule${module.id}`,
|
||||
hash: module.hash
|
||||
hash: chunkGraph.getModuleHash(module)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue