【115】vue-router使用懶載入機制,在生產環境中,如何避免瀏覽器快取Webpack 3 編譯後生成的js路徑,導致404錯誤。(一)
前言
為了適應不斷變化的市場需求,軟體產品需要持續部署。生產環境的部署週期往往短則一週,長則半個月。在這一持續部署的過程中,前端開發人員要面臨一個問題:生產環境部署了新版本的程式碼後,如果使用者沒有 F5 重新整理瀏覽器,就會導致瀏覽器快取Webpack 3 編譯後生成的js路徑,導致404錯誤。
使用者沒有 F5 重新整理瀏覽器的情況是有可能發生的。第一種可能發生的情況是使用者經常不關機,而是休眠。第二種可能發生的情況是:使用者開啟瀏覽器輸入網址,但是瀏覽器快取了 index.html 和引用的 js 檔案。
我準備寫兩篇文章來闡述如何解決這個問題。這篇文章重點講如何重現這種錯誤。
問題分析
Vue.js 加 Weppack 是現在常見的前端專案開發配置。如果允許 webpack 把所有程式碼打包到同一個 js 檔案中,會嚴重拖慢瀏覽器首屏載入速度,因此 vue-router 的懶載入機制就成為了必然的選擇。同時當用戶 F5 重新整理網站頁面的時候,為了避免 Webpack 打包生成的 js 檔案被瀏覽器快取,要用檔案的雜湊值來給 js 檔案命名。這會讓每次修改過的 vue 元件編譯生成全新命名的 js 檔案。你的專案很可能是這麼配置的:
output: {
path: path.resolve(__dirname, './dist'),
// 因為用到了 html-webpack-plugin 處理HTML檔案。處理後的HTML檔案都放到了
// dist資料夾裡。html檔案裡面js的相對路徑應該從使用 html-webpack-plugin 前
// 的'/dist/' 改成 '/'
publicPath: '/',
filename: '[name].[hash].js'
},
雖然上面的方法很好,能夠解決使用者 F5 重新整理瀏覽器時的快取問題。但是現實總是殘酷的,如果使用者在你部署完成後沒有 F5 重新整理頁面(比如使用者不關機,或者瀏覽器快取了index.html 及其 js),就會碰到一個新問題: 當Webpack 載入一個修改過且沒有快取下來的頁面的時候,因為 js 瀏覽器中儲存的是舊的 js 檔名,而 Nginx 中的是新的 js 檔名,導致瀏覽器報出 404 錯誤!!
有些人可能想到在夜深人靜的時候釋出程式碼,但這並不能解決問題。原因有二: 1. 到了第二天瀏覽器還是會快取 index.html 及其 js 檔案。 2. 部分使用者喜歡不關機,只是讓機器處於休眠狀態。
原始碼
問題重現
首先你需要在自己的機器上安裝一個伺服器。我自己使用了 Nginx 作為前端靜態資源的伺服器。因為我用了HTML5模式的前端路由,所以 Nginx 配置做以下修改:
開啟 Nginx 安裝目錄 / conf / nginx.conf 配置檔案,server 配置如下:
server {
listen 80;
server_name localhost;
location / {
root 'D:/workspaceSet/vsc/csdnBlog/blog115/dist';
try_files $uri $uri/ /index.html =404;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
blog115 中含有兩個頁面,分別是 home 和 page1,前端路由如下:
import index from './index.vue';
export default [
{
path:'/',
name: "index",
component:index,
children: [
{
path:"home",
name: "home",
component: ()=>import("./home.vue")
},
{
path: "page1",
name: "page1",
component: ()=>import("./page1.vue")
}
]
}
]
在blog115專案目錄下執行 npm run build
命令,會生成生產環境程式碼。在命令列中通過 cd 命令進入 Nginx 目錄下,執行 start nginx
命令,啟動 Nginx。瀏覽器位址列裡輸入 http://localhost
就可以看到頁面了,如下圖所示:
注意此時不要點選頭部“頁面1”的連結,因為這麼做會吧 page1.vue 快取到伺服器,我們就無法重現這個問題了。
然後開啟 page1.vue 的編輯器,隨便改點內容,再執行 npm run build
。為了確保伺服器上的內容已經更新,你可以重啟 Nginx 。然後在同一個瀏覽器標籤頁中開啟控制檯,點選“頁面1”連結,你就可以看到控制檯報錯了。內容類似下面圖片中的樣子:
這樣,我們就成功地重現了這個問題。