假如我們同時(shí)引入了lodash和jquery

image.png
然后運(yùn)行打包npm run build,這個(gè)時(shí)候會報(bào)一個(gè)文件過大的警告

image.png
出現(xiàn)警告的原因是因?yàn)橥瑫r(shí)引入兩個(gè)庫,打包生成的文件會比較大,超過了要求的
244kb
image.png
其實(shí)這個(gè)警告并不影響我們代碼的運(yùn)行,怎么去掉這個(gè)警告呢? 在
webpack.common.js里加一個(gè)配置項(xiàng)就行了,這個(gè)配置項(xiàng)作用就是不讓webpack提示我們性能上的一些問題
image.png
之后運(yùn)行打包就沒有警告了,但是生成的打包文件名字太長了

image.png
此時(shí)我想打包出來的
lodash和jquery存放的文件名是我指定的,比如vendors.chunks.js該怎么配置呢?
image.png
然后再打包,就會生成我們想要的文件名

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

image.png
那么它的整個(gè)加載過程是這樣的:
- 首先訪問頁面(index.html),然后頁面會去請求兩個(gè)JS文件,
- 當(dāng)用戶第一次訪問的時(shí)候,這兩個(gè)JS文件是肯定會被請求的。
- 但是當(dāng)用戶第二次刷新頁面的時(shí)候,這兩個(gè)文件實(shí)際上已經(jīng)被保存在了瀏覽器里面,所以第二次訪問頁面的時(shí)候?yàn)g覽器會直接去拿緩存了。
問題來了,當(dāng)用戶第一次訪問過之后,還沒有進(jìn)行第二個(gè)訪問的時(shí)候,我們修改了源代碼,并打包后新生成的文件,上傳到了服務(wù)器,這樣當(dāng)用戶刷新的時(shí)候,他看到的是原來的老的內(nèi)容呢? 還是我們修改過的新的內(nèi)容呢?
- 實(shí)際上,如果用戶是普通刷新(而不是強(qiáng)制刷新),他拿到的還是我們之前展示的老的內(nèi)容。
-
因?yàn)?,就算是我們修改了?nèi)容,但是我們打包生成的新的文件,還是原來的文件名。還是下邊這幾個(gè)名字
image.png - 那么用戶再請求頁面的時(shí)候,瀏覽器發(fā)現(xiàn)這兩個(gè)文件,本地已經(jīng)有緩存了,就直接從緩存拿就行了,就不會用新上傳到服務(wù)器的文件了。這就是產(chǎn)生問題。
為了解決用戶瀏覽器上,緩存文件的問題,我們可以引入一個(gè)概念叫做content hash
- 我們對代碼做個(gè)變更,我們把
webpack.common.js里的output部分配置拿出來放到webpack.dev.js里
image.png
image.png - 因?yàn)殚_發(fā)環(huán)境下,我們不用去關(guān)注用戶緩存的問題,每次我都單獨(dú)打包然后刷新或者熱模塊更新,都會幫我們解決這個(gè)更新的問題。畢竟是開發(fā)環(huán)境。
- 上線的時(shí)候的配置也要改下,這里的
contenthash也是和name一樣的占位符
image.png - 如果我們的源代碼沒有改變,那么打包生成的
contenthash永遠(yuǎn)都不會變。因?yàn)樗歉鶕?jù)content產(chǎn)生的一個(gè)hash字符串。content不變hash字符串就不變。 - 我們來驗(yàn)證一下,先看下我們此時(shí)
index.js里的代碼
image.png -
然后我們運(yùn)行打包
image.png - 然后我們修改下
index.js的值
image.png -
然后再打包
image.png - 我們就會發(fā)現(xiàn),我們的邏輯代碼打包生成的文件的文件名里的
hash值變了。而我們引入的lodash和jquery庫因?yàn)闆]有變化,生成的文件的文件名里的hash值也就沒有變化。 - 所以,如果我們對源代碼做了變更,并且上傳到服務(wù)器,當(dāng)用戶再訪問的時(shí)候,因?yàn)轫撁嬉埱蟮腏S文件的文件名跟原來的不一樣,瀏覽器就不會去拿緩存了,就需要重新請求我們上傳的新的JS文件了。而vendos這個(gè)文件因?yàn)槲募麤]有變更,瀏覽器就會直接去緩存里拿
contenthash就是webpack去解決瀏覽器caching的方法
有的時(shí)候,如果我們是用的老一點(diǎn)的webpack4版本的時(shí)候會發(fā)現(xiàn),即便我們沒有去改變源代碼,但是兩次打包的時(shí)候,有可能contenthash也是不同的,這個(gè)時(shí)候需要我們額外的去做一個(gè)配置

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








