mirror of https://github.com/webpack/webpack.git
chore: comments
This commit is contained in:
parent
c94b2e9a1b
commit
a47f4443d1
|
@ -155,13 +155,13 @@ URLDependency.Template = class URLDependencyTemplate extends (
|
||||||
|
|
||||||
runtimeRequirements.add(RuntimeGlobals.require);
|
runtimeRequirements.add(RuntimeGlobals.require);
|
||||||
|
|
||||||
// Check if we need to add prefetch/preload runtime
|
// Determine if prefetch/preload hints are specified
|
||||||
const needsPrefetch = dep.prefetch !== undefined && dep.prefetch !== false;
|
const needsPrefetch = dep.prefetch !== undefined && dep.prefetch !== false;
|
||||||
const needsPreload = dep.preload !== undefined && dep.preload !== false;
|
const needsPreload = dep.preload !== undefined && dep.preload !== false;
|
||||||
|
|
||||||
// Skip inline prefetch/preload if handled by startup module
|
// Generate inline prefetch/preload code if not handled by startup module
|
||||||
if ((needsPrefetch || needsPreload) && !dep._startupPrefetch) {
|
if ((needsPrefetch || needsPreload) && !dep._startupPrefetch) {
|
||||||
// Get the module to determine asset type
|
// Resolve module to determine appropriate asset type
|
||||||
const module = moduleGraph.getModule(dep);
|
const module = moduleGraph.getModule(dep);
|
||||||
let asType = "";
|
let asType = "";
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ URLDependency.Template = class URLDependencyTemplate extends (
|
||||||
asType = getAssetType(request);
|
asType = getAssetType(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the module expression (just the module id)
|
// Get the module ID for runtime code generation
|
||||||
const moduleExpr = runtimeTemplate.moduleRaw({
|
const moduleExpr = runtimeTemplate.moduleRaw({
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
module: moduleGraph.getModule(dep),
|
module: moduleGraph.getModule(dep),
|
||||||
|
@ -181,9 +181,9 @@ URLDependency.Template = class URLDependencyTemplate extends (
|
||||||
weak: false
|
weak: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build the prefetch/preload code
|
// Construct prefetch/preload function calls
|
||||||
const hintCode = [];
|
const hintCode = [];
|
||||||
// Only pass valid fetchPriority values
|
// Validate fetchPriority against allowed values
|
||||||
const validFetchPriority =
|
const validFetchPriority =
|
||||||
dep.fetchPriority && ["high", "low", "auto"].includes(dep.fetchPriority)
|
dep.fetchPriority && ["high", "low", "auto"].includes(dep.fetchPriority)
|
||||||
? dep.fetchPriority
|
? dep.fetchPriority
|
||||||
|
@ -196,20 +196,20 @@ URLDependency.Template = class URLDependencyTemplate extends (
|
||||||
: "undefined";
|
: "undefined";
|
||||||
|
|
||||||
if (needsPrefetch && !needsPreload) {
|
if (needsPrefetch && !needsPreload) {
|
||||||
// Only prefetch
|
// Generate prefetch call
|
||||||
runtimeRequirements.add(RuntimeGlobals.prefetchAsset);
|
runtimeRequirements.add(RuntimeGlobals.prefetchAsset);
|
||||||
hintCode.push(
|
hintCode.push(
|
||||||
`${RuntimeGlobals.prefetchAsset}(url, "${asType}", ${fetchPriority}, ${preloadType});`
|
`${RuntimeGlobals.prefetchAsset}(url, "${asType}", ${fetchPriority}, ${preloadType});`
|
||||||
);
|
);
|
||||||
} else if (needsPreload) {
|
} else if (needsPreload) {
|
||||||
// Preload (takes precedence over prefetch)
|
// Generate preload call (overrides prefetch if both specified)
|
||||||
runtimeRequirements.add(RuntimeGlobals.preloadAsset);
|
runtimeRequirements.add(RuntimeGlobals.preloadAsset);
|
||||||
hintCode.push(
|
hintCode.push(
|
||||||
`${RuntimeGlobals.preloadAsset}(url, "${asType}", ${fetchPriority}, ${preloadType});`
|
`${RuntimeGlobals.preloadAsset}(url, "${asType}", ${fetchPriority}, ${preloadType});`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap in IIFE to execute hint code and return URL
|
// Create IIFE that generates URL and adds resource hints
|
||||||
if (dep.relative) {
|
if (dep.relative) {
|
||||||
runtimeRequirements.add(RuntimeGlobals.relativeUrl);
|
runtimeRequirements.add(RuntimeGlobals.relativeUrl);
|
||||||
source.replace(
|
source.replace(
|
||||||
|
@ -234,7 +234,7 @@ URLDependency.Template = class URLDependencyTemplate extends (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if ((needsPrefetch || needsPreload) && dep._startupPrefetch) {
|
} else if ((needsPrefetch || needsPreload) && dep._startupPrefetch) {
|
||||||
// Prefetch/preload handled by startup module - generate standard URL
|
// Generate standard URL when prefetch/preload is handled by startup module
|
||||||
if (dep.relative) {
|
if (dep.relative) {
|
||||||
runtimeRequirements.add(RuntimeGlobals.relativeUrl);
|
runtimeRequirements.add(RuntimeGlobals.relativeUrl);
|
||||||
source.replace(
|
source.replace(
|
||||||
|
@ -264,14 +264,14 @@ URLDependency.Template = class URLDependencyTemplate extends (
|
||||||
})}, ${RuntimeGlobals.baseURI}`
|
})}, ${RuntimeGlobals.baseURI}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Still need to add runtime requirements for prefetch/preload
|
// Register runtime requirements for prefetch/preload functions
|
||||||
if (needsPrefetch && !needsPreload) {
|
if (needsPrefetch && !needsPreload) {
|
||||||
runtimeRequirements.add(RuntimeGlobals.prefetchAsset);
|
runtimeRequirements.add(RuntimeGlobals.prefetchAsset);
|
||||||
} else if (needsPreload) {
|
} else if (needsPreload) {
|
||||||
runtimeRequirements.add(RuntimeGlobals.preloadAsset);
|
runtimeRequirements.add(RuntimeGlobals.preloadAsset);
|
||||||
}
|
}
|
||||||
} else if (dep.relative) {
|
} else if (dep.relative) {
|
||||||
// No prefetch/preload - use original code
|
// Standard URL generation without resource hints
|
||||||
runtimeRequirements.add(RuntimeGlobals.relativeUrl);
|
runtimeRequirements.add(RuntimeGlobals.relativeUrl);
|
||||||
source.replace(
|
source.replace(
|
||||||
dep.outerRange[0],
|
dep.outerRange[0],
|
||||||
|
|
|
@ -41,12 +41,12 @@ class AssetPrefetchStartupPlugin {
|
||||||
const assetPrefetchMap = new WeakMap();
|
const assetPrefetchMap = new WeakMap();
|
||||||
const chunkAssetInfoMap = new WeakMap();
|
const chunkAssetInfoMap = new WeakMap();
|
||||||
|
|
||||||
// Hook into finishModules to collect all URLDependencies
|
// Collect URLDependencies with prefetch/preload hints during module finalization
|
||||||
compilation.hooks.finishModules.tap(PLUGIN_NAME, (modules) => {
|
compilation.hooks.finishModules.tap(PLUGIN_NAME, (modules) => {
|
||||||
for (const module of modules) {
|
for (const module of modules) {
|
||||||
if (!module.dependencies) continue;
|
if (!module.dependencies) continue;
|
||||||
|
|
||||||
// Collect URLDependencies with prefetch/preload
|
// Find all URL dependencies that have prefetch or preload hints
|
||||||
const assetDeps = [];
|
const assetDeps = [];
|
||||||
for (const dep of module.dependencies) {
|
for (const dep of module.dependencies) {
|
||||||
if (dep.constructor.name === "URLDependency") {
|
if (dep.constructor.name === "URLDependency") {
|
||||||
|
@ -64,7 +64,7 @@ class AssetPrefetchStartupPlugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Process assets when chunks are being optimized
|
// Aggregate prefetch/preload assets by chunk during optimization
|
||||||
compilation.hooks.optimizeChunks.tap(
|
compilation.hooks.optimizeChunks.tap(
|
||||||
{ name: PLUGIN_NAME, stage: 1 },
|
{ name: PLUGIN_NAME, stage: 1 },
|
||||||
(chunks) => {
|
(chunks) => {
|
||||||
|
@ -77,13 +77,13 @@ class AssetPrefetchStartupPlugin {
|
||||||
preload: /** @type {AssetInfo[]} */ ([])
|
preload: /** @type {AssetInfo[]} */ ([])
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process all modules in this chunk
|
// Iterate through all modules in the chunk
|
||||||
for (const module of chunkGraph.getChunkModules(chunk)) {
|
for (const module of chunkGraph.getChunkModules(chunk)) {
|
||||||
const urlDeps = assetPrefetchMap.get(module);
|
const urlDeps = assetPrefetchMap.get(module);
|
||||||
if (!urlDeps) continue;
|
if (!urlDeps) continue;
|
||||||
|
|
||||||
for (const dep of urlDeps) {
|
for (const dep of urlDeps) {
|
||||||
// Mark dependency as handled by startup prefetch
|
// Flag this dependency as handled by startup module to prevent inline generation
|
||||||
dep._startupPrefetch = true;
|
dep._startupPrefetch = true;
|
||||||
|
|
||||||
const resolvedModule = moduleGraph.getModule(dep);
|
const resolvedModule = moduleGraph.getModule(dep);
|
||||||
|
@ -94,7 +94,7 @@ class AssetPrefetchStartupPlugin {
|
||||||
).request;
|
).request;
|
||||||
if (!request) continue;
|
if (!request) continue;
|
||||||
|
|
||||||
// Get the actual asset filename from module buildInfo
|
// Extract the asset filename from module metadata
|
||||||
let assetUrl;
|
let assetUrl;
|
||||||
if (
|
if (
|
||||||
resolvedModule.buildInfo &&
|
resolvedModule.buildInfo &&
|
||||||
|
@ -102,7 +102,7 @@ class AssetPrefetchStartupPlugin {
|
||||||
) {
|
) {
|
||||||
assetUrl = resolvedModule.buildInfo.filename;
|
assetUrl = resolvedModule.buildInfo.filename;
|
||||||
} else {
|
} else {
|
||||||
// Fallback to extracting from request
|
// Fall back to filename from request path
|
||||||
assetUrl = request.split(/[\\/]/).pop() || request;
|
assetUrl = request.split(/[\\/]/).pop() || request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,18 +160,15 @@ class AssetPrefetchStartupPlugin {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ensure runtime functions are available
|
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.prefetchAsset)
|
.for(RuntimeGlobals.prefetchAsset)
|
||||||
.tap(PLUGIN_NAME, (chunk, set) => {
|
.tap(PLUGIN_NAME, (chunk, set) => {
|
||||||
// AssetPrefetchPreloadRuntimeModule will be added by URLParserPlugin
|
|
||||||
set.add(RuntimeGlobals.publicPath);
|
set.add(RuntimeGlobals.publicPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.preloadAsset)
|
.for(RuntimeGlobals.preloadAsset)
|
||||||
.tap(PLUGIN_NAME, (chunk, set) => {
|
.tap(PLUGIN_NAME, (chunk, set) => {
|
||||||
// AssetPrefetchPreloadRuntimeModule will be added by URLParserPlugin
|
|
||||||
set.add(RuntimeGlobals.publicPath);
|
set.add(RuntimeGlobals.publicPath);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,8 +55,8 @@ class AssetPrefetchStartupRuntimeModule extends RuntimeModule {
|
||||||
const lines = [];
|
const lines = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AssetInfo} asset The asset information to serialize
|
* @param {AssetInfo} asset asset info object
|
||||||
* @returns {string} Serialized arguments for prefetch/preload function
|
* @returns {string} serialized function arguments
|
||||||
*/
|
*/
|
||||||
const serializeAsset = (asset) => {
|
const serializeAsset = (asset) => {
|
||||||
const args = [
|
const args = [
|
||||||
|
|
|
@ -19,7 +19,7 @@ class AssetPrefetchPreloadPlugin {
|
||||||
*/
|
*/
|
||||||
apply(compiler) {
|
apply(compiler) {
|
||||||
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
||||||
// Add runtime module for asset prefetch
|
// Register runtime module for asset prefetch
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.prefetchAsset)
|
.for(RuntimeGlobals.prefetchAsset)
|
||||||
.tap(PLUGIN_NAME, (chunk, set) => {
|
.tap(PLUGIN_NAME, (chunk, set) => {
|
||||||
|
@ -29,7 +29,7 @@ class AssetPrefetchPreloadPlugin {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add runtime module for asset preload
|
// Register runtime module for asset preload
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.preloadAsset)
|
.for(RuntimeGlobals.preloadAsset)
|
||||||
.tap(PLUGIN_NAME, (chunk, set) => {
|
.tap(PLUGIN_NAME, (chunk, set) => {
|
||||||
|
|
|
@ -47,7 +47,7 @@ class AssetPrefetchPreloadRuntimeModule extends RuntimeModule {
|
||||||
"link.setAttribute('fetchpriority', fetchPriority);"
|
"link.setAttribute('fetchpriority', fetchPriority);"
|
||||||
]),
|
]),
|
||||||
"}",
|
"}",
|
||||||
// Add nonce if needed
|
// Apply nonce attribute for CSP if configured
|
||||||
compilation.outputOptions.crossOriginLoading
|
compilation.outputOptions.crossOriginLoading
|
||||||
? Template.asString([
|
? Template.asString([
|
||||||
`if(${RuntimeGlobals.scriptNonce}) {`,
|
`if(${RuntimeGlobals.scriptNonce}) {`,
|
||||||
|
|
|
@ -185,9 +185,9 @@ class URLParserPlugin {
|
||||||
);
|
);
|
||||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||||
|
|
||||||
// Handle prefetch/preload hints
|
// Process magic comments for prefetch/preload hints
|
||||||
if (importOptions) {
|
if (importOptions) {
|
||||||
// Validate webpackPrefetch
|
// webpackPrefetch should be boolean true
|
||||||
if (
|
if (
|
||||||
importOptions.webpackPrefetch !== undefined &&
|
importOptions.webpackPrefetch !== undefined &&
|
||||||
importOptions.webpackPrefetch !== true
|
importOptions.webpackPrefetch !== true
|
||||||
|
@ -200,7 +200,7 @@ class URLParserPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate webpackPreload
|
// webpackPreload should be boolean true
|
||||||
if (
|
if (
|
||||||
importOptions.webpackPreload !== undefined &&
|
importOptions.webpackPreload !== undefined &&
|
||||||
importOptions.webpackPreload !== true
|
importOptions.webpackPreload !== true
|
||||||
|
@ -213,7 +213,7 @@ class URLParserPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate webpackFetchPriority
|
// webpackFetchPriority should be one of: high, low, auto
|
||||||
if (
|
if (
|
||||||
importOptions.webpackFetchPriority !== undefined &&
|
importOptions.webpackFetchPriority !== undefined &&
|
||||||
(typeof importOptions.webpackFetchPriority !== "string" ||
|
(typeof importOptions.webpackFetchPriority !== "string" ||
|
||||||
|
@ -229,7 +229,7 @@ class URLParserPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate webpackPreloadAs
|
// webpackPreloadAs should be a string
|
||||||
if (
|
if (
|
||||||
importOptions.webpackPreloadAs !== undefined &&
|
importOptions.webpackPreloadAs !== undefined &&
|
||||||
typeof importOptions.webpackPreloadAs !== "string"
|
typeof importOptions.webpackPreloadAs !== "string"
|
||||||
|
@ -242,7 +242,7 @@ class URLParserPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate webpackPreloadType
|
// webpackPreloadType should be a string
|
||||||
if (
|
if (
|
||||||
importOptions.webpackPreloadType !== undefined &&
|
importOptions.webpackPreloadType !== undefined &&
|
||||||
typeof importOptions.webpackPreloadType !== "string"
|
typeof importOptions.webpackPreloadType !== "string"
|
||||||
|
@ -255,7 +255,7 @@ class URLParserPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store hints on the dependency for later use
|
// Store magic comment values on dependency
|
||||||
dep.prefetch = importOptions.webpackPrefetch;
|
dep.prefetch = importOptions.webpackPrefetch;
|
||||||
dep.preload = importOptions.webpackPreload;
|
dep.preload = importOptions.webpackPreload;
|
||||||
dep.fetchPriority = importOptions.webpackFetchPriority;
|
dep.fetchPriority = importOptions.webpackFetchPriority;
|
||||||
|
@ -263,7 +263,7 @@ class URLParserPlugin {
|
||||||
dep.preloadType = importOptions.webpackPreloadType;
|
dep.preloadType = importOptions.webpackPreloadType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add dependency directly
|
// Register the dependency
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
|
InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the 'as' attribute value for prefetch/preload based on file extension
|
* Determines the 'as' attribute value for prefetch/preload based on file extension
|
||||||
* Reference: MDN rel=preload documentation
|
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/preload#what_types_of_content_can_be_preloaded
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/preload#what_types_of_content_can_be_preloaded
|
||||||
* @param {string} request The module request string or filename
|
* @param {string} request module request string or filename
|
||||||
* @returns {string} The 'as' attribute value for link element
|
* @returns {string} asset type for link element 'as' attribute
|
||||||
*/
|
*/
|
||||||
const getAssetType = (request) => {
|
const getAssetType = (request) => {
|
||||||
if (/\.(png|jpe?g|gif|svg|webp|avif|bmp|ico|tiff?)$/i.test(request)) {
|
if (/\.(png|jpe?g|gif|svg|webp|avif|bmp|ico|tiff?)$/i.test(request)) {
|
||||||
|
@ -26,8 +25,7 @@ const getAssetType = (request) => {
|
||||||
} else if (
|
} else if (
|
||||||
/\.(mp4|webm|ogg|mp3|wav|flac|aac|m4a|avi|mov|wmv|mkv)$/i.test(request)
|
/\.(mp4|webm|ogg|mp3|wav|flac|aac|m4a|avi|mov|wmv|mkv)$/i.test(request)
|
||||||
) {
|
) {
|
||||||
// Audio/video files: use 'fetch' as fallback since as='audio'/'video' not supported
|
// Audio/video files use 'fetch' as browser support varies
|
||||||
// Reference: https://github.com/mdn/browser-compat-data/issues/9577
|
|
||||||
return "fetch";
|
return "fetch";
|
||||||
}
|
}
|
||||||
return "fetch";
|
return "fetch";
|
||||||
|
|
Loading…
Reference in New Issue