From e2ada92510869e2d86b726074add717b271a8e47 Mon Sep 17 00:00:00 2001 From: tangxinyue <524779910@qq.com> Date: Fri, 24 Jul 2026 16:37:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=92=A4=E9=94=80=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E5=8F=8A=E5=BC=BA=E5=88=B6=E8=B7=B3=E5=9B=9E=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=9B=E5=9C=A8=20vite=20=E4=B8=AD=E5=8E=BB=E9=99=A4=20Chunk?= =?UTF-8?q?=20=E6=89=93=E5=8C=85=20Hash=EF=BC=8C=E5=B9=B6=E7=BB=99?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E8=B7=AF=E7=94=B1=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E6=97=A0=20Hash=20=E5=9B=9E=E9=80=80=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=8C=E4=BB=8E=E7=89=A9=E7=90=86=E4=B8=8A=E6=B6=88=E7=81=AD?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=97=A7=E5=BC=95=E7=94=A8=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E6=AD=BB=E9=94=81=20404?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/core/router/index.cjs | 27 +++++++++++++++++++++++---- src/router/index.js | 31 +++++++------------------------ vite.config.js | 5 +++++ 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/service/core/router/index.cjs b/service/core/router/index.cjs index ecb84d6..073aaee 100644 --- a/service/core/router/index.cjs +++ b/service/core/router/index.cjs @@ -94,10 +94,29 @@ const matchFile = async (request, response) => { if (fs.existsSync(mappedPath)) { targetPath = mappedPath } else if (cleanPath.startsWith('/assets/')) { - response.writeHead(404, { 'Content-Type': 'text/plain' }) - response.end('Asset Not Found') - resolve(true) - return + // 如果请求的是带 hash 的旧文件,尝试摘除 -[hash] 请求固定文件 + const filename = cleanPath.split('/').pop() + const parts = filename.split('.') + const ext = parts.pop() + const nameParts = parts.join('.').split('-') + if (nameParts.length > 1) { + nameParts.pop() // 移除最后的 hash + const baseName = nameParts.join('-') + const fallbackPath = dist + '/assets/' + baseName + '.' + ext + if (fs.existsSync(fallbackPath)) { + targetPath = fallbackPath + } else { + response.writeHead(404, { 'Content-Type': 'text/plain' }) + response.end('Asset Not Found') + resolve(true) + return + } + } else { + response.writeHead(404, { 'Content-Type': 'text/plain' }) + response.end('Asset Not Found') + resolve(true) + return + } } } fs.readFile(targetPath, (err, file) => { diff --git a/src/router/index.js b/src/router/index.js index 8f208c3..fb51863 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -48,25 +48,14 @@ router.beforeEach(async (to, from, next) => { router.onError((error) => { const pattern = /Failed to fetch dynamically imported module|Importing a module script failed/i if (pattern.test(error?.message || '')) { - if (window._chunkErrorHandled) return - window._chunkErrorHandled = true - - const forceReload = () => { - // 不再重载当前错误路径,直接跳回首页,并带上时间戳跳出 CDN 缓存 - window.location.href = window.location.origin + '/?t=' + Date.now() - } - - const cleanAndReload = async () => { - // 暴力清空所有的 Cache API,防止 SW 缓存 index.html 等 - if (window.caches) { - try { - const keys = await window.caches.keys() - for (const key of keys) { - await window.caches.delete(key) - } - } catch (e) {} + const isReloaded = sessionStorage.getItem('chunk_reload_flag') + if (!isReloaded) { + sessionStorage.setItem('chunk_reload_flag', 'true') + const forceReload = () => { + const url = new URL(window.location.href) + url.searchParams.set('t', Date.now()) + window.location.href = url.href } - if ('serviceWorker' in navigator) { navigator.serviceWorker.getRegistrations().then(registrations => { for (const registration of registrations) { @@ -78,12 +67,6 @@ router.onError((error) => { forceReload() } } - - if (window.confirm('系统检测到版本更新,当前页面数据已过期。点击【确定】立即刷新体验最新版本!')) { - cleanAndReload() - } else { - window._chunkErrorHandled = false - } } }) diff --git a/vite.config.js b/vite.config.js index 369958c..e2cfe3b 100644 --- a/vite.config.js +++ b/vite.config.js @@ -41,6 +41,11 @@ export default defineConfig({ build: { chunkSizeWarningLimit: 2000, rollupOptions: { + output: { + entryFileNames: 'assets/[name].js', + chunkFileNames: 'assets/[name].js', + assetFileNames: 'assets/[name].[ext]' + }, onwarn(warning, warn) { if (warning.code === 'UNRESOLVED_IMPORT' || warning.code === 'UNUSED_EXTERNAL_IMPORT') return; warn(warning);