Vue 熱更新成功,但瀏覽器不刷新

最近在更新個人主頁,這個主題看夠了,就想換另一個。但是今天突然發現我的 Vue 不能熱更新?費了一會勁才搞明白怎麼回事。下面就分享一下我的入坑,出坑過程吧。

webpack-dev-server 炸了?

一開始我還真的以爲是 HMR 不工作了,所以這裏陷入了一個大坑,這裏省略 1 個小時的搜索。。。

後面細心我的發現改了代碼後,命令行是有顯示在編譯的。

嗯。。。說明熱更新是沒問題,可能是更新,但是更新到瀏覽器這一步不行了,或者說 webpack-dev-server 沒有真正地通知到瀏覽器,所以沒有刷新。

然後又搜了一波“Vue 瀏覽器無法正常刷新”,這裏省略1小時的糾結。。。

sockjs-node

後面無聊點開了 Network 看到下面的報錯:

好奇點開這個請求詳情:

這裏我關注了到了 Request URL: http://172.20.10.2:8080/sockjs-node/info?t=1590456177387。這裏有 "sockjs" 字眼,嗯,sock?socket !!!!(此時應該有BGM)

我可以合理地提出自己的一個猜想:webpack-dev-server 和瀏覽器應該是一個雙工的過程。因爲第一次連接沒有連接上,瀏覽器就根本沒有在監聽 webpack-dev-server,所以代碼改了,瀏覽器並沒不知道!

爲了驗證我的猜想,我查了下這個請求,發現了 sockjs-node 這個庫,https://github.com/sockjs/sockjs-node,果然是一個 websocket 的東西。同時,我還查了很多中文的垃圾博客,爲什麼要說垃圾,因爲抄襲。

回到問題本身,根據上面的這些博客,可以知道 sockjs-node 是一個:

首先,sockjs-node是何方神聖?不難查出,sockjs-node是一個JavaScript庫,提供跨瀏覽器JavaScript的API,創建了一個低延遲、全雙工的瀏覽器和web服務器之間通信通道。 —— 來自各種抄襲博客

那問題就變簡單了,只要搞清楚爲什麼不能響應這個請求就好了。

都是 VPN 的鍋

因爲在查資料和嘗試各路方法的時候,我總會不斷重啓我的 Vue 項目。然後有一次,瀏覽器竟然可以自動刷新了。此時的我還清楚地記得我在重啓前把 VPN 關了,因爲之前要裝個 npm 包。

然後我嘗試了幾次,只要開 VPN 就炸,關了 VPN 就成功了。所以這次我搜索的內容變成了 “Vue 熱更新 VPN”,搜了幾次發現了這篇文章:https://blog.csdn.net/gulang03/article/details/89217273

裏面遇到的就是我的問題,這裏總結一下,因爲這個 Request 的地址是局域網的地址,而我用了 VPN 代理,它就會當成是 public address 去請求。一個是局域的,一個 public address ,那肯定是無法響應的嘛。

OK,到此爲止,其實已經有兩種解決方法了:

  1. 把當前 IP 加到 VPN 的 exclude list
  2. 每次項目重啓的時候,把 VPN 關了。之後是可以再次打開的,因爲只要第一次 websocket 連接成功後,後面就可以正常通信了。不過,刷新就不行了,因爲每次刷新又得創建連接。

修改 host

仔細想想,問題不就是因爲他用了 public address 所以無法建立連接麼?那爲什麼不直接把 http://172.20.10.2:8080/sockjs-node/info?t=1590456177387
改成 http://localhost:8080/sockjs-node/info?t=1590456177387。別用 172.20.10.2,用 localhost 唄,這肯定是能訪問到本機的呀。

所以我又開始搜索 “Vue How to change sockjs-node host”,搜出了兩遍比較好的 Github Issue。

第一篇 https://github.com/gtalarico/django-vue-template/issues/5 和我的問題有的類似,也是上面這個請求無法訪問了。不過他好像是 Django 的問題。但是上面給的方法是可以解決的。

在 package.json 改成 "server": "vue-cli-service serve --host 127.0.0.1 --port 8080"。這樣 host 就是 127.0.0.0 訪問的就是本機了。

另一篇 https://github.com/vuejs/vue-cli/issues/1525 說的就是 Vue 這個 cli 的 websocket 就是連不上,怎麼修改 Host 的。這裏的解決方法也差不多。

在 vue.config.js 裏添加 devServer 的配置:

module.exports = {
  ...
  devServer: {
    host: '0.0.0.0',
    public: '0.0.0.0:8080',
    disableHostCheck: true
  }
}

這樣訪問的還是本機,websocket 也是可以成功建立的。

但是,這裏也有不好的地方,它改了 Network。你可能會問,改了 Network 怎麼了?先看看原來是怎麼樣的:

一個是本地的地址,一個是公開的地址,有了公開的地址就可以在手機裏調試呀。不然每次都要 ifconfig 去找本機的 IP,好麻煩。而且別人看到你提交的代碼可能會過來找你。

總強

總結一下,問題其實就是因爲開了代理,代理以爲你的局域網地址是 public address,所以並不能得到響應。因此 webpack-dev-server 和瀏覽器的雙工通信沒有成功連接,瀏覽器就無法監聽到 webpack-dev-server 的熱更新。最後瀏覽器就變成了憨憨。

解決方法有下面幾種:

  1. 每次開 Vue 項目時候,先關了 VPN。等項目啓動了再開 VPN,因爲雙工通信只要第一次連接好了,後面就能正常通信了,VPN 再也不會搗亂。缺點是不能刷新,一刷新又會發 Request了。
  2. 把當前 IP 地址加到 VPN 的 exclude list。這樣就還是會訪問局域地址,不會以爲它是 public addresss。
  3. 修改請求的 Host:
    3.1 可以在 package.json 裏改成 "server": "vue-cli-service serve --host 127.0.0.1 --port 8080"
    3.2 或者在 vue.config.js 裏添加
module.exports = {
  ...
  devServer: {
    host: '0.0.0.0',
    public: '0.0.0.0:8080',
    disableHostCheck: true
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章