首頁 > 軟體

Vue開發中出現Loading Chunk Failed的問題解決

2022-03-29 19:00:14

報錯現象

某天測試反應在點選頁籤的時候出現了 Loading Chunk Failed 的錯誤,經過本人百度分析後判斷是非同步元件在發包時舊資源被替換的問題,然後一通CV操作之後發現問題還是存在,於是便有如下探究。

發生原因

使用者在發包前進入了頁面(也就是請求到了 index.html ),並且在 index.html 中可以得知將來要請求的非同步元件的名字叫 a.js ,當伺服器這時候發包,並且清空掉了 a.js 這個資源,改名叫 a1.js 。發包之後使用者點選 a.js 對應的元件時,瀏覽器拿著先前在 index.html 得知的 a.js 這個名字去伺服器請求資源就得到了以上的 Loading Chunk Failed 報錯。

正常的生產上線流程可能存在靜態資源和頁面分屬不同伺服器,應該是先全量部署靜態資源(各種js,css,圖片),不清空舊資源,然後再部署頁面。但如果清空掉舊資源就可能導致報錯。

如果在測試環境中可能會採取清空覆蓋掉舊資源,這個時候就必須要前端進行控制了。

解決思路

  • 在監聽到路由報錯的時候,前端強制重新整理頁面,重新獲取index.html和對應的靜態資源路徑。
  • 設定preFetch,網路空閒的時候就請求資源,可以大幅降低報錯的機率。

觸發bug

想要解決問題首先就是得復現問題,涉及到發包上線的測試和驗證都有點小尷尬,因此提供下個人思路

  • 最直接的就是你開個頁面,然後控制檯網路禁用掉快取,然後發包後進入其他非同步元件觸發bug。
  • 如果想要觸發 onError 這個勾點的話,直接斷開 devServer 就可以了。
  • 本地復現的話就是開個本地伺服器,然後進入頁面,把 dist 資料夾中對應的js檔案刪去即可觸發。

程式碼實現

 /* 正則使用'S'而不是'd' 為了適配寫魔法註釋的朋友,寫'd'遇到魔法註釋就匹配不成功了。
  * 使用reload方法而不是replace原因是replace還是去請求之前的js檔案,會導致迴圈報錯。
  * reload會重新整理頁面, 請求最新的index.html以及最新的js路徑。
  * 直接修改location.href或使用location.assign或location.replace,和router.replace同理, 
  * 在當前場景中請求的依然是原來的js檔案,區別僅有瀏覽器的歷史棧。因此必須採用reload.
  * reload()有個特點是當你在A頁面試圖進入B頁面的時候報錯,會在A頁面重新整理,因此在重新整理後需要手動書寫邏輯
  * 進入B頁面,可以在router.onReady()方法裡面書寫
  * 為了避免在特殊情況下伺服器丟失資源導致無限報錯重新整理,做了一步控制,僅嘗試一次進入B頁面,
  * 如果不成功就只重新整理A頁面,停留在當前的A頁面。
  */
 ​
 ​
 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')
     }
   }
 })

一點思考

我之前提到過非同步元件而不是路由懶載入導致了這個問題的發生,有趣的是,當你子元件是用懶載入方式進行,並且沒有設定或者關閉了preFetch,且之前沒有快取。很可能也會報這種錯。在網路中和路由懶載入一樣是報 404 找不到對應資源,區別就是不會報 loadingChunkError 的錯誤。

設定快取策略中頁面一定要對頁面( inedx.html )設定no cache no store,避免依然指向舊的已被刪除的資源,只有Get方式獲取的資源才可以設定快取策略。

到此這篇關於Vue開發中出現Loading Chunk Failed的問題解決的文章就介紹到這了,更多相關Vue Loading Chunk Failed內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com