|
|
|
@ -24,12 +24,16 @@ const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
|
|
|
|
|
/** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */
|
|
|
|
|
/** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */
|
|
|
|
|
/** @typedef {import("../Compilation")} Compilation */
|
|
|
|
|
/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
|
|
|
|
|
/** @typedef {import("../Compilation").InterpolatedPathAndAssetInfo} InterpolatedPathAndAssetInfo */
|
|
|
|
|
/** @typedef {import("../Compiler")} Compiler */
|
|
|
|
|
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
|
|
|
|
|
/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
|
|
|
|
|
/** @typedef {import("../Module")} Module */
|
|
|
|
|
/** @typedef {import("../Module").BuildInfo} BuildInfo */
|
|
|
|
|
/** @typedef {import("../Module").BuildMeta} BuildMeta */
|
|
|
|
|
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
|
|
|
|
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
|
|
|
/** @typedef {import("../NormalModule")} NormalModule */
|
|
|
|
|
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
|
|
|
|
|
/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */
|
|
|
|
@ -164,25 +168,44 @@ const decodeDataUriContent = (encoding, content) => {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const NO_TYPES = new Set();
|
|
|
|
|
const ASSET_TYPES = new Set([ASSET_MODULE_TYPE]);
|
|
|
|
|
const JS_TYPES = new Set(["javascript"]);
|
|
|
|
|
const JS_AND_ASSET_TYPES = new Set(["javascript", ASSET_MODULE_TYPE]);
|
|
|
|
|
const CSS_TYPES = new Set(["css-url"]);
|
|
|
|
|
const CSS_AND_JS_TYPES = new Set(["javascript", "css-url"]);
|
|
|
|
|
const JS_AND_ASSET_TYPES = new Set([ASSET_MODULE_TYPE, "javascript"]);
|
|
|
|
|
const CSS_AND_ASSET_TYPES = new Set([ASSET_MODULE_TYPE, "css-url"]);
|
|
|
|
|
const JS_AND_CSS_AND_ASSET_TYPES = new Set([
|
|
|
|
|
ASSET_MODULE_TYPE,
|
|
|
|
|
"javascript",
|
|
|
|
|
"css-url"
|
|
|
|
|
]);
|
|
|
|
|
const DEFAULT_ENCODING = "base64";
|
|
|
|
|
|
|
|
|
|
class AssetGenerator extends Generator {
|
|
|
|
|
/**
|
|
|
|
|
* @param {ModuleGraph} moduleGraph the module graph
|
|
|
|
|
* @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url
|
|
|
|
|
* @param {AssetModuleFilename=} filename override for output.assetModuleFilename
|
|
|
|
|
* @param {RawPublicPath=} publicPath override for output.assetModulePublicPath
|
|
|
|
|
* @param {AssetModuleOutputPath=} outputPath the output path for the emitted file which is not included in the runtime import
|
|
|
|
|
* @param {boolean=} emit generate output asset
|
|
|
|
|
*/
|
|
|
|
|
constructor(dataUrlOptions, filename, publicPath, outputPath, emit) {
|
|
|
|
|
constructor(
|
|
|
|
|
moduleGraph,
|
|
|
|
|
dataUrlOptions,
|
|
|
|
|
filename,
|
|
|
|
|
publicPath,
|
|
|
|
|
outputPath,
|
|
|
|
|
emit
|
|
|
|
|
) {
|
|
|
|
|
super();
|
|
|
|
|
this.dataUrlOptions = dataUrlOptions;
|
|
|
|
|
this.filename = filename;
|
|
|
|
|
this.publicPath = publicPath;
|
|
|
|
|
this.outputPath = outputPath;
|
|
|
|
|
this.emit = emit;
|
|
|
|
|
this._moduleGraph = moduleGraph;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -259,208 +282,368 @@ class AssetGenerator extends Generator {
|
|
|
|
|
return /** @type {string} */ (mimeType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {NormalModule} module module for which the code should be generated
|
|
|
|
|
* @returns {string} DataURI
|
|
|
|
|
*/
|
|
|
|
|
generateDataUri(module) {
|
|
|
|
|
const source = /** @type {Source} */ (module.originalSource());
|
|
|
|
|
|
|
|
|
|
let encodedSource;
|
|
|
|
|
|
|
|
|
|
if (typeof this.dataUrlOptions === "function") {
|
|
|
|
|
encodedSource = this.dataUrlOptions.call(null, source.source(), {
|
|
|
|
|
filename: module.matchResource || module.resource,
|
|
|
|
|
module
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
/** @type {"base64" | false | undefined} */
|
|
|
|
|
let encoding =
|
|
|
|
|
/** @type {AssetGeneratorDataUrlOptions} */
|
|
|
|
|
(this.dataUrlOptions).encoding;
|
|
|
|
|
if (
|
|
|
|
|
encoding === undefined &&
|
|
|
|
|
module.resourceResolveData &&
|
|
|
|
|
module.resourceResolveData.encoding !== undefined
|
|
|
|
|
) {
|
|
|
|
|
encoding = module.resourceResolveData.encoding;
|
|
|
|
|
}
|
|
|
|
|
if (encoding === undefined) {
|
|
|
|
|
encoding = DEFAULT_ENCODING;
|
|
|
|
|
}
|
|
|
|
|
const mimeType = this.getMimeType(module);
|
|
|
|
|
|
|
|
|
|
let encodedContent;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
module.resourceResolveData &&
|
|
|
|
|
module.resourceResolveData.encoding === encoding &&
|
|
|
|
|
decodeDataUriContent(
|
|
|
|
|
module.resourceResolveData.encoding,
|
|
|
|
|
module.resourceResolveData.encodedContent
|
|
|
|
|
).equals(source.buffer())
|
|
|
|
|
) {
|
|
|
|
|
encodedContent = module.resourceResolveData.encodedContent;
|
|
|
|
|
} else {
|
|
|
|
|
encodedContent = encodeDataUri(encoding, source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
encodedSource = `data:${mimeType}${
|
|
|
|
|
encoding ? `;${encoding}` : ""
|
|
|
|
|
},${encodedContent}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return encodedSource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @param {NormalModule} module module for which the code should be generated
|
|
|
|
|
* @param {GenerateContext} generateContext context for generate
|
|
|
|
|
* @returns {string} the full content hash
|
|
|
|
|
*/
|
|
|
|
|
_getFullContentHash(module, { runtimeTemplate }) {
|
|
|
|
|
const hash = createHash(
|
|
|
|
|
/** @type {Algorithm} */
|
|
|
|
|
(runtimeTemplate.outputOptions.hashFunction)
|
|
|
|
|
);
|
|
|
|
|
if (runtimeTemplate.outputOptions.hashSalt) {
|
|
|
|
|
hash.update(runtimeTemplate.outputOptions.hashSalt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hash.update(/** @type {Source} */ (module.originalSource()).buffer());
|
|
|
|
|
|
|
|
|
|
return /** @type {string} */ (
|
|
|
|
|
hash.digest(runtimeTemplate.outputOptions.hashDigest)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @param {string} fullContentHash the full content hash
|
|
|
|
|
* @param {GenerateContext} generateContext context for generate
|
|
|
|
|
* @returns {string} the content hash
|
|
|
|
|
*/
|
|
|
|
|
_getContentHash(fullContentHash, generateContext) {
|
|
|
|
|
return nonNumericOnlyHash(
|
|
|
|
|
fullContentHash,
|
|
|
|
|
/** @type {number} */
|
|
|
|
|
(generateContext.runtimeTemplate.outputOptions.hashDigestLength)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @param {NormalModule} module module for which the code should be generated
|
|
|
|
|
* @param {GenerateContext} generateContext context for generate
|
|
|
|
|
* @param {string} contentHash the content hash
|
|
|
|
|
* @returns {{ filename: string, originalFilename: string, assetInfo: AssetInfo }} info
|
|
|
|
|
*/
|
|
|
|
|
_getFilenameWithInfo(
|
|
|
|
|
module,
|
|
|
|
|
{ runtime, runtimeTemplate, chunkGraph },
|
|
|
|
|
contentHash
|
|
|
|
|
) {
|
|
|
|
|
const assetModuleFilename =
|
|
|
|
|
this.filename ||
|
|
|
|
|
/** @type {AssetModuleFilename} */
|
|
|
|
|
(runtimeTemplate.outputOptions.assetModuleFilename);
|
|
|
|
|
|
|
|
|
|
const sourceFilename = this.getSourceFileName(module, runtimeTemplate);
|
|
|
|
|
let { path: filename, info: assetInfo } =
|
|
|
|
|
runtimeTemplate.compilation.getAssetPathWithInfo(assetModuleFilename, {
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const originalFilename = filename;
|
|
|
|
|
|
|
|
|
|
if (this.outputPath) {
|
|
|
|
|
const { path: outputPath, info } =
|
|
|
|
|
runtimeTemplate.compilation.getAssetPathWithInfo(this.outputPath, {
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
});
|
|
|
|
|
filename = path.posix.join(outputPath, filename);
|
|
|
|
|
assetInfo = mergeAssetInfo(assetInfo, info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { originalFilename, filename, assetInfo };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @param {NormalModule} module module for which the code should be generated
|
|
|
|
|
* @param {GenerateContext} generateContext context for generate
|
|
|
|
|
* @param {string} filename the filename
|
|
|
|
|
* @param {AssetInfo} assetInfo the asset info
|
|
|
|
|
* @param {string} contentHash the content hash
|
|
|
|
|
* @returns {{ assetPath: string, assetInfo: AssetInfo }} asset path and info
|
|
|
|
|
*/
|
|
|
|
|
_getAssetPathWithInfo(
|
|
|
|
|
module,
|
|
|
|
|
{ runtimeTemplate, runtime, chunkGraph, type, runtimeRequirements },
|
|
|
|
|
filename,
|
|
|
|
|
assetInfo,
|
|
|
|
|
contentHash
|
|
|
|
|
) {
|
|
|
|
|
const sourceFilename = this.getSourceFileName(module, runtimeTemplate);
|
|
|
|
|
|
|
|
|
|
let assetPath;
|
|
|
|
|
|
|
|
|
|
if (this.publicPath !== undefined && type === "javascript") {
|
|
|
|
|
const { path, info } = runtimeTemplate.compilation.getAssetPathWithInfo(
|
|
|
|
|
this.publicPath,
|
|
|
|
|
{
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
assetInfo = mergeAssetInfo(assetInfo, info);
|
|
|
|
|
assetPath = JSON.stringify(path + filename);
|
|
|
|
|
} else if (this.publicPath !== undefined && type === "css-url") {
|
|
|
|
|
const { path, info } = runtimeTemplate.compilation.getAssetPathWithInfo(
|
|
|
|
|
this.publicPath,
|
|
|
|
|
{
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
assetInfo = mergeAssetInfo(assetInfo, info);
|
|
|
|
|
assetPath = path + filename;
|
|
|
|
|
} else if (type === "javascript") {
|
|
|
|
|
// add __webpack_require__.p
|
|
|
|
|
runtimeRequirements.add(RuntimeGlobals.publicPath);
|
|
|
|
|
assetPath = runtimeTemplate.concatenation(
|
|
|
|
|
{ expr: RuntimeGlobals.publicPath },
|
|
|
|
|
filename
|
|
|
|
|
);
|
|
|
|
|
} else if (type === "css-url") {
|
|
|
|
|
const compilation = runtimeTemplate.compilation;
|
|
|
|
|
const path =
|
|
|
|
|
compilation.outputOptions.publicPath === "auto"
|
|
|
|
|
? CssUrlDependency.PUBLIC_PATH_AUTO
|
|
|
|
|
: compilation.getAssetPath(
|
|
|
|
|
/** @type {TemplatePath} */
|
|
|
|
|
(compilation.outputOptions.publicPath),
|
|
|
|
|
{
|
|
|
|
|
hash: compilation.hash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assetPath = path + filename;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assetInfo = { sourceFilename, ...assetInfo };
|
|
|
|
|
|
|
|
|
|
return { assetPath, assetInfo };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {NormalModule} module module for which the code should be generated
|
|
|
|
|
* @param {GenerateContext} generateContext context for generate
|
|
|
|
|
* @returns {Source} generated code
|
|
|
|
|
*/
|
|
|
|
|
generate(
|
|
|
|
|
module,
|
|
|
|
|
{
|
|
|
|
|
runtime,
|
|
|
|
|
concatenationScope,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
generate(module, generateContext) {
|
|
|
|
|
const {
|
|
|
|
|
type,
|
|
|
|
|
getData,
|
|
|
|
|
runtimeTemplate,
|
|
|
|
|
runtimeRequirements,
|
|
|
|
|
type,
|
|
|
|
|
getData
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case ASSET_MODULE_TYPE:
|
|
|
|
|
return /** @type {Source} */ (module.originalSource());
|
|
|
|
|
default: {
|
|
|
|
|
let content;
|
|
|
|
|
const originalSource = /** @type {Source} */ (module.originalSource());
|
|
|
|
|
if (
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).dataUrl
|
|
|
|
|
) {
|
|
|
|
|
let encodedSource;
|
|
|
|
|
if (typeof this.dataUrlOptions === "function") {
|
|
|
|
|
encodedSource = this.dataUrlOptions.call(
|
|
|
|
|
null,
|
|
|
|
|
originalSource.source(),
|
|
|
|
|
{
|
|
|
|
|
filename: module.matchResource || module.resource,
|
|
|
|
|
module
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
/** @type {"base64" | false | undefined} */
|
|
|
|
|
let encoding =
|
|
|
|
|
/** @type {AssetGeneratorDataUrlOptions} */
|
|
|
|
|
(this.dataUrlOptions).encoding;
|
|
|
|
|
if (
|
|
|
|
|
encoding === undefined &&
|
|
|
|
|
module.resourceResolveData &&
|
|
|
|
|
module.resourceResolveData.encoding !== undefined
|
|
|
|
|
) {
|
|
|
|
|
encoding = module.resourceResolveData.encoding;
|
|
|
|
|
}
|
|
|
|
|
if (encoding === undefined) {
|
|
|
|
|
encoding = DEFAULT_ENCODING;
|
|
|
|
|
}
|
|
|
|
|
const mimeType = this.getMimeType(module);
|
|
|
|
|
concatenationScope
|
|
|
|
|
} = generateContext;
|
|
|
|
|
|
|
|
|
|
let encodedContent;
|
|
|
|
|
let content;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
module.resourceResolveData &&
|
|
|
|
|
module.resourceResolveData.encoding === encoding &&
|
|
|
|
|
decodeDataUriContent(
|
|
|
|
|
module.resourceResolveData.encoding,
|
|
|
|
|
module.resourceResolveData.encodedContent
|
|
|
|
|
).equals(originalSource.buffer())
|
|
|
|
|
) {
|
|
|
|
|
encodedContent = module.resourceResolveData.encodedContent;
|
|
|
|
|
} else {
|
|
|
|
|
encodedContent = encodeDataUri(encoding, originalSource);
|
|
|
|
|
}
|
|
|
|
|
const needContent = type === "javascript" || type === "css-url";
|
|
|
|
|
|
|
|
|
|
encodedSource = `data:${mimeType}${
|
|
|
|
|
encoding ? `;${encoding}` : ""
|
|
|
|
|
},${encodedContent}`;
|
|
|
|
|
}
|
|
|
|
|
const data =
|
|
|
|
|
/** @type {NonNullable<GenerateContext["getData"]>} */
|
|
|
|
|
(getData)();
|
|
|
|
|
data.set("url", Buffer.from(encodedSource));
|
|
|
|
|
content = JSON.stringify(encodedSource);
|
|
|
|
|
} else {
|
|
|
|
|
const assetModuleFilename =
|
|
|
|
|
this.filename ||
|
|
|
|
|
/** @type {AssetModuleFilename} */
|
|
|
|
|
(runtimeTemplate.outputOptions.assetModuleFilename);
|
|
|
|
|
const hash = createHash(
|
|
|
|
|
/** @type {Algorithm} */
|
|
|
|
|
(runtimeTemplate.outputOptions.hashFunction)
|
|
|
|
|
);
|
|
|
|
|
if (runtimeTemplate.outputOptions.hashSalt) {
|
|
|
|
|
hash.update(runtimeTemplate.outputOptions.hashSalt);
|
|
|
|
|
}
|
|
|
|
|
hash.update(originalSource.buffer());
|
|
|
|
|
const fullHash = /** @type {string} */ (
|
|
|
|
|
hash.digest(runtimeTemplate.outputOptions.hashDigest)
|
|
|
|
|
);
|
|
|
|
|
const contentHash = nonNumericOnlyHash(
|
|
|
|
|
fullHash,
|
|
|
|
|
/** @type {number} */
|
|
|
|
|
(runtimeTemplate.outputOptions.hashDigestLength)
|
|
|
|
|
);
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).fullContentHash = fullHash;
|
|
|
|
|
const sourceFilename = this.getSourceFileName(
|
|
|
|
|
module,
|
|
|
|
|
runtimeTemplate
|
|
|
|
|
);
|
|
|
|
|
let { path: filename, info: assetInfo } =
|
|
|
|
|
runtimeTemplate.compilation.getAssetPathWithInfo(
|
|
|
|
|
assetModuleFilename,
|
|
|
|
|
{
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
let assetPath;
|
|
|
|
|
let assetPathForCss;
|
|
|
|
|
if (this.publicPath !== undefined) {
|
|
|
|
|
const { path, info } =
|
|
|
|
|
runtimeTemplate.compilation.getAssetPathWithInfo(
|
|
|
|
|
this.publicPath,
|
|
|
|
|
{
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
assetInfo = mergeAssetInfo(assetInfo, info);
|
|
|
|
|
assetPath = JSON.stringify(path + filename);
|
|
|
|
|
assetPathForCss = path + filename;
|
|
|
|
|
} else {
|
|
|
|
|
runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p
|
|
|
|
|
assetPath = runtimeTemplate.concatenation(
|
|
|
|
|
{ expr: RuntimeGlobals.publicPath },
|
|
|
|
|
filename
|
|
|
|
|
);
|
|
|
|
|
const compilation = runtimeTemplate.compilation;
|
|
|
|
|
const path =
|
|
|
|
|
compilation.outputOptions.publicPath === "auto"
|
|
|
|
|
? CssUrlDependency.PUBLIC_PATH_AUTO
|
|
|
|
|
: compilation.getAssetPath(
|
|
|
|
|
/** @type {TemplatePath} */
|
|
|
|
|
(compilation.outputOptions.publicPath),
|
|
|
|
|
{
|
|
|
|
|
hash: compilation.hash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
assetPathForCss = path + filename;
|
|
|
|
|
}
|
|
|
|
|
assetInfo = {
|
|
|
|
|
sourceFilename,
|
|
|
|
|
...assetInfo
|
|
|
|
|
};
|
|
|
|
|
if (this.outputPath) {
|
|
|
|
|
const { path: outputPath, info } =
|
|
|
|
|
runtimeTemplate.compilation.getAssetPathWithInfo(
|
|
|
|
|
this.outputPath,
|
|
|
|
|
{
|
|
|
|
|
module,
|
|
|
|
|
runtime,
|
|
|
|
|
filename: sourceFilename,
|
|
|
|
|
chunkGraph,
|
|
|
|
|
contentHash
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
assetInfo = mergeAssetInfo(assetInfo, info);
|
|
|
|
|
filename = path.posix.join(outputPath, filename);
|
|
|
|
|
}
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).filename = filename;
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).assetInfo = assetInfo;
|
|
|
|
|
if (getData) {
|
|
|
|
|
// Due to code generation caching module.buildInfo.XXX can't used to store such information
|
|
|
|
|
// It need to be stored in the code generation results instead, where it's cached too
|
|
|
|
|
// TODO webpack 6 For back-compat reasons we also store in on module.buildInfo
|
|
|
|
|
const data = getData();
|
|
|
|
|
data.set("fullContentHash", fullHash);
|
|
|
|
|
data.set("filename", filename);
|
|
|
|
|
data.set("assetInfo", assetInfo);
|
|
|
|
|
data.set("assetPathForCss", assetPathForCss);
|
|
|
|
|
}
|
|
|
|
|
content = assetPath;
|
|
|
|
|
const data = getData
|
|
|
|
|
? /** @type {GenerateContext["getData"]} */
|
|
|
|
|
(getData)()
|
|
|
|
|
: undefined;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).dataUrl &&
|
|
|
|
|
needContent
|
|
|
|
|
) {
|
|
|
|
|
if (data && data.has("url")) {
|
|
|
|
|
content = data.get("url");
|
|
|
|
|
} else {
|
|
|
|
|
const encodedSource = this.generateDataUri(module);
|
|
|
|
|
content = JSON.stringify(encodedSource);
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
data.set("url", {
|
|
|
|
|
[type]: Buffer.from(encodedSource)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (concatenationScope) {
|
|
|
|
|
concatenationScope.registerNamespaceExport(
|
|
|
|
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
|
|
|
|
);
|
|
|
|
|
return new RawSource(
|
|
|
|
|
`${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
|
|
|
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
|
|
|
|
} = ${content};`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
runtimeRequirements.add(RuntimeGlobals.module);
|
|
|
|
|
return new RawSource(`${RuntimeGlobals.module}.exports = ${content};`);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/** @type {string} */
|
|
|
|
|
let fullHash;
|
|
|
|
|
|
|
|
|
|
if (data && data.has("fullContentHash")) {
|
|
|
|
|
fullHash = data.get("fullContentHash");
|
|
|
|
|
} else {
|
|
|
|
|
fullHash = this._getFullContentHash(module, generateContext);
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
data.set("fullContentHash", fullHash);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(/** @type {BuildInfo} */ (module.buildInfo).fullContentHash)) {
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).fullContentHash = fullHash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @type {string} */
|
|
|
|
|
let contentHash;
|
|
|
|
|
|
|
|
|
|
if (data && data.has("contentHash")) {
|
|
|
|
|
contentHash = data.get("contentHash");
|
|
|
|
|
} else {
|
|
|
|
|
contentHash = this._getContentHash(fullHash, generateContext);
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
data.set("contentHash", contentHash);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let originalFilename;
|
|
|
|
|
let filename;
|
|
|
|
|
let assetInfo = {};
|
|
|
|
|
|
|
|
|
|
if (data && data.has("originalFilename")) {
|
|
|
|
|
originalFilename = data.get("originalFilename");
|
|
|
|
|
} else {
|
|
|
|
|
({ originalFilename, filename, assetInfo } = this._getFilenameWithInfo(
|
|
|
|
|
module,
|
|
|
|
|
generateContext,
|
|
|
|
|
contentHash
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
data.set("filename", filename);
|
|
|
|
|
data.set("assetInfo", assetInfo);
|
|
|
|
|
data.set("filenameWithInfo", originalFilename);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assetInfo =
|
|
|
|
|
data && data.has("assetInfo") ? data.get("assetInfo") : assetInfo;
|
|
|
|
|
|
|
|
|
|
/** @type {string} */
|
|
|
|
|
let assetPath;
|
|
|
|
|
|
|
|
|
|
if (type === "javascript" || type === "css-url") {
|
|
|
|
|
({ assetPath, assetInfo } = this._getAssetPathWithInfo(
|
|
|
|
|
module,
|
|
|
|
|
generateContext,
|
|
|
|
|
originalFilename,
|
|
|
|
|
assetInfo,
|
|
|
|
|
contentHash
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
data.set("url", { [type]: assetPath, ...data.get("url") });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
data.set("assetInfo", assetInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Due to code generation caching module.buildInfo.XXX can't used to store such information
|
|
|
|
|
// It need to be stored in the code generation results instead, where it's cached too
|
|
|
|
|
// TODO webpack 6 For back-compat reasons we also store in on module.buildInfo
|
|
|
|
|
if (!module.buildInfo.filename) {
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).filename = filename;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!module.buildInfo.assetInfo) {
|
|
|
|
|
/** @type {BuildInfo} */
|
|
|
|
|
(module.buildInfo).assetInfo = assetInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
content = assetPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type === "javascript") {
|
|
|
|
|
if (concatenationScope) {
|
|
|
|
|
concatenationScope.registerNamespaceExport(
|
|
|
|
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new RawSource(
|
|
|
|
|
`${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
|
|
|
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
|
|
|
|
} = ${content};`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runtimeRequirements.add(RuntimeGlobals.module);
|
|
|
|
|
|
|
|
|
|
return new RawSource(`${RuntimeGlobals.module}.exports = ${content};`);
|
|
|
|
|
} else if (type === "css-url") {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return /** @type {Source} */ (module.originalSource());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -468,10 +651,38 @@ class AssetGenerator extends Generator {
|
|
|
|
|
* @returns {Set<string>} available types (do not mutate)
|
|
|
|
|
*/
|
|
|
|
|
getTypes(module) {
|
|
|
|
|
if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) {
|
|
|
|
|
return JS_TYPES;
|
|
|
|
|
const sourceTypes = new Set();
|
|
|
|
|
const connections = this._moduleGraph.getIncomingConnections(module);
|
|
|
|
|
|
|
|
|
|
for (const connection of connections) {
|
|
|
|
|
sourceTypes.add(connection.originModule.type.split("/")[0]);
|
|
|
|
|
}
|
|
|
|
|
return JS_AND_ASSET_TYPES;
|
|
|
|
|
|
|
|
|
|
if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) {
|
|
|
|
|
if (sourceTypes) {
|
|
|
|
|
if (sourceTypes.has("javascript") && sourceTypes.has("css")) {
|
|
|
|
|
return CSS_AND_JS_TYPES;
|
|
|
|
|
} else if (sourceTypes.has("javascript")) {
|
|
|
|
|
return JS_TYPES;
|
|
|
|
|
} else if (sourceTypes.has("css")) {
|
|
|
|
|
return CSS_TYPES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NO_TYPES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sourceTypes) {
|
|
|
|
|
if (sourceTypes.has("javascript") && sourceTypes.has("css")) {
|
|
|
|
|
return JS_AND_CSS_AND_ASSET_TYPES;
|
|
|
|
|
} else if (sourceTypes.has("javascript")) {
|
|
|
|
|
return JS_AND_ASSET_TYPES;
|
|
|
|
|
} else if (sourceTypes.has("css")) {
|
|
|
|
|
return CSS_AND_ASSET_TYPES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ASSET_TYPES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|