Vue開(kāi)發(fā)中出現(xiàn)Loading?Chunk?Failed的問(wèn)題解決
報(bào)錯(cuò)現(xiàn)象
某天測(cè)試反應(yīng)在點(diǎn)擊頁(yè)簽的時(shí)候出現(xiàn)了 Loading Chunk Failed 的錯(cuò)誤,經(jīng)過(guò)本人百度分析后判斷是異步組件在發(fā)包時(shí)舊資源被替換的問(wèn)題,然后一通CV操作之后發(fā)現(xiàn)問(wèn)題還是存在,于是便有如下探究。
發(fā)生原因
用戶在發(fā)包前進(jìn)入了頁(yè)面(也就是請(qǐng)求到了 index.html ),并且在 index.html 中可以得知將來(lái)要請(qǐng)求的異步組件的名字叫 a.js ,當(dāng)服務(wù)器這時(shí)候發(fā)包,并且清空掉了 a.js 這個(gè)資源,改名叫 a1.js 。發(fā)包之后用戶點(diǎn)擊 a.js 對(duì)應(yīng)的組件時(shí),瀏覽器拿著先前在 index.html 得知的 a.js 這個(gè)名字去服務(wù)器請(qǐng)求資源就得到了以上的 Loading Chunk Failed 報(bào)錯(cuò)。
正常的生產(chǎn)上線流程可能存在靜態(tài)資源和頁(yè)面分屬不同服務(wù)器,應(yīng)該是先全量部署靜態(tài)資源(各種js,css,圖片),不清空舊資源,然后再部署頁(yè)面。但如果清空掉舊資源就可能導(dǎo)致報(bào)錯(cuò)。
如果在測(cè)試環(huán)境中可能會(huì)采取清空覆蓋掉舊資源,這個(gè)時(shí)候就必須要前端進(jìn)行控制了。
解決思路
- 在監(jiān)聽(tīng)到路由報(bào)錯(cuò)的時(shí)候,前端強(qiáng)制刷新頁(yè)面,重新獲取index.html和對(duì)應(yīng)的靜態(tài)資源路徑。
- 設(shè)置preFetch,網(wǎng)絡(luò)空閑的時(shí)候就請(qǐng)求資源,可以大幅降低報(bào)錯(cuò)的幾率。
觸發(fā)bug
想要解決問(wèn)題首先就是得復(fù)現(xiàn)問(wèn)題,涉及到發(fā)包上線的測(cè)試和驗(yàn)證都有點(diǎn)小尷尬,因此提供下個(gè)人思路
- 最直接的就是你開(kāi)個(gè)頁(yè)面,然后控制臺(tái)網(wǎng)絡(luò)禁用掉緩存,然后發(fā)包后進(jìn)入其他異步組件觸發(fā)bug。
- 如果想要觸發(fā) onError 這個(gè)鉤子的話,直接斷開(kāi) devServer 就可以了。
- 本地復(fù)現(xiàn)的話就是開(kāi)個(gè)本地服務(wù)器,然后進(jìn)入頁(yè)面,把 dist 文件夾中對(duì)應(yīng)的js文件刪去即可觸發(fā)。
代碼實(shí)現(xiàn)
?/* 正則使用'\S'而不是'\d' 為了適配寫(xiě)魔法注釋的朋友,寫(xiě)'\d'遇到魔法注釋就匹配不成功了。 ??* 使用reload方法而不是replace原因是replace還是去請(qǐng)求之前的js文件,會(huì)導(dǎo)致循環(huán)報(bào)錯(cuò)。 ? * reload會(huì)刷新頁(yè)面, 請(qǐng)求最新的index.html以及最新的js路徑。 ??* 直接修改location.href或使用location.assign或location.replace,和router.replace同理,? ? * 在當(dāng)前場(chǎng)景中請(qǐng)求的依然是原來(lái)的js文件,區(qū)別僅有瀏覽器的歷史棧。因此必須采用reload. ??* reload()有個(gè)特點(diǎn)是當(dāng)你在A頁(yè)面試圖進(jìn)入B頁(yè)面的時(shí)候報(bào)錯(cuò),會(huì)在A頁(yè)面刷新,因此在刷新后需要手動(dòng)書(shū)寫(xiě)邏輯 ? * 進(jìn)入B頁(yè)面,可以在router.onReady()方法里面書(shū)寫(xiě) ? * 為了避免在特殊情況下服務(wù)器丟失資源導(dǎo)致無(wú)限報(bào)錯(cuò)刷新,做了一步控制,僅嘗試一次進(jìn)入B頁(yè)面, ? * 如果不成功就只刷新A頁(yè)面,停留在當(dāng)前的A頁(yè)面。 ??*/ ?? ?? ?router.onError((error) => { ???const jsPattern = /Loading chunk (\S)+ failed/g ???const cssPattern = /Loading CSS chunk (\S)+ failed/g ???const isChunkLoadFailed = error.message.match(jsPattern || cssPattern) ???const targetPath = router.history.pending.fullPath ???if (isChunkLoadFailed) { ?????localStorage.setItem('targetPath', targetPath) ?????window.location.reload() ?? } ?}) ?? ?router.onReady(() => { ???const targetPath = localStorage.getItem('targetPath') ???const tryReload = localStorage.getItem('tryReload') ???if (targetPath) { ?????localStorage.removeItem('targetPath') ?????if (!tryReload) { ???????router.replace(targetPath) ???????localStorage.setItem('tryReload', true) ???? } else { ???????localStorage.removeItem('tryReload') ???? } ?? } ?})
一點(diǎn)思考
我之前提到過(guò)異步組件而不是路由懶加載導(dǎo)致了這個(gè)問(wèn)題的發(fā)生,有趣的是,當(dāng)你子組件是用懶加載方式進(jìn)行,并且沒(méi)有設(shè)置或者關(guān)閉了preFetch,且之前沒(méi)有緩存。很可能也會(huì)報(bào)這種錯(cuò)。在網(wǎng)絡(luò)中和路由懶加載一樣是報(bào) 404 找不到對(duì)應(yīng)資源,區(qū)別就是不會(huì)報(bào) loadingChunkError 的錯(cuò)誤。
設(shè)置緩存策略中頁(yè)面一定要對(duì)頁(yè)面( inedx.html )設(shè)置no cache no store,避免依然指向舊的已被刪除的資源,只有Get方式獲取的資源才可以設(shè)置緩存策略。
到此這篇關(guān)于Vue開(kāi)發(fā)中出現(xiàn)Loading Chunk Failed的問(wèn)題解決的文章就介紹到這了,更多相關(guān)Vue Loading Chunk Failed內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+axios 攔截器實(shí)現(xiàn)統(tǒng)一token的案例
這篇文章主要介紹了vue+axios 攔截器實(shí)現(xiàn)統(tǒng)一token的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Vue項(xiàng)目中使用iView組件庫(kù)設(shè)置樣式不生效的解決方案
這篇文章主要介紹了Vue項(xiàng)目中使用iView組件庫(kù)設(shè)置樣式不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09vue實(shí)現(xiàn)同一個(gè)頁(yè)面可以有多個(gè)router-view的方法
今天小編就為大家分享一篇vue實(shí)現(xiàn)同一個(gè)頁(yè)面可以有多個(gè)router-view的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue使用video插件vue-video-player的示例
這篇文章主要介紹了vue使用video插件vue-video-player的示例,幫助大家更好的理解和使用vue插件,感興趣的朋友可以了解下2020-10-10vue2.0使用Sortable.js實(shí)現(xiàn)的拖拽功能示例
本篇文章主要介紹了vue2.0使用Sortable.js實(shí)現(xiàn)的拖拽功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02Vue+Element實(shí)現(xiàn)網(wǎng)頁(yè)版?zhèn)€人簡(jiǎn)歷系統(tǒng)(推薦)
這篇文章主要介紹了Vue+Element實(shí)現(xiàn)網(wǎng)頁(yè)版?zhèn)€人簡(jiǎn)歷系統(tǒng),需要的朋友可以參考下2019-12-12vuex提交state&&實(shí)時(shí)監(jiān)聽(tīng)state數(shù)據(jù)的改變方法
今天小編就為大家分享一篇vuex提交state&&實(shí)時(shí)監(jiān)聽(tīng)state數(shù)據(jù)的改變方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09