vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
75 lines (74 loc) • 3.89 kB
JavaScript
export { getPageAssets };
export { setResolveClientEntriesDev };
export { resolveIncludeAssetsImportedByServer };
import { assert, prependBase, toPosixPath, unique, getGlobalObject } from '../utils.js';
import { retrieveAssetsDev } from './getPageAssets/retrieveAssetsDev.js';
import { retrieveAssetsProd } from './getPageAssets/retrieveAssetsProd.js';
import { inferMediaType } from './inferMediaType.js';
import { getManifestEntry } from './getPageAssets/getManifestEntry.js';
import { sortPageAssetsForEarlyHintsHeader } from './getPageAssets/sortPageAssetsForEarlyHintsHeader.js';
const globalObject = getGlobalObject('renderPage/getPageAssets.ts', {
resolveClientEntriesDev: null,
});
async function getPageAssets(pageContext, clientDependencies, clientEntries) {
const globalContext = pageContext._globalContext;
const { _isProduction: isProduction } = globalContext;
const isDev = !isProduction;
let assetUrls;
let clientEntriesSrc;
if (isDev) {
const { _viteDevServer: viteDevServer } = globalContext;
clientEntriesSrc = clientEntries.map((clientEntry) => globalObject.resolveClientEntriesDev(clientEntry, viteDevServer));
assetUrls = await retrieveAssetsDev(clientDependencies, viteDevServer);
}
else {
const { assetsManifest } = globalContext;
clientEntriesSrc = clientEntries.map((clientEntry) => resolveClientEntriesProd(clientEntry, assetsManifest));
assetUrls = retrieveAssetsProd(clientDependencies, assetsManifest, resolveIncludeAssetsImportedByServer(pageContext._globalContext.config));
}
let pageAssets = [];
unique([...clientEntriesSrc, ...assetUrls]).forEach((src) => {
const { mediaType = null, assetType = null } = inferMediaType(src) || {};
if (isDev && assetType === 'style') {
// https://github.com/vikejs/vike/issues/449
if (src.endsWith('?inline')) {
return;
}
// https://github.com/vikejs/vike/issues/401
// WARNING: if changing following line, then also update https://github.com/vikejs/vike/blob/fae90a15d88e5e87ca9fcbb54cf2dc8773d2f229/vike/client/shared/removeFoucBuster.ts#L28
src = src + '?direct';
}
const isEntry = clientEntriesSrc.includes(src) ||
// Vite automatically injects CSS, not only in development, but also in production (albeit with a FOUC). Therefore, strictly speaking, CSS aren't entries. We still, however, set `isEntry: true` for CSS, in order to denote page assets that should absolutely be injected in the HTML, regardless of preload strategy (not injecting CSS leads to FOUC).
assetType === 'style';
pageAssets.push({
src,
assetType,
mediaType,
isEntry,
});
});
pageAssets.forEach(({ src }) => {
assert(1 === pageAssets.filter((p) => p.src === src).length);
});
pageAssets = pageAssets.map((pageAsset) => {
const baseServerAssets = pageContext._baseAssets || pageContext._baseServer;
pageAsset.src = prependBase(toPosixPath(pageAsset.src), baseServerAssets);
return pageAsset;
});
await sortPageAssetsForEarlyHintsHeader(pageAssets, isProduction);
return pageAssets;
}
function resolveClientEntriesProd(clientEntry, assetsManifest) {
const { manifestEntry } = getManifestEntry(clientEntry, assetsManifest);
assert(manifestEntry.isEntry || manifestEntry.isDynamicEntry || clientEntry.endsWith('.css'), { clientEntry });
let { file } = manifestEntry;
assert(!file.startsWith('/'));
return '/' + file;
}
function setResolveClientEntriesDev(resolveClientEntriesDev) {
globalObject.resolveClientEntriesDev = resolveClientEntriesDev;
}
function resolveIncludeAssetsImportedByServer(config) {
return config.includeAssetsImportedByServer ?? true;
}