fix: 发版后软刷新检测入口壳并在 chunk 404 时硬刷新
避免 Logo/下拉刷新仍跑旧 index.js,以及站内消息预取失败弹出英文 toast。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,22 @@
|
||||
const RELOAD_AT_KEY = 'j13:chunk-reload-at';
|
||||
const RELOAD_COOLDOWN_MS = 15_000;
|
||||
|
||||
/** 从 HTML 中提取入口 module script(Vite 产物:/assets/index-*.js) */
|
||||
function extractEntryScriptSrc(html: string): string | null {
|
||||
const re = /<script[^>]*\stype=["']module["'][^>]*\ssrc=["']([^"']+)["'][^>]*>/i;
|
||||
const m = html.match(re);
|
||||
if (m?.[1]) return m[1];
|
||||
// src 在 type 之前
|
||||
const re2 = /<script[^>]*\ssrc=["']([^"']+)["'][^>]*\stype=["']module["'][^>]*>/i;
|
||||
return html.match(re2)?.[1] ?? null;
|
||||
}
|
||||
|
||||
/** 当前文档已加载的入口 script src */
|
||||
export function getDocumentEntryScriptSrc(): string | null {
|
||||
const el = document.querySelector<HTMLScriptElement>('script[type="module"][src]');
|
||||
return el?.getAttribute('src') ?? null;
|
||||
}
|
||||
|
||||
/** 判断是否为「发版后旧 JS chunk 失效」类错误 */
|
||||
export function isChunkLoadError(error: unknown): boolean {
|
||||
const msg = error instanceof Error
|
||||
@@ -32,3 +48,29 @@ export function reloadForStaleChunk(): boolean {
|
||||
window.location.reload();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 软刷新前对比入口 HTML 中的 index-*.js 哈希。
|
||||
* 发版后当前页 chunk 仍在内存,裸 import() 不会重新拉文件,必须主动检测。
|
||||
* @returns 是否已触发硬刷新(调用方应停止后续软刷新)
|
||||
*/
|
||||
export async function reloadIfShellStale(): Promise<boolean> {
|
||||
const current = getDocumentEntryScriptSrc();
|
||||
if (!current) return false;
|
||||
|
||||
try {
|
||||
const res = await fetch(`${window.location.pathname}${window.location.search}`, {
|
||||
cache: 'no-store',
|
||||
headers: { Accept: 'text/html' },
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
if (!res.ok) return false;
|
||||
const html = await res.text();
|
||||
const next = extractEntryScriptSrc(html);
|
||||
if (!next || next === current) return false;
|
||||
return reloadForStaleChunk();
|
||||
} catch {
|
||||
// 网络失败:跳过,继续软刷新
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user