實(shí)際上,當(dāng)我們打包之后,生成的dist目錄下的這幾個(gè)文件,
應(yīng)該是交給后端放到服務(wù)器上,服務(wù)器上就可以運(yùn)行這些文件。
假設(shè),我們已經(jīng)把代碼放到了服務(wù)器上運(yùn)行了

假如我們我們現(xiàn)在的代碼跑在服務(wù)器上,
那么它的請(qǐng)求過程,它的整個(gè)加載過程是這樣的:
- 首先訪問頁(yè)面(index.html),然后頁(yè)面會(huì)去請(qǐng)求兩個(gè)JS文件,
- 當(dāng)用戶第一次訪問的時(shí)候,這兩個(gè)JS文件是肯定會(huì)被請(qǐng)求的。
- 但是當(dāng)用戶第二次刷新頁(yè)面的時(shí)候,這兩個(gè)文件實(shí)際上已經(jīng)被保存在了瀏覽器里面,
所以第二次訪問頁(yè)面的時(shí)候?yàn)g覽器會(huì)直接去拿緩存了。
問題來(lái)了,當(dāng)用戶第一次訪問過之后,
還沒有進(jìn)行第二個(gè)訪問的時(shí)候,
我們修改了源代碼,并打包后新生成的文件,上傳到了服務(wù)器,
這樣當(dāng)用戶刷新的時(shí)候,他看到的是原來(lái)的老的內(nèi)容呢? 還是我們修改過的新的內(nèi)容呢?
實(shí)際上,如果用戶是普通刷新(而不是強(qiáng)制刷新),
他拿到的還是我們之前展示的老的內(nèi)容。因?yàn)椋退闶俏覀冃薷牧藘?nèi)容,
但是我們打包生成的新的文件,還是原來(lái)的文件名。
還是下邊這幾個(gè)名字那么用戶再請(qǐng)求頁(yè)面的時(shí)候,瀏覽器發(fā)現(xiàn)這兩個(gè)文件,本地已經(jīng)有緩存了,
就直接從緩存拿就行了,就不會(huì)用新上傳到服務(wù)器的文件了。
這就是產(chǎn)生問題。

為了解決用戶瀏覽器上,緩存文件的問題,
我們可以引入一個(gè)概念叫做content hash
-
我們對(duì)代碼做個(gè)變更,
我們把webpack.common.js里的output部分配置拿出來(lái)放到webpack.dev.js里imageimage 因?yàn)?code>開發(fā)環(huán)境下,我們不用去關(guān)注用戶緩存的問題,
每次我都單獨(dú)打包然后刷新或者熱模塊更新,都會(huì)幫我們解決這個(gè)更新的問題。
畢竟是開發(fā)環(huán)境。-
上線的時(shí)候的配置也要改下,這里的
contenthash也是和name一樣的占位符image 如果我們的源代碼沒有改變,
那么打包生成的contenthash永遠(yuǎn)都不會(huì)變。
因?yàn)樗歉鶕?jù)content產(chǎn)生的一個(gè)hash字符串。content不變hash字符串就不變。-
我們來(lái)驗(yàn)證一下,先看下我們此時(shí)
index.js里的代碼image -
然后我們運(yùn)行打包
image -
然后我們修改下
index.js的值image -
然后再打包
image 我們就會(huì)發(fā)現(xiàn),我們的
邏輯代碼打包生成的文件的文件名里的hash值變了。
而我們引入的lodash和jquery庫(kù)因?yàn)闆]有變化,生成的文件的文件名里的hash值也就沒有變化。
所以,如果我們對(duì)源代碼做了變更,并且上傳到服務(wù)器,
當(dāng)用戶再訪問的時(shí)候,因?yàn)轫?yè)面要請(qǐng)求的JS文件的文件名跟原來(lái)的不一樣,瀏覽器就不會(huì)去拿緩存了,
就需要重新請(qǐng)求我們上傳的新的JS文件了。
而vendos這個(gè)文件因?yàn)槲募麤]有變更,瀏覽器就會(huì)直接去緩存里拿
此時(shí)重新打包代碼,把代碼上線,
就會(huì)把dist目錄扔到線上去,
用戶再去訪問線上的頁(yè)面的時(shí)候,
流程:
會(huì)打開線上的index.html,
去加載vendors.xxxxx.js和main.xxxxx.js,
vendors.xxxxx.js和之前請(qǐng)求的vendors.xxxxx.js名字一模一樣,就可以用本的緩存,
而mian.哈希值.js對(duì)應(yīng)的哈希值變了,
所以它必須的到我們的服務(wù)器上重新的加載新的main.哈希值.js,
通過contenthash這種方式,
我們可以做到 當(dāng)我們重新打包代碼上線的時(shí)候,
用戶只需要更新我們有變化的代碼,而沒有變化的代碼 用戶可以直接用它本地的緩存
就是webpack去解決瀏覽器caching的方法
有的時(shí)候,如果我們是用的老一點(diǎn)的webpack4版本的時(shí)候會(huì)發(fā)現(xiàn),
即便我們沒有去改變?cè)创a,但是兩次打包的時(shí)候,有可能contenthash也是不同的,
這個(gè)時(shí)候需要我們額外的去做一個(gè)配置

當(dāng)然了新版本webpack這樣配置也是沒有問題的。
-
運(yùn)行打包的時(shí)候,會(huì)多出一個(gè)runtime文件
image
實(shí)際上,當(dāng)我們?cè)谧鯼webpack`打包的時(shí)候,
main.js放置的是我們的業(yè)務(wù)邏輯,
vendors.js放置的是我們的庫(kù),
但是我們的業(yè)務(wù)邏輯和我們的庫(kù)之間,也是有關(guān)聯(lián)的,
這個(gè)關(guān)聯(lián)邏輯處理內(nèi)置的代碼叫做`manifest`,
默認(rèn)manifest是既存在于main.js里,也存在于vendors.js里邊的,
manifest每次打包的時(shí)候,
在舊版的`webpack`中可能會(huì)有差異,
正是因?yàn)樗牟町悓?dǎo)致了每次打包的時(shí)候,
雖然我們沒有改變?cè)创a,但是main和vendors里的代碼也都跟著改變了,
這就是為什么老版本的webpack,
即便我們沒有去改變?cè)创a,
兩次打包的`contenthash`也發(fā)生變化了。
當(dāng)我們配置了`runtimeChunk`,就把`manifest`這一塊關(guān)系相關(guān)的代碼抽離出來(lái),
單獨(dú)放到了`runtime`這樣一個(gè)文件里面去,
這樣的話,`main.js`里就放業(yè)務(wù)邏輯,`vendors.js`里就放我們的庫(kù),
而他們之間的關(guān)系代碼都放到`runtime`文件里去,
這樣,在老版本里,無(wú)論我們?cè)趺创虬?main對(duì)應(yīng)的contenthash和vendors對(duì)應(yīng)的contenthash都不會(huì)發(fā)生變化了。
因?yàn)樗麄儍蓚€(gè)里邊不會(huì)有manifest的代碼了。







