feat: refactoring project
This commit is contained in:
622
node_modules/webpack/lib/asset/AssetGenerator.js
generated
vendored
622
node_modules/webpack/lib/asset/AssetGenerator.js
generated
vendored
@@ -10,6 +10,16 @@ const path = require("path");
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const ConcatenationScope = require("../ConcatenationScope");
|
||||
const Generator = require("../Generator");
|
||||
const {
|
||||
NO_TYPES,
|
||||
ASSET_TYPES,
|
||||
ASSET_AND_JS_TYPES,
|
||||
ASSET_AND_JS_AND_CSS_URL_TYPES,
|
||||
ASSET_AND_CSS_URL_TYPES,
|
||||
JS_TYPES,
|
||||
JS_AND_CSS_URL_TYPES,
|
||||
CSS_URL_TYPES
|
||||
} = require("../ModuleSourceTypesConstants");
|
||||
const { ASSET_MODULE_TYPE } = require("../ModuleTypeConstants");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
||||
@@ -18,19 +28,36 @@ const { makePathsRelative } = require("../util/identifier");
|
||||
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorDataUrlOptions} AssetGeneratorDataUrlOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetModuleFilename} AssetModuleFilename */
|
||||
/** @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("../Module").SourceTypes} SourceTypes */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
/** @typedef {import("../NormalModule")} NormalModule */
|
||||
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
|
||||
/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/createHash").Algorithm} Algorithm */
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {Array<T> | Set<T>} a a
|
||||
* @param {Array<U> | Set<U>} b b
|
||||
* @returns {Array<T> & Array<U>} array
|
||||
*/
|
||||
const mergeMaybeArrays = (a, b) => {
|
||||
const set = new Set();
|
||||
if (Array.isArray(a)) for (const item of a) set.add(item);
|
||||
@@ -40,6 +67,13 @@ const mergeMaybeArrays = (a, b) => {
|
||||
return Array.from(set);
|
||||
};
|
||||
|
||||
/**
|
||||
* @template {object} T
|
||||
* @template {object} U
|
||||
* @param {TODO} a a
|
||||
* @param {TODO} b b
|
||||
* @returns {T & U} object
|
||||
*/
|
||||
const mergeAssetInfo = (a, b) => {
|
||||
const result = { ...a, ...b };
|
||||
for (const key of Object.keys(a)) {
|
||||
@@ -69,6 +103,13 @@ const mergeAssetInfo = (a, b) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @template {object} T
|
||||
* @template {object} U
|
||||
* @param {TODO} a a
|
||||
* @param {TODO} b b
|
||||
* @returns {T & U} object
|
||||
*/
|
||||
const mergeRelatedInfo = (a, b) => {
|
||||
const result = { ...a, ...b };
|
||||
for (const key of Object.keys(a)) {
|
||||
@@ -80,7 +121,13 @@ const mergeRelatedInfo = (a, b) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {"base64" | false} encoding encoding
|
||||
* @param {Source} source source
|
||||
* @returns {string} encoded data
|
||||
*/
|
||||
const encodeDataUri = (encoding, source) => {
|
||||
/** @type {string | undefined} */
|
||||
let encodedContent;
|
||||
|
||||
switch (encoding) {
|
||||
@@ -95,9 +142,13 @@ const encodeDataUri = (encoding, source) => {
|
||||
encodedContent = content.toString("utf-8");
|
||||
}
|
||||
|
||||
encodedContent = encodeURIComponent(encodedContent).replace(
|
||||
encodedContent = encodeURIComponent(
|
||||
/** @type {string} */
|
||||
(encodedContent)
|
||||
).replace(
|
||||
/[!'()*]/g,
|
||||
character => "%" + character.codePointAt(0).toString(16)
|
||||
character =>
|
||||
`%${/** @type {number} */ (character.codePointAt(0)).toString(16)}`
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -128,25 +179,32 @@ const decodeDataUriContent = (encoding, content) => {
|
||||
}
|
||||
};
|
||||
|
||||
const JS_TYPES = new Set(["javascript"]);
|
||||
const JS_AND_ASSET_TYPES = new Set(["javascript", ASSET_MODULE_TYPE]);
|
||||
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 {string=} filename override for output.assetModuleFilename
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,9 +241,14 @@ class AssetGenerator extends Generator {
|
||||
}
|
||||
|
||||
/** @type {string | boolean | undefined} */
|
||||
let mimeType = this.dataUrlOptions.mimetype;
|
||||
let mimeType =
|
||||
/** @type {AssetGeneratorDataUrlOptions} */
|
||||
(this.dataUrlOptions).mimetype;
|
||||
if (mimeType === undefined) {
|
||||
const ext = path.extname(module.nameForCondition());
|
||||
const ext = path.extname(
|
||||
/** @type {string} */
|
||||
(module.nameForCondition())
|
||||
);
|
||||
if (
|
||||
module.resourceResolveData &&
|
||||
module.resourceResolveData.mimetype !== undefined
|
||||
@@ -220,205 +283,348 @@ class AssetGenerator extends Generator {
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module module for which the code should be generated
|
||||
* @param {GenerateContext} generateContext context for generate
|
||||
* @returns {Source} generated code
|
||||
* @returns {string} DataURI
|
||||
*/
|
||||
generate(
|
||||
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
|
||||
* @param {string} contentHash the content hash
|
||||
* @returns {{ filename: string, originalFilename: string, assetInfo: AssetInfo }} info
|
||||
*/
|
||||
_getFilenameWithInfo(
|
||||
module,
|
||||
{
|
||||
runtime,
|
||||
concatenationScope,
|
||||
chunkGraph,
|
||||
{ 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;
|
||||
}
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line object-shorthand
|
||||
assetPath: /** @type {string} */ (assetPath),
|
||||
assetInfo: { sourceFilename, ...assetInfo }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module module for which the code should be generated
|
||||
* @param {GenerateContext} generateContext context for generate
|
||||
* @returns {Source | null} generated code
|
||||
*/
|
||||
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 (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 {string | false | undefined} */
|
||||
let encoding = this.dataUrlOptions.encoding;
|
||||
if (encoding === undefined) {
|
||||
if (
|
||||
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 = getData();
|
||||
data.set("url", Buffer.from(encodedSource));
|
||||
content = JSON.stringify(encodedSource);
|
||||
} else {
|
||||
const assetModuleFilename =
|
||||
this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
|
||||
const hash = createHash(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,
|
||||
runtimeTemplate.outputOptions.hashDigestLength
|
||||
);
|
||||
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(
|
||||
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);
|
||||
}
|
||||
module.buildInfo.filename = filename;
|
||||
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 ? getData() : undefined;
|
||||
|
||||
if (concatenationScope) {
|
||||
concatenationScope.registerNamespaceExport(
|
||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||
);
|
||||
return new RawSource(
|
||||
`${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||
} = ${content};`
|
||||
);
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
return new RawSource(
|
||||
`${RuntimeGlobals.module}.exports = ${content};`
|
||||
);
|
||||
}
|
||||
if (
|
||||
/** @type {BuildInfo} */
|
||||
(module.buildInfo).dataUrl &&
|
||||
needContent
|
||||
) {
|
||||
const encodedSource = this.generateDataUri(module);
|
||||
content =
|
||||
type === "javascript" ? JSON.stringify(encodedSource) : encodedSource;
|
||||
|
||||
if (data) {
|
||||
data.set("url", { [type]: content, ...data.get("url") });
|
||||
}
|
||||
} else {
|
||||
const hash = createHash(
|
||||
/** @type {Algorithm} */
|
||||
(runtimeTemplate.outputOptions.hashFunction)
|
||||
);
|
||||
|
||||
if (runtimeTemplate.outputOptions.hashSalt) {
|
||||
hash.update(runtimeTemplate.outputOptions.hashSalt);
|
||||
}
|
||||
|
||||
hash.update(/** @type {Source} */ (module.originalSource()).buffer());
|
||||
|
||||
const fullHash =
|
||||
/** @type {string} */
|
||||
(hash.digest(runtimeTemplate.outputOptions.hashDigest));
|
||||
|
||||
if (data) {
|
||||
data.set("fullContentHash", fullHash);
|
||||
}
|
||||
|
||||
/** @type {BuildInfo} */
|
||||
(module.buildInfo).fullContentHash = fullHash;
|
||||
|
||||
/** @type {string} */
|
||||
const contentHash = nonNumericOnlyHash(
|
||||
fullHash,
|
||||
/** @type {number} */
|
||||
(generateContext.runtimeTemplate.outputOptions.hashDigestLength)
|
||||
);
|
||||
|
||||
if (data) {
|
||||
data.set("contentHash", contentHash);
|
||||
}
|
||||
|
||||
const { originalFilename, filename, assetInfo } =
|
||||
this._getFilenameWithInfo(module, generateContext, contentHash);
|
||||
|
||||
if (data) {
|
||||
data.set("filename", filename);
|
||||
}
|
||||
|
||||
let { assetPath, assetInfo: newAssetInfo } = this._getAssetPathWithInfo(
|
||||
module,
|
||||
generateContext,
|
||||
originalFilename,
|
||||
assetInfo,
|
||||
contentHash
|
||||
);
|
||||
|
||||
if (data && (type === "javascript" || type === "css-url")) {
|
||||
data.set("url", { [type]: assetPath, ...data.get("url") });
|
||||
}
|
||||
|
||||
if (data && data.get("assetInfo")) {
|
||||
newAssetInfo = mergeAssetInfo(data.get("assetInfo"), newAssetInfo);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
data.set("assetInfo", newAssetInfo);
|
||||
}
|
||||
|
||||
// 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
|
||||
/** @type {BuildInfo} */
|
||||
(module.buildInfo).filename = filename;
|
||||
|
||||
/** @type {BuildInfo} */
|
||||
(module.buildInfo).assetInfo = newAssetInfo;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module fresh module
|
||||
* @returns {Set<string>} available types (do not mutate)
|
||||
* @returns {SourceTypes} available types (do not mutate)
|
||||
*/
|
||||
getTypes(module) {
|
||||
if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) {
|
||||
return JS_TYPES;
|
||||
} else {
|
||||
return JS_AND_ASSET_TYPES;
|
||||
const sourceTypes = new Set();
|
||||
const connections = this._moduleGraph.getIncomingConnections(module);
|
||||
|
||||
for (const connection of connections) {
|
||||
if (!connection.originModule) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sourceTypes.add(connection.originModule.type.split("/")[0]);
|
||||
}
|
||||
|
||||
if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) {
|
||||
if (sourceTypes) {
|
||||
if (sourceTypes.has("javascript") && sourceTypes.has("css")) {
|
||||
return JS_AND_CSS_URL_TYPES;
|
||||
} else if (sourceTypes.has("javascript")) {
|
||||
return JS_TYPES;
|
||||
} else if (sourceTypes.has("css")) {
|
||||
return CSS_URL_TYPES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO_TYPES;
|
||||
}
|
||||
|
||||
if (sourceTypes) {
|
||||
if (sourceTypes.has("javascript") && sourceTypes.has("css")) {
|
||||
return ASSET_AND_JS_AND_CSS_URL_TYPES;
|
||||
} else if (sourceTypes.has("javascript")) {
|
||||
return ASSET_AND_JS_TYPES;
|
||||
} else if (sourceTypes.has("css")) {
|
||||
return ASSET_AND_CSS_URL_TYPES;
|
||||
}
|
||||
}
|
||||
|
||||
return ASSET_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,11 +656,10 @@ class AssetGenerator extends Generator {
|
||||
// 4/3 = base64 encoding
|
||||
// 34 = ~ data url header + footer + rounding
|
||||
return originalSource.size() * 1.34 + 36;
|
||||
} else {
|
||||
// it's only estimated so this number is probably fine
|
||||
// Example: m.exports=r.p+"0123456789012345678901.ext"
|
||||
return 42;
|
||||
}
|
||||
// it's only estimated so this number is probably fine
|
||||
// Example: m.exports=r.p+"0123456789012345678901.ext"
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,8 +667,12 @@ class AssetGenerator extends Generator {
|
||||
* @param {Hash} hash hash that will be modified
|
||||
* @param {UpdateHashContext} updateHashContext context for updating hash
|
||||
*/
|
||||
updateHash(hash, { module, runtime, runtimeTemplate, chunkGraph }) {
|
||||
if (module.buildInfo.dataUrl) {
|
||||
updateHash(hash, updateHashContext) {
|
||||
const { module } = updateHashContext;
|
||||
if (
|
||||
/** @type {BuildInfo} */
|
||||
(module.buildInfo).dataUrl
|
||||
) {
|
||||
hash.update("data-url");
|
||||
// this.dataUrlOptions as function should be pure and only depend on input source and filename
|
||||
// therefore it doesn't need to be hashed
|
||||
@@ -472,19 +681,26 @@ class AssetGenerator extends Generator {
|
||||
.ident;
|
||||
if (ident) hash.update(ident);
|
||||
} else {
|
||||
const dataUrlOptions =
|
||||
/** @type {AssetGeneratorDataUrlOptions} */
|
||||
(this.dataUrlOptions);
|
||||
if (
|
||||
this.dataUrlOptions.encoding &&
|
||||
this.dataUrlOptions.encoding !== DEFAULT_ENCODING
|
||||
dataUrlOptions.encoding &&
|
||||
dataUrlOptions.encoding !== DEFAULT_ENCODING
|
||||
) {
|
||||
hash.update(this.dataUrlOptions.encoding);
|
||||
hash.update(dataUrlOptions.encoding);
|
||||
}
|
||||
if (this.dataUrlOptions.mimetype)
|
||||
hash.update(this.dataUrlOptions.mimetype);
|
||||
if (dataUrlOptions.mimetype) hash.update(dataUrlOptions.mimetype);
|
||||
// computed mimetype depends only on module filename which is already part of the hash
|
||||
}
|
||||
} else {
|
||||
hash.update("resource");
|
||||
|
||||
const { module, chunkGraph, runtime } = updateHashContext;
|
||||
const runtimeTemplate =
|
||||
/** @type {NonNullable<UpdateHashContext["runtimeTemplate"]>} */
|
||||
(updateHashContext.runtimeTemplate);
|
||||
|
||||
const pathData = {
|
||||
module,
|
||||
runtime,
|
||||
@@ -506,7 +722,9 @@ class AssetGenerator extends Generator {
|
||||
}
|
||||
|
||||
const assetModuleFilename =
|
||||
this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
|
||||
this.filename ||
|
||||
/** @type {AssetModuleFilename} */
|
||||
(runtimeTemplate.outputOptions.assetModuleFilename);
|
||||
const { path: filename, info } =
|
||||
runtimeTemplate.compilation.getAssetPathWithInfo(
|
||||
assetModuleFilename,
|
||||
|
||||
55
node_modules/webpack/lib/asset/AssetModulesPlugin.js
generated
vendored
55
node_modules/webpack/lib/asset/AssetModulesPlugin.js
generated
vendored
@@ -17,9 +17,12 @@ const createSchemaValidation = require("../util/create-schema-validation");
|
||||
const memoize = require("../util/memoize");
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../Module")} Module */
|
||||
/** @typedef {import("../Module").BuildInfo} BuildInfo */
|
||||
/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
|
||||
|
||||
/**
|
||||
* @param {string} name name of definitions
|
||||
@@ -89,7 +92,8 @@ class AssetModulesPlugin {
|
||||
.tap(plugin, parserOptions => {
|
||||
validateParserOptions(parserOptions);
|
||||
parserOptions = cleverMerge(
|
||||
compiler.options.module.parser.asset,
|
||||
/** @type {AssetParserOptions} */
|
||||
(compiler.options.module.parser.asset),
|
||||
parserOptions
|
||||
);
|
||||
|
||||
@@ -107,21 +111,21 @@ class AssetModulesPlugin {
|
||||
});
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for(ASSET_MODULE_TYPE_INLINE)
|
||||
.tap(plugin, parserOptions => {
|
||||
.tap(plugin, _parserOptions => {
|
||||
const AssetParser = getAssetParser();
|
||||
|
||||
return new AssetParser(true);
|
||||
});
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for(ASSET_MODULE_TYPE_RESOURCE)
|
||||
.tap(plugin, parserOptions => {
|
||||
.tap(plugin, _parserOptions => {
|
||||
const AssetParser = getAssetParser();
|
||||
|
||||
return new AssetParser(false);
|
||||
});
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for(ASSET_MODULE_TYPE_SOURCE)
|
||||
.tap(plugin, parserOptions => {
|
||||
.tap(plugin, _parserOptions => {
|
||||
const AssetSourceParser = getAssetSourceParser();
|
||||
|
||||
return new AssetSourceParser();
|
||||
@@ -137,7 +141,7 @@ class AssetModulesPlugin {
|
||||
.tap(plugin, generatorOptions => {
|
||||
validateGeneratorOptions[type](generatorOptions);
|
||||
|
||||
let dataUrl = undefined;
|
||||
let dataUrl;
|
||||
if (type !== ASSET_MODULE_TYPE_RESOURCE) {
|
||||
dataUrl = generatorOptions.dataUrl;
|
||||
if (!dataUrl || typeof dataUrl === "object") {
|
||||
@@ -149,9 +153,9 @@ class AssetModulesPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
let filename = undefined;
|
||||
let publicPath = undefined;
|
||||
let outputPath = undefined;
|
||||
let filename;
|
||||
let publicPath;
|
||||
let outputPath;
|
||||
if (type !== ASSET_MODULE_TYPE_INLINE) {
|
||||
filename = generatorOptions.filename;
|
||||
publicPath = generatorOptions.publicPath;
|
||||
@@ -161,6 +165,7 @@ class AssetModulesPlugin {
|
||||
const AssetGenerator = getAssetGenerator();
|
||||
|
||||
return new AssetGenerator(
|
||||
compilation.moduleGraph,
|
||||
dataUrl,
|
||||
filename,
|
||||
publicPath,
|
||||
@@ -174,7 +179,7 @@ class AssetModulesPlugin {
|
||||
.tap(plugin, () => {
|
||||
const AssetSourceGenerator = getAssetSourceGenerator();
|
||||
|
||||
return new AssetSourceGenerator();
|
||||
return new AssetSourceGenerator(compilation.moduleGraph);
|
||||
});
|
||||
|
||||
compilation.hooks.renderManifest.tap(plugin, (result, options) => {
|
||||
@@ -193,24 +198,23 @@ class AssetModulesPlugin {
|
||||
module,
|
||||
chunk.runtime
|
||||
);
|
||||
const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
|
||||
const data =
|
||||
/** @type {NonNullable<CodeGenerationResult["data"]>} */
|
||||
(codeGenResult.data);
|
||||
result.push({
|
||||
render: () => codeGenResult.sources.get(type),
|
||||
filename:
|
||||
module.buildInfo.filename ||
|
||||
codeGenResult.data.get("filename"),
|
||||
info:
|
||||
module.buildInfo.assetInfo ||
|
||||
codeGenResult.data.get("assetInfo"),
|
||||
render: () =>
|
||||
/** @type {Source} */ (codeGenResult.sources.get(type)),
|
||||
filename: buildInfo.filename || data.get("filename"),
|
||||
info: buildInfo.assetInfo || data.get("assetInfo"),
|
||||
auxiliary: true,
|
||||
identifier: `assetModule${chunkGraph.getModuleId(module)}`,
|
||||
hash:
|
||||
module.buildInfo.fullContentHash ||
|
||||
codeGenResult.data.get("fullContentHash")
|
||||
hash: buildInfo.fullContentHash || data.get("fullContentHash")
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error} */ (e).message +=
|
||||
} catch (err) {
|
||||
/** @type {Error} */ (err).message +=
|
||||
`\nduring rendering of asset ${module.identifier()}`;
|
||||
throw e;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,9 +228,12 @@ class AssetModulesPlugin {
|
||||
const { codeGenerationResult } = options;
|
||||
const source = codeGenerationResult.sources.get(ASSET_MODULE_TYPE);
|
||||
if (source === undefined) return;
|
||||
context.assets.set(codeGenerationResult.data.get("filename"), {
|
||||
const data =
|
||||
/** @type {NonNullable<CodeGenerationResult["data"]>} */
|
||||
(codeGenerationResult.data);
|
||||
context.assets.set(data.get("filename"), {
|
||||
source,
|
||||
info: codeGenerationResult.data.get("assetInfo")
|
||||
info: data.get("assetInfo")
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
116
node_modules/webpack/lib/asset/AssetSourceGenerator.js
generated
vendored
116
node_modules/webpack/lib/asset/AssetSourceGenerator.js
generated
vendored
@@ -8,55 +8,86 @@
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const ConcatenationScope = require("../ConcatenationScope");
|
||||
const Generator = require("../Generator");
|
||||
const {
|
||||
NO_TYPES,
|
||||
CSS_URL_TYPES,
|
||||
JS_TYPES,
|
||||
JS_AND_CSS_URL_TYPES
|
||||
} = require("../ModuleSourceTypesConstants");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
|
||||
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
|
||||
/** @typedef {import("../Module").SourceTypes} SourceTypes */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
/** @typedef {import("../NormalModule")} NormalModule */
|
||||
|
||||
const TYPES = new Set(["javascript"]);
|
||||
|
||||
class AssetSourceGenerator extends Generator {
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph the module graph
|
||||
*/
|
||||
constructor(moduleGraph) {
|
||||
super();
|
||||
|
||||
this._moduleGraph = moduleGraph;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module module for which the code should be generated
|
||||
* @param {GenerateContext} generateContext context for generate
|
||||
* @returns {Source} generated code
|
||||
* @returns {Source | null} generated code
|
||||
*/
|
||||
generate(
|
||||
module,
|
||||
{ concatenationScope, chunkGraph, runtimeTemplate, runtimeRequirements }
|
||||
{ type, concatenationScope, getData, runtimeTemplate, runtimeRequirements }
|
||||
) {
|
||||
const originalSource = module.originalSource();
|
||||
const data = getData ? getData() : undefined;
|
||||
|
||||
if (!originalSource) {
|
||||
return new RawSource("");
|
||||
switch (type) {
|
||||
case "javascript": {
|
||||
if (!originalSource) {
|
||||
return new RawSource("");
|
||||
}
|
||||
|
||||
const content = originalSource.source();
|
||||
const encodedSource =
|
||||
typeof content === "string" ? content : content.toString("utf-8");
|
||||
|
||||
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);
|
||||
}
|
||||
case "css-url": {
|
||||
if (!originalSource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const content = originalSource.source();
|
||||
const encodedSource =
|
||||
typeof content === "string" ? content : content.toString("utf-8");
|
||||
|
||||
if (data) {
|
||||
data.set("url", { [type]: encodedSource });
|
||||
}
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
const content = originalSource.source();
|
||||
|
||||
let encodedSource;
|
||||
if (typeof content === "string") {
|
||||
encodedSource = content;
|
||||
} else {
|
||||
encodedSource = content.toString("utf-8");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,10 +101,29 @@ class AssetSourceGenerator extends Generator {
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module fresh module
|
||||
* @returns {Set<string>} available types (do not mutate)
|
||||
* @returns {SourceTypes} available types (do not mutate)
|
||||
*/
|
||||
getTypes(module) {
|
||||
return TYPES;
|
||||
const sourceTypes = new Set();
|
||||
const connections = this._moduleGraph.getIncomingConnections(module);
|
||||
|
||||
for (const connection of connections) {
|
||||
if (!connection.originModule) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sourceTypes.add(connection.originModule.type.split("/")[0]);
|
||||
}
|
||||
|
||||
if (sourceTypes.has("javascript") && sourceTypes.has("css")) {
|
||||
return JS_AND_CSS_URL_TYPES;
|
||||
} else if (sourceTypes.has("javascript")) {
|
||||
return JS_TYPES;
|
||||
} else if (sourceTypes.has("css")) {
|
||||
return CSS_URL_TYPES;
|
||||
}
|
||||
|
||||
return NO_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
9
node_modules/webpack/lib/asset/RawDataUrlModule.js
generated
vendored
9
node_modules/webpack/lib/asset/RawDataUrlModule.js
generated
vendored
@@ -7,6 +7,7 @@
|
||||
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const Module = require("../Module");
|
||||
const { JS_TYPES } = require("../ModuleSourceTypesConstants");
|
||||
const { ASSET_MODULE_TYPE_RAW_DATA_URL } = require("../ModuleTypeConstants");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
@@ -26,8 +27,6 @@ const makeSerializable = require("../util/makeSerializable");
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
|
||||
const TYPES = new Set(["javascript"]);
|
||||
|
||||
class RawDataUrlModule extends Module {
|
||||
/**
|
||||
* @param {string} url raw url
|
||||
@@ -46,7 +45,7 @@ class RawDataUrlModule extends Module {
|
||||
* @returns {SourceTypes} types available (do not mutate)
|
||||
*/
|
||||
getSourceTypes() {
|
||||
return TYPES;
|
||||
return JS_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +113,9 @@ class RawDataUrlModule extends Module {
|
||||
new RawSource(`module.exports = ${JSON.stringify(this.url)};`)
|
||||
);
|
||||
const data = new Map();
|
||||
data.set("url", this.urlBuffer);
|
||||
data.set("url", {
|
||||
javascript: this.url
|
||||
});
|
||||
const runtimeRequirements = new Set();
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
return { sources, runtimeRequirements, data };
|
||||
|
||||
Reference in New Issue
Block a user