Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add asset info with * immutable for long term cache-able asset * size for the asset size in bytes * development for devtools * hotModuleReplacement for HMR assets show asset info in stats
- Loading branch information
Showing
16 changed files
with
339 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,6 +104,21 @@ const buildChunkGraph = require("./buildChunkGraph"); | |
* @property {string[]=} trace | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} AssetInfo | ||
* @property {boolean=} immutable true, if the asset can be long term cached forever (contains a hash) | ||
* @property {number=} size size in bytes, only set after asset has been emitted | ||
* @property {boolean=} development true, when asset is only used for development and doesn't count towards user-facing assets | ||
* @property {boolean=} hotModuleReplacement true, when asset ships data for updating an existing application (HMR) | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} Asset | ||
* @property {string} name the filename of the asset | ||
* @property {Source} source source of the asset | ||
* @property {AssetInfo} info info about the asset | ||
*/ | ||
|
||
/** | ||
* @param {Chunk} a first chunk to sort by id | ||
* @param {Chunk} b second chunk to sort by id | ||
|
@@ -446,6 +461,7 @@ class Compilation extends Tapable { | |
this.entries = []; | ||
/** @private @type {{name: string, request: string, module: Module}[]} */ | ||
this._preparedEntrypoints = []; | ||
/** @type {Map<string, Entrypoint>} */ | ||
this.entrypoints = new Map(); | ||
/** @type {Chunk[]} */ | ||
this.chunks = []; | ||
|
@@ -465,6 +481,8 @@ class Compilation extends Tapable { | |
this.additionalChunkAssets = []; | ||
/** @type {CompilationAssets} */ | ||
this.assets = {}; | ||
/** @type {Map<string, AssetInfo>} */ | ||
this.assetsInfo = new Map(); | ||
/** @type {WebpackError[]} */ | ||
this.errors = []; | ||
/** @type {WebpackError[]} */ | ||
|
@@ -1233,6 +1251,7 @@ class Compilation extends Tapable { | |
this.namedChunkGroups.clear(); | ||
this.additionalChunkAssets.length = 0; | ||
this.assets = {}; | ||
this.assetsInfo.clear(); | ||
for (const module of this.modules) { | ||
module.unseal(); | ||
} | ||
|
@@ -1963,13 +1982,101 @@ class Compilation extends Tapable { | |
this.hash = this.fullHash.substr(0, hashDigestLength); | ||
} | ||
|
||
/** | ||
* @param {string} file file name | ||
* @param {Source} source asset source | ||
* @param {AssetInfo} assetInfo extra asset information | ||
* @returns {void} | ||
*/ | ||
emitAsset(file, source, assetInfo = {}) { | ||
if (this.assets[file]) { | ||
if (this.assets[file] !== source) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
LuisRizo
|
||
throw new Error( | ||
`Conflict: Multiple assets emit to the same filename ${file}` | ||
); | ||
} | ||
const oldInfo = this.assetsInfo.get(file); | ||
this.assetsInfo.set(file, Object.assign({}, oldInfo, assetInfo)); | ||
return; | ||
} | ||
this.assets[file] = source; | ||
this.assetsInfo.set(file, assetInfo); | ||
} | ||
|
||
/** | ||
* @param {string} file file name | ||
* @param {Source | function(Source): Source} newSourceOrFunction new asset source or function converting old to new | ||
* @param {AssetInfo | function(AssetInfo | undefined): AssetInfo} assetInfoUpdateOrFunction new asset info or function converting old to new | ||
*/ | ||
updateAsset( | ||
file, | ||
newSourceOrFunction, | ||
assetInfoUpdateOrFunction = undefined | ||
) { | ||
if (!this.assets[file]) { | ||
throw new Error( | ||
`Called Compilation.updateAsset for not existing filename ${file}` | ||
); | ||
} | ||
if (typeof newSourceOrFunction === "function") { | ||
this.assets[file] = newSourceOrFunction(this.assets[file]); | ||
} else { | ||
this.assets[file] = newSourceOrFunction; | ||
} | ||
if (assetInfoUpdateOrFunction !== undefined) { | ||
const oldInfo = this.assetsInfo.get(file); | ||
if (typeof assetInfoUpdateOrFunction === "function") { | ||
this.assetsInfo.set(file, assetInfoUpdateOrFunction(oldInfo || {})); | ||
} else { | ||
this.assetsInfo.set( | ||
file, | ||
Object.assign({}, oldInfo, assetInfoUpdateOrFunction) | ||
); | ||
} | ||
} | ||
} | ||
|
||
getAssets() { | ||
/** @type {Asset[]} */ | ||
const array = []; | ||
for (const assetName of Object.keys(this.assets)) { | ||
if (Object.prototype.hasOwnProperty.call(this.assets, assetName)) { | ||
array.push({ | ||
name: assetName, | ||
source: this.assets[assetName], | ||
info: this.assetsInfo.get(assetName) || {} | ||
}); | ||
} | ||
} | ||
return array; | ||
} | ||
|
||
/** | ||
* @param {string} name the name of the asset | ||
* @returns {Asset | undefined} the asset or undefined when not found | ||
*/ | ||
getAsset(name) { | ||
if (!Object.prototype.hasOwnProperty.call(this.assets, name)) | ||
return undefined; | ||
return { | ||
name, | ||
source: this.assets[name], | ||
info: this.assetsInfo.get(name) || {} | ||
}; | ||
} | ||
|
||
createModuleAssets() { | ||
for (let i = 0; i < this.modules.length; i++) { | ||
const module = this.modules[i]; | ||
if (module.buildInfo.assets) { | ||
const assetsInfo = module.buildInfo.assetsInfo; | ||
for (const assetName of Object.keys(module.buildInfo.assets)) { | ||
const fileName = this.getPath(assetName); | ||
this.assets[fileName] = module.buildInfo.assets[assetName]; | ||
this.emitAsset( | ||
fileName, | ||
module.buildInfo.assets[assetName], | ||
assetsInfo ? assetsInfo.get(assetName) : undefined | ||
); | ||
this.hooks.moduleAsset.call(module, fileName); | ||
} | ||
} | ||
|
@@ -2003,7 +2110,12 @@ class Compilation extends Tapable { | |
const cacheName = fileManifest.identifier; | ||
const usedHash = fileManifest.hash; | ||
filenameTemplate = fileManifest.filenameTemplate; | ||
file = this.getPath(filenameTemplate, fileManifest.pathOptions); | ||
const pathAndInfo = this.getPathWithInfo( | ||
filenameTemplate, | ||
fileManifest.pathOptions | ||
); | ||
file = pathAndInfo.path; | ||
const assetInfo = pathAndInfo.info; | ||
|
||
// check if the same filename was already written by another chunk | ||
const alreadyWritten = alreadyWrittenFiles.get(file); | ||
|
@@ -2051,12 +2163,7 @@ class Compilation extends Tapable { | |
}; | ||
} | ||
} | ||
if (this.assets[file] && this.assets[file] !== source) { | ||
throw new Error( | ||
`Conflict: Multiple assets emit to the same filename ${file}` | ||
); | ||
} | ||
this.assets[file] = source; | ||
this.emitAsset(file, source, assetInfo); | ||
chunk.files.push(file); | ||
this.hooks.chunkAsset.call(chunk, file); | ||
alreadyWrittenFiles.set(file, { | ||
|
@@ -2084,6 +2191,17 @@ class Compilation extends Tapable { | |
return this.mainTemplate.getAssetPath(filename, data); | ||
} | ||
|
||
/** | ||
* @param {string} filename used to get asset path with hash | ||
* @param {TODO=} data // TODO: figure out this param type | ||
* @returns {{ path: string, info: AssetInfo }} interpolated path and asset info | ||
*/ | ||
getPathWithInfo(filename, data) { | ||
data = data || {}; | ||
data.hash = data.hash || this.hash; | ||
return this.mainTemplate.getAssetPathWithInfo(filename, data); | ||
} | ||
|
||
/** | ||
* This function allows you to run another instance of webpack inside of webpack however as | ||
* a child with different settings and configurations (if desired) applied. It copies all hooks, plugins | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
I'm seeing this error from the same source, but imported in two different stylesheets... for an image.