詳解Vue項目中出現(xiàn)Loading chunk {n} failed問題的解決方法
最近有個Vue項目中會偶爾出現(xiàn)Loading chunk {n} failed的報錯,報錯來自于webpack進行code spilt之后某些bundle文件lazy loading失敗。但是這個問題的根本原因沒有被找到,因為這個問題出現(xiàn)的偶然性太高了,而且有的手機上會出現(xiàn),有的不會,用模擬器不會出現(xiàn),用真機又會出現(xiàn),不知道是網(wǎng)絡原因還是webpack的bug。在github、stackoverflow等各種地方也找不到原因和解決方案,這是github上關于這個問題的討論:Loading chunk {n} failed #742,雖然最后還是不了了之,但是大家可以參考一下。
這個問題出現(xiàn)概率比較小但是一旦出現(xiàn)就會導致頁面崩潰,所以還是得解決,下面就貼出我的解決方案:
我的思路是既然找不到報錯的原因那么嘗試去捕獲這個錯誤并做容錯處理,有兩種實現(xiàn),一是在服務端捕獲這個錯誤,一個是在前端捕獲。
服務端實現(xiàn)
報錯的原因是某些js bundle沒有被找到,所以在服務端接收到獲取該js文件的請求時先判斷該js文件是否存在,如果存在直接返回js文件,如果不存在則返回一個提示信息給前端,讓前端處理。假設服務端用express作為靜態(tài)文件服務器,代碼如下:
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();')向前端返回一條消息,并執(zhí)行前端定義的serverRebuildHook方法。
接著我們在前端實現(xiàn)serverRebuildHook方法:
window.serverRebuildHook = function () {
alert('服務器版本已更新,正在刷新本地緩存,請稍后...');
location.replace(location.href);
}
方法很簡單,提示一下用戶服務端更新然后重新刷新當前頁面。
這種實現(xiàn)是參考github上的回答, 相對比較繁瑣,而且用戶體驗并不好,只能刷新當前頁面,不能跳轉到目標頁。
前端實現(xiàn)
由于項目里面用到了vue-router,vue-router的錯誤處理函數(shù) onError 是不是能夠捕獲該錯誤呢?我們來看一下官方文檔的說明:

當在渲染一個路由的過程中,需要嘗試解析一個異步組件時發(fā)生錯誤。 完全符合我們場景,所以在onError方法中我們實現(xiàn)如下代碼:
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的錯誤時我們重新渲染目標頁面,這種實現(xiàn)明顯更簡單和友好。
后續(xù)如果發(fā)現(xiàn)了導致Loading chunk {n} failed的本質原因會再更新本文,歡迎關注!
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Vue中引入bootstrap.min.css的正確姿勢分享
這篇文章主要介紹了Vue中引入bootstrap.min.css的正確姿勢,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10

