您好,登錄后才能下訂單哦!
最近有個Vue項目中會偶爾出現Loading chunk {n} failed
的報錯,報錯來自于webpack進行code spilt之后某些bundle文件lazy loading失敗。但是這個問題的根本原因沒有被找到,因為這個問題出現的偶然性太高了,而且有的手機上會出現,有的不會,用模擬器不會出現,用真機又會出現,不知道是網絡原因還是webpack的bug。在github、stackoverflow等各種地方也找不到原因和解決方案,這是github上關于這個問題的討論:Loading chunk {n} failed #742,雖然最后還是不了了之,但是大家可以參考一下。
這個問題出現概率比較小但是一旦出現就會導致頁面崩潰,所以還是得解決,下面就貼出我的解決方案:
我的思路是既然找不到報錯的原因那么嘗試去捕獲這個錯誤并做容錯處理,有兩種實現,一是在服務端捕獲這個錯誤,一個是在前端捕獲。
服務端實現
報錯的原因是某些js bundle沒有被找到,所以在服務端接收到獲取該js文件的請求時先判斷該js文件是否存在,如果存在直接返回js文件,如果不存在則返回一個提示信息給前端,讓前端處理。假設服務端用express作為靜態文件服務器,代碼如下:
app.all(/\.js$/, (req, res) => { const fileName = req.path.slice(req.path.lastIndexOf('/') + 1); const filePath = path.resolve(__dirname, './public/static/js/' + fileName); if (fs.existsSync(filePath)) { fs.sendFile(filePath); } else { res.setHeader('Content-Type', 'application/javascript; charset=UTF-8') res.setHeader('Accept-Ranges', 'bytes') res.setHeader('Vary', 'Accept-Encoding') res.setHeader('Transfer-Encoding', 'chunked') res.setHeader('Last-Modified', new Date().toUTCString()) res.setHeader('Cache-Control', 'no-cache') res.send('window.serverRebuildHook && window.serverRebuildHook();') } });
當js文件未找到時,通過res.send('window.serverRebuildHook && window.serverRebuildHook();')
向前端返回一條消息,并執行前端定義的serverRebuildHook
方法。
接著我們在前端實現serverRebuildHook
方法:
window.serverRebuildHook = function () { alert('服務器版本已更新,正在刷新本地緩存,請稍后...'); location.replace(location.href); }
方法很簡單,提示一下用戶服務端更新然后重新刷新當前頁面。
這種實現是參考github上的回答, 相對比較繁瑣,而且用戶體驗并不好,只能刷新當前頁面,不能跳轉到目標頁。
前端實現
由于項目里面用到了vue-router,vue-router的錯誤處理函數 onError 是不是能夠捕獲該錯誤呢?我們來看一下官方文檔的說明:
當在渲染一個路由的過程中,需要嘗試解析一個異步組件時發生錯誤。 完全符合我們場景,所以在onError方法中我們實現如下代碼:
router.onError((error) => { const pattern = /Loading chunk (\d)+ failed/g; const isChunkLoadFailed = error.message.match(pattern); const targetPath = router.history.pending.fullPath; if (isChunkLoadFailed) { router.replace(targetPath); } });
當捕獲到Loading chunk {n} failed
的錯誤時我們重新渲染目標頁面,這種實現明顯更簡單和友好。
后續如果發現了導致Loading chunk {n} failed
的本質原因會再更新本文,歡迎關注!
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。