mirror of https://github.com/webpack/webpack.git
141 lines
3.7 KiB
JavaScript
141 lines
3.7 KiB
JavaScript
/*
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
Author Tobias Koppers @sokra
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
const RuntimeGlobals = require("../RuntimeGlobals");
|
|
const RuntimeModule = require("../RuntimeModule");
|
|
const Template = require("../Template");
|
|
|
|
/** @typedef {import("../Chunk")} Chunk */
|
|
/** @typedef {import("../Compilation")} Compilation */
|
|
|
|
/**
|
|
* @typedef {object} AssetInfo
|
|
* @property {string} url
|
|
* @property {string} as
|
|
* @property {string=} fetchPriority
|
|
* @property {string=} type
|
|
*/
|
|
|
|
/**
|
|
* @typedef {object} AssetPrefetchInfo
|
|
* @property {AssetInfo[]} prefetch
|
|
* @property {AssetInfo[]} preload
|
|
*/
|
|
|
|
class AssetPrefetchStartupRuntimeModule extends RuntimeModule {
|
|
/**
|
|
* @param {AssetPrefetchInfo} assetInfo asset prefetch/preload information
|
|
*/
|
|
constructor(assetInfo) {
|
|
super("asset prefetch", RuntimeModule.STAGE_TRIGGER);
|
|
this.assetInfo = assetInfo;
|
|
}
|
|
|
|
/**
|
|
* @returns {string | null} runtime code
|
|
*/
|
|
generate() {
|
|
const { assetInfo } = this;
|
|
const compilation = /** @type {Compilation} */ (this.compilation);
|
|
const { runtimeTemplate } = compilation;
|
|
|
|
const lines = [];
|
|
|
|
// Helper to serialize asset info
|
|
/**
|
|
* @param {AssetInfo} asset The asset information to serialize
|
|
* @returns {string} Serialized arguments for prefetch/preload function
|
|
*/
|
|
const serializeAsset = (asset) => {
|
|
const args = [
|
|
`${RuntimeGlobals.publicPath} + "${asset.url}"`,
|
|
`"${asset.as}"`
|
|
];
|
|
|
|
if (asset.fetchPriority) {
|
|
args.push(`"${asset.fetchPriority}"`);
|
|
} else {
|
|
args.push("undefined");
|
|
}
|
|
|
|
if (asset.type) {
|
|
args.push(`"${asset.type}"`);
|
|
}
|
|
|
|
return args.join(", ");
|
|
};
|
|
|
|
// Generate prefetch code
|
|
if (assetInfo.prefetch.length > 0) {
|
|
const prefetchCode =
|
|
assetInfo.prefetch.length <= 2
|
|
? // For few assets, generate direct calls
|
|
assetInfo.prefetch.map(
|
|
(asset) =>
|
|
`${RuntimeGlobals.prefetchAsset}(${serializeAsset(asset)});`
|
|
)
|
|
: // For many assets, use array iteration
|
|
Template.asString([
|
|
`[${assetInfo.prefetch
|
|
.map(
|
|
(asset) =>
|
|
`{ url: ${RuntimeGlobals.publicPath} + "${asset.url}", as: "${asset.as}"${
|
|
asset.fetchPriority
|
|
? `, fetchPriority: "${asset.fetchPriority}"`
|
|
: ""
|
|
}${asset.type ? `, type: "${asset.type}"` : ""} }`
|
|
)
|
|
.join(", ")}].forEach(${runtimeTemplate.basicFunction("asset", [
|
|
`${RuntimeGlobals.prefetchAsset}(asset.url, asset.as, asset.fetchPriority, asset.type);`
|
|
])});`
|
|
]);
|
|
|
|
if (Array.isArray(prefetchCode)) {
|
|
lines.push(...prefetchCode);
|
|
} else {
|
|
lines.push(prefetchCode);
|
|
}
|
|
}
|
|
|
|
// Generate preload code with higher priority
|
|
if (assetInfo.preload.length > 0) {
|
|
const preloadCode =
|
|
assetInfo.preload.length <= 2
|
|
? // For few assets, generate direct calls
|
|
assetInfo.preload.map(
|
|
(asset) =>
|
|
`${RuntimeGlobals.preloadAsset}(${serializeAsset(asset)});`
|
|
)
|
|
: // For many assets, use array iteration
|
|
Template.asString([
|
|
`[${assetInfo.preload
|
|
.map(
|
|
(asset) =>
|
|
`{ url: ${RuntimeGlobals.publicPath} + "${asset.url}", as: "${asset.as}"${
|
|
asset.fetchPriority
|
|
? `, fetchPriority: "${asset.fetchPriority}"`
|
|
: ""
|
|
}${asset.type ? `, type: "${asset.type}"` : ""} }`
|
|
)
|
|
.join(", ")}].forEach(${runtimeTemplate.basicFunction("asset", [
|
|
`${RuntimeGlobals.preloadAsset}(asset.url, asset.as, asset.fetchPriority, asset.type);`
|
|
])});`
|
|
]);
|
|
|
|
if (Array.isArray(preloadCode)) {
|
|
lines.push(...preloadCode);
|
|
} else {
|
|
lines.push(preloadCode);
|
|
}
|
|
}
|
|
|
|
return Template.asString(lines);
|
|
}
|
|
}
|
|
|
|
module.exports = AssetPrefetchStartupRuntimeModule;
|