溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

詳解Vue項目中出現(xiàn)Loading chunk {n} failed問題的解決方法

發(fā)布時間:2020-10-04 10:01:39 來源:腳本之家 閱讀:319 作者:MudOnTire 欄目:web開發(fā)

最近有個Vue項目中會偶爾出現(xiàn)Loading chunk {n} failed的報錯,報錯來自于webpack進行code spilt之后某些bundle文件lazy loading失敗。但是這個問題的根本原因沒有被找到,因為這個問題出現(xiàn)的偶然性太高了,而且有的手機上會出現(xiàn),有的不會,用模擬器不會出現(xiàn),用真機又會出現(xiàn),不知道是網(wǎng)絡(luò)原因還是webpack的bug。在github、stackoverflow等各種地方也找不到原因和解決方案,這是github上關(guān)于這個問題的討論:Loading chunk {n} failed #742,雖然最后還是不了了之,但是大家可以參考一下。

這個問題出現(xiàn)概率比較小但是一旦出現(xiàn)就會導(dǎo)致頁面崩潰,所以還是得解決,下面就貼出我的解決方案:

我的思路是既然找不到報錯的原因那么嘗試去捕獲這個錯誤并做容錯處理,有兩種實現(xiàn),一是在服務(wù)端捕獲這個錯誤,一個是在前端捕獲。

服務(wù)端實現(xiàn)

報錯的原因是某些js bundle沒有被找到,所以在服務(wù)端接收到獲取該js文件的請求時先判斷該js文件是否存在,如果存在直接返回js文件,如果不存在則返回一個提示信息給前端,讓前端處理。假設(shè)服務(wù)端用express作為靜態(tài)文件服務(wù)器,代碼如下:

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();')
  }
});

當(dāng)js文件未找到時,通過res.send('window.serverRebuildHook && window.serverRebuildHook();')向前端返回一條消息,并執(zhí)行前端定義的serverRebuildHook方法。

接著我們在前端實現(xiàn)serverRebuildHook方法:

window.serverRebuildHook = function () {
 alert('服務(wù)器版本已更新,正在刷新本地緩存,請稍后...');
 location.replace(location.href);
}

方法很簡單,提示一下用戶服務(wù)端更新然后重新刷新當(dāng)前頁面。

這種實現(xiàn)是參考github上的回答, 相對比較繁瑣,而且用戶體驗并不好,只能刷新當(dāng)前頁面,不能跳轉(zhuǎn)到目標頁。

前端實現(xiàn)

由于項目里面用到了vue-router,vue-router的錯誤處理函數(shù) onError 是不是能夠捕獲該錯誤呢?我們來看一下官方文檔的說明:

詳解Vue項目中出現(xiàn)Loading chunk {n} failed問題的解決方法

當(dāng)在渲染一個路由的過程中,需要嘗試解析一個異步組件時發(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);
 }
});

當(dāng)捕獲到Loading chunk {n} failed的錯誤時我們重新渲染目標頁面,這種實現(xiàn)明顯更簡單和友好。

后續(xù)如果發(fā)現(xiàn)了導(dǎo)致Loading chunk {n} failed的本質(zhì)原因會再更新本文,歡迎關(guān)注!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI