one
Version:
One is a React framework for web, iOS, and Android apps.
113 lines (111 loc) • 3.48 kB
JavaScript
const MAX_MODULES = 500;
const TIMEOUT_MS = 5e3;
function collectImports(source, base) {
const out = [];
const add = (spec) => {
if (!/^[./]|^https?:/.test(spec)) return;
try {
out.push(new URL(spec, base).href);
} catch {}
};
for (const m of source.matchAll(/(?:^|[\s;}])(?:import|export)[^'"]{0,300}?from\s*["']([^"']+)["']/g)) add(m[1]);
for (const m of source.matchAll(/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g)) add(m[1]);
for (const m of source.matchAll(/(?:^|[\s;}])import\s*["']([^"']+)["']/g)) add(m[1]);
return out;
}
async function findRouteLoadFault(entryUrl) {
const deadline = Date.now() + TIMEOUT_MS;
const importers = /* @__PURE__ */ new Map();
const entry = new URL(entryUrl, window.location.href).href;
importers.set(entry, null);
let frontier = [entry];
let visited = 0;
while (frontier.length && visited < MAX_MODULES && Date.now() < deadline) {
const batch = frontier.slice(0, 32);
frontier = frontier.slice(batch.length);
visited += batch.length;
const results = await Promise.all(batch.map(async (url) => {
let res;
try {
res = await fetch(url);
} catch {
return {
url,
fault: "unreachable",
imports: []
};
}
if (res.status === 404) return {
url,
fault: "missing",
imports: []
};
if (!res.ok) return {
url,
fault: null,
imports: []
};
const type = res.headers.get("content-type") ?? "";
if (!type.includes("javascript")) return {
url,
fault: null,
imports: []
};
return {
url,
fault: null,
imports: collectImports(await res.text(), url)
};
}));
for (const result of results) {
if (result.fault === "missing") {
const importer = importers.get(result.url) ?? null;
if (importer?.includes("/node_modules/")) continue;
return {
kind: "missing",
url: result.url,
importer
};
}
if (result.fault === "unreachable") {
const serverAnswers = await fetch(window.location.href, { method: "HEAD" }).then(() => true, () => false);
return serverAnswers ? {
kind: "blocked",
url: result.url
} : null;
}
for (const next of result.imports) {
if (importers.has(next)) continue;
importers.set(next, result.url);
frontier.push(next);
}
}
}
return null;
}
async function diagnoseRouteLoadFailure(routeId, routeUrl) {
const fault = await findRouteLoadFault(routeUrl);
if (!fault) return null;
const toPath = (url) => url.replace(window.location.origin, "");
const path = toPath(fault.url);
if (fault.kind === "missing") {
return [
`Route "${routeId}" failed to load because ${path} does not exist (the dev server answered 404).`,
``,
fault.importer ? `${toPath(fault.importer)} imports it. Create the file or remove the import.` : `Create the file or remove the import.`
].join("\n");
}
return [
`Route "${routeId}" failed to load because this browser refused to fetch ${path}`,
``,
`That request never reached the dev server, so a content blocker or privacy`,
`extension is blocking it. In dev the module URL is the source path, and a`,
`path containing a word like "analytics", "pageview" or "track" matches the`,
`tracking rules those blockers ship.`,
``,
`Rename the file or the directory so its path no longer matches, or allow`,
`${window.location.origin} in the blocker.`
].join("\n");
}
export { diagnoseRouteLoadFailure, findRouteLoadFault };
//# sourceMappingURL=diagnoseRouteLoadFailure.mjs.map