fix: 撤销弹窗及强制跳回机制;在 vite 中去除 Chunk 打包 Hash,并给服务端路由补充无 Hash 回退机制,从物理上消灭缓存旧引用导致的死锁 404
This commit is contained in:
parent
1308bf86fd
commit
e2ada92510
|
|
@ -94,11 +94,30 @@ const matchFile = async (request, response) => {
|
|||
if (fs.existsSync(mappedPath)) {
|
||||
targetPath = mappedPath
|
||||
} else if (cleanPath.startsWith('/assets/')) {
|
||||
// 如果请求的是带 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) => {
|
||||
if (!err) {
|
||||
|
|
|
|||
|
|
@ -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 isReloaded = sessionStorage.getItem('chunk_reload_flag')
|
||||
if (!isReloaded) {
|
||||
sessionStorage.setItem('chunk_reload_flag', 'true')
|
||||
const forceReload = () => {
|
||||
// 不再重载当前错误路径,直接跳回首页,并带上时间戳跳出 CDN 缓存
|
||||
window.location.href = window.location.origin + '/?t=' + Date.now()
|
||||
const url = new URL(window.location.href)
|
||||
url.searchParams.set('t', Date.now())
|
||||
window.location.href = url.href
|
||||
}
|
||||
|
||||
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) {}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue