Webpack原理與實(shí)踐之如何讓你的模塊支持熱替換?
寫在前面
在上一文中介紹了《如何使用DevServer提高你的本地開發(fā)效率》,在配置好DevServer可以讓我們更加專注業(yè)務(wù)編碼,可以實(shí)現(xiàn)代碼更新來讓頁面樣式重新渲染。但是當(dāng)我們使用DevServer去自動刷新時(shí),例如在進(jìn)行編輯器開發(fā)修改了文本樣式,會刷新頁面編輯器文本丟失,不能實(shí)時(shí)顯示樣式。當(dāng)然我們也有對應(yīng)的解決方法,例如:
- 可以回到代碼中寫死文本內(nèi)容到編輯器中,這樣即使頁面刷新,也不會丟失內(nèi)容
- 通過代碼將編輯器中的內(nèi)容及時(shí)保存到localStorage中,刷新后再重新獲取 但是,這些方法存在不足,只是有漏補(bǔ)漏的措施,并沒有根本解決問題,并不適合代碼的維護(hù)。這時(shí)候webpack就提供了模塊熱替換HMR來解決我們的問題。
模塊熱替換HMR
HMR全稱 Hot Module Replacement,即為"模塊熱替換"或"模塊熱更新"。在計(jì)算機(jī)領(lǐng)域有個(gè)"熱插拔"的概念,指的是在正在運(yùn)行的計(jì)算機(jī)設(shè)備上插拔設(shè)備,并不會影響計(jì)算機(jī)的正常運(yùn)行,插上去的設(shè)備能夠立刻工作。這里的"熱"指的是在運(yùn)行過程中的即時(shí)變化。
HMR已經(jīng)集成在webpack模塊中,所以不需要再單獨(dú)安裝模塊,在運(yùn)行webpack-dev-server命令時(shí),通過--hot參數(shù)去開啟這個(gè)特性,或者也可以在配置文件中通過添加對應(yīng)的配置來開啟這個(gè)功能,這里需要配置兩個(gè)地方:
- 需要將devServer對象中的hot屬性設(shè)置為true
- 需要載入一個(gè)插件,這個(gè)插件是webpack內(nèi)置的一個(gè)插件,所以先導(dǎo)入webpack模塊,有了模塊后就可以使用一個(gè)叫做HotModuleReplacementPlugin插件。
- const webpack = require("webpack")
- module.exports ={
- devServer:{
- // 開啟HMR特性,如果資源不支持HMR會fallback到live reloading
- hot: true
- // 只使用HMR,不會fallback到live reloading
- // hotOnly:true
- },
- plugins:[
- // HMR特性所需要的插件
- new webpack.HotModuleReplacementPlugin()
- ]
- }
至于為什么我們開啟HMR過后,樣式文件的修改就可以直接熱更新呢,而且我們并沒有手動處理樣式模塊的更新?這是因?yàn)闃邮轿募墙?jīng)過Loader處理的,在style-loader中就已經(jīng)自動處理了樣式文件的熱更新,所以就不需要我們額外手動去處理。
那么什么樣式可以自動更新處理呢,然而我們的腳本文件卻需要自己手動處理?這是因?yàn)闃邮侥K更新后,只需要將更新后的css及時(shí)替換到頁面中,這樣就可以覆蓋掉之前的樣式,從而實(shí)現(xiàn)更新。
然而我們在使用vue-cli或者create-react-app框架腳手架工具時(shí),可能沒有進(jìn)行手動處理,js代碼照樣可以實(shí)現(xiàn)熱替換。這是因?yàn)槲覀冊谑褂每蚣艿臅r(shí)候,項(xiàng)目中的每個(gè)文件都是有規(guī)律可循的,比如:react中要求每個(gè)模塊導(dǎo)出的必須是個(gè)函數(shù)或者類,那么這樣就可以有通用的替換方法,所以這些工具內(nèi)部都已經(jīng)實(shí)現(xiàn)了通用的替換操作,就不再需要我們手動處理了。
參考文章
《webpack原理與實(shí)踐》
《webpack中文文檔》
寫在最后
其實(shí)在我們自己在項(xiàng)目中配置HMR時(shí),需要寫一些額外的代碼會覺得比較麻煩,但是還是需要我們了解其深層的原理。關(guān)于前端框架vue、react都是集成式框架,都是開箱即用,已經(jīng)繼承了HMR相關(guān)的配置。