186 lines
6.1 KiB
JavaScript
186 lines
6.1 KiB
JavaScript
|
|
import { t as resolveModuleDependencies } from "./dependencies-VCG-RX19.mjs";
|
||
|
|
// src/utils.ts
|
||
|
|
const IS_JS_RE = /\.[cm]?js(?:\?[^.]+)?$/;
|
||
|
|
const HAS_EXT_RE = /[^./]\.[^./]+$/;
|
||
|
|
const IS_CSS_RE = /\.(?:css|postcss|pcss|sass|scss|less|stylus|styl)(?:\?[^.]+)?$/;
|
||
|
|
function isJS(file) {
|
||
|
|
return IS_JS_RE.test(file) || !HAS_EXT_RE.test(file);
|
||
|
|
}
|
||
|
|
function isCSS(file) {
|
||
|
|
return IS_CSS_RE.test(file);
|
||
|
|
}
|
||
|
|
const IMAGE_RE = /^(?:jpe?g|png|svg|gif|webp|ico)$/;
|
||
|
|
const FONT_RE = /^(?:woff2?|ttf|otf|eot)$/;
|
||
|
|
const AUDIO_RE = /^(?:mp3|wav|ogg|flac|aac|m4a|wma|aiff|aif|au|raw|vox|opus)$/;
|
||
|
|
const VIDEO_RE = /^(?:mp4|webm|ogv|mkv|avi|mov|flv|wmv|mpg|mpeg|m4v|3gp|3g2|mxf|rm|rmvb|asf|asx|m3u8|m3u|pls|cue)$/;
|
||
|
|
const contentTypeMap = {
|
||
|
|
ico: "image/x-icon",
|
||
|
|
jpg: "image/jpeg",
|
||
|
|
svg: "image/svg+xml"
|
||
|
|
};
|
||
|
|
function getContentType(asType, extension) {
|
||
|
|
if (asType === "font") return `font/${extension}`;
|
||
|
|
if (asType === "image") return contentTypeMap[extension] || `image/${extension}`;
|
||
|
|
}
|
||
|
|
function getAsType(ext) {
|
||
|
|
if (ext === "js" || ext === "cjs" || ext === "mjs") return "script";
|
||
|
|
else if (ext === "css") return "style";
|
||
|
|
else if (IMAGE_RE.test(ext)) return "image";
|
||
|
|
else if (FONT_RE.test(ext)) return "font";
|
||
|
|
else if (AUDIO_RE.test(ext)) return "audio";
|
||
|
|
else if (VIDEO_RE.test(ext)) return "video";
|
||
|
|
}
|
||
|
|
const parseResource = (path) => {
|
||
|
|
const chunk = {};
|
||
|
|
const qIndex = path.indexOf("?");
|
||
|
|
const end = qIndex === -1 ? path.length : qIndex;
|
||
|
|
const dotIndex = path.lastIndexOf(".", end - 1);
|
||
|
|
const extension = dotIndex === -1 || dotIndex < path.lastIndexOf("/", end - 1) ? "" : path.slice(dotIndex + 1, end);
|
||
|
|
const asType = getAsType(extension);
|
||
|
|
if (asType) {
|
||
|
|
chunk.resourceType = asType;
|
||
|
|
if (asType === "script" && extension !== "cjs") chunk.module = true;
|
||
|
|
}
|
||
|
|
if (chunk.resourceType !== "font") chunk.prefetch = true;
|
||
|
|
if (chunk.resourceType === "script" || chunk.resourceType === "style") chunk.preload = true;
|
||
|
|
const contentType = getContentType(asType, extension);
|
||
|
|
if (contentType) chunk.mimeType = contentType;
|
||
|
|
return chunk;
|
||
|
|
};
|
||
|
|
// src/vite.ts
|
||
|
|
function normalizeViteManifest(manifest) {
|
||
|
|
const _manifest = {};
|
||
|
|
for (const file in manifest) {
|
||
|
|
const chunk = manifest[file];
|
||
|
|
_manifest[file] = Object.assign(parseResource(chunk.file || file), chunk);
|
||
|
|
for (const item of chunk.css || []) if (!_manifest[item]) _manifest[item] = {
|
||
|
|
file: item,
|
||
|
|
...parseResource(item)
|
||
|
|
};
|
||
|
|
for (const item of chunk.assets || []) if (!_manifest[item]) _manifest[item] = {
|
||
|
|
file: item,
|
||
|
|
...parseResource(item)
|
||
|
|
};
|
||
|
|
}
|
||
|
|
return _manifest;
|
||
|
|
}
|
||
|
|
// src/webpack.ts
|
||
|
|
function normalizeWebpackManifest(manifest) {
|
||
|
|
const clientManifest = {};
|
||
|
|
for (const outfile of manifest.all) if (isJS(outfile)) clientManifest[getIdentifier(outfile)] = {
|
||
|
|
file: outfile,
|
||
|
|
...parseResource(outfile)
|
||
|
|
};
|
||
|
|
const first = getIdentifier(manifest.initial.find(isJS));
|
||
|
|
if (first) {
|
||
|
|
if (!(first in clientManifest)) throw new Error(`Invalid manifest - initial entrypoint not in \`all\`: ${manifest.initial.find(isJS)}`);
|
||
|
|
clientManifest[first].css = [];
|
||
|
|
clientManifest[first].assets = [];
|
||
|
|
clientManifest[first].dynamicImports = [];
|
||
|
|
}
|
||
|
|
for (const outfile of manifest.initial) if (isJS(outfile)) clientManifest[getIdentifier(outfile)].isEntry = true;
|
||
|
|
else if (isCSS(outfile) && first) {
|
||
|
|
clientManifest[first].css.push(outfile);
|
||
|
|
clientManifest[outfile] = {
|
||
|
|
file: outfile,
|
||
|
|
...parseResource(outfile)
|
||
|
|
};
|
||
|
|
} else if (first) {
|
||
|
|
clientManifest[first].assets.push(outfile);
|
||
|
|
clientManifest[outfile] = {
|
||
|
|
file: outfile,
|
||
|
|
...parseResource(outfile)
|
||
|
|
};
|
||
|
|
}
|
||
|
|
for (const outfile of manifest.async) if (isJS(outfile)) {
|
||
|
|
const identifier = getIdentifier(outfile);
|
||
|
|
if (!(identifier in clientManifest)) throw new Error(`Invalid manifest - async module not in \`all\`: ${outfile}`);
|
||
|
|
clientManifest[identifier].isDynamicEntry = true;
|
||
|
|
clientManifest[identifier].sideEffects = true;
|
||
|
|
clientManifest[first].dynamicImports.push(identifier);
|
||
|
|
} else if (first) {
|
||
|
|
const key = isCSS(outfile) ? "css" : "assets";
|
||
|
|
const identifier = getIdentifier(outfile);
|
||
|
|
clientManifest[identifier] = {
|
||
|
|
file: "",
|
||
|
|
[key]: [outfile]
|
||
|
|
};
|
||
|
|
clientManifest[outfile] = {
|
||
|
|
file: outfile,
|
||
|
|
...parseResource(outfile)
|
||
|
|
};
|
||
|
|
clientManifest[first].dynamicImports.push(identifier);
|
||
|
|
}
|
||
|
|
for (const [moduleId, importIndexes] of Object.entries(manifest.modules)) {
|
||
|
|
const cssFiles = [];
|
||
|
|
const assetFiles = [];
|
||
|
|
const imports = [];
|
||
|
|
for (const index of importIndexes) {
|
||
|
|
const file = manifest.all[index];
|
||
|
|
if (isJS(file)) {
|
||
|
|
const identifier = getIdentifier(file);
|
||
|
|
imports.push(identifier);
|
||
|
|
clientManifest[identifier] = {
|
||
|
|
...clientManifest[identifier],
|
||
|
|
file
|
||
|
|
};
|
||
|
|
} else if (isCSS(file)) cssFiles.push(file);
|
||
|
|
else assetFiles.push(file);
|
||
|
|
}
|
||
|
|
clientManifest[moduleId] = {
|
||
|
|
file: "",
|
||
|
|
...parseResource(moduleId),
|
||
|
|
imports,
|
||
|
|
css: cssFiles,
|
||
|
|
assets: assetFiles
|
||
|
|
};
|
||
|
|
for (const key of ["css", "assets"]) for (const file of clientManifest[moduleId][key] || []) clientManifest[file] = clientManifest[file] || {
|
||
|
|
file,
|
||
|
|
...parseResource(file)
|
||
|
|
};
|
||
|
|
}
|
||
|
|
return clientManifest;
|
||
|
|
}
|
||
|
|
function getIdentifier(output) {
|
||
|
|
return output ? `_${output}` : null;
|
||
|
|
}
|
||
|
|
// src/precompute.ts
|
||
|
|
/**
|
||
|
|
* Build-time utility to precompute all module dependencies from a manifest.
|
||
|
|
* This eliminates recursive dependency resolution at runtime.
|
||
|
|
*
|
||
|
|
* @param manifest The build manifest
|
||
|
|
* @returns Serializable precomputed data for runtime use
|
||
|
|
*/
|
||
|
|
function precomputeDependencies(manifest) {
|
||
|
|
const dependencies = {};
|
||
|
|
const entrypoints = [];
|
||
|
|
const modules = {};
|
||
|
|
let resourceCount = 0;
|
||
|
|
for (const moduleId in manifest) {
|
||
|
|
resourceCount++;
|
||
|
|
resolveModuleDependencies(manifest, moduleId, dependencies);
|
||
|
|
const meta = manifest[moduleId];
|
||
|
|
if (meta.isEntry) entrypoints.push(moduleId);
|
||
|
|
const module = {
|
||
|
|
file: meta.file,
|
||
|
|
resourceType: meta.resourceType,
|
||
|
|
mimeType: meta.mimeType,
|
||
|
|
module: meta.module
|
||
|
|
};
|
||
|
|
if (meta.dynamicImports?.length) module.dynamicImports = meta.dynamicImports;
|
||
|
|
modules[moduleId] = module;
|
||
|
|
}
|
||
|
|
return {
|
||
|
|
dependencies,
|
||
|
|
entrypoints,
|
||
|
|
modules,
|
||
|
|
resourceCount
|
||
|
|
};
|
||
|
|
}
|
||
|
|
// src/types.ts
|
||
|
|
function defineManifest(manifest) {
|
||
|
|
return manifest;
|
||
|
|
}
|
||
|
|
export { defineManifest, normalizeViteManifest, normalizeWebpackManifest, precomputeDependencies };
|