manifest.json在微前端中的妙用

本文中的manifest.json
關(guān)于manifest.json的常見(jiàn)使用,相信大家去Google或者百度一下,能在很多技術(shù)和場(chǎng)景中看到這個(gè)文件,它的使用也是有比較大的差異。這里主要講下的是在Webpack打包中,這個(gè)文件的介紹和使用,以及分享下筆者在實(shí)踐中利用Webpack打包產(chǎn)生的manifest.json,實(shí)現(xiàn)微前端場(chǎng)景下資源加載優(yōu)化的目的。
Webpack中的manifest
為了方便起見(jiàn),我們先拿umi,簡(jiǎn)單創(chuàng)建個(gè)演示項(xiàng)目,有興趣的同學(xué)也可以用純凈的webpack去配置下相同的效果【筆者也有類(lèi)似的習(xí)慣,可以說(shuō)是潔癖,但是確實(shí)更能體會(huì)到本質(zhì)】

然后執(zhí)行npm i
安裝下依賴(lài)
安裝完成后,我們修改下配置,因?yàn)閡mi默認(rèn)配置是不產(chǎn)生manifest的,修改.umirc.ts
,詳細(xì)或者更多配置可以參考umi的manifest配置

然后我們執(zhí)行npm run build
,執(zhí)行打包完成后我們會(huì)得到如圖所示的dist目錄和manifest.json的內(nèi)容

怎么樣來(lái)簡(jiǎn)單理解下這個(gè)manifest.json的作用呢?更詳細(xì)的定義,大家可以參考webpack的文檔鏈接
相信大家或多或少聽(tīng)到過(guò)Windows的注冊(cè)表的概念,可以類(lèi)比下,這個(gè)文件就是記錄了我們這個(gè)項(xiàng)目打包的注冊(cè)信息。因?yàn)閡mi的打包的工具中默認(rèn)配置了入口的js文件是umi.js
css文件入口是umi.css
,更多的時(shí)候比如像筆者的團(tuán)隊(duì)的打包工具設(shè)置的入口文件是index.js
和index.css
這個(gè)大同小異,所以我們?cè)谫Y源引用的時(shí)候 會(huì)變成baseUrl
+?/
+index.js
,當(dāng)然在微前端場(chǎng)景中也是類(lèi)似,實(shí)際比較大型的項(xiàng)目會(huì)把整個(gè)打包產(chǎn)物的目錄部署到nginx的靜態(tài)目錄下,或者上傳CDN服務(wù)上去。
從實(shí)際效果來(lái)說(shuō),如果是單個(gè)spa項(xiàng)目,因?yàn)?/span>HtmlWebpackPlugin
的存在和使用,可以在index.html中注入相應(yīng)的入口信息;如果是微前端項(xiàng)目,我們會(huì)在對(duì)應(yīng)的界面的某個(gè)菜單配置加載某個(gè)前端項(xiàng)目的資源入口地址,比如https://xxxx/tms/index.js
,nginx映射關(guān)系背后的實(shí)際目錄可能是?/mnt/cdn/tms/dist/index.js
關(guān)于微前端的概念和實(shí)踐,如果大家有興趣,筆者可以后期再介紹下實(shí)戰(zhàn)經(jīng)驗(yàn)
由此就帶來(lái)一個(gè)實(shí)際的問(wèn)題,這段地址是一個(gè)靜態(tài)地址,不論我代碼發(fā)布了多少次,因?yàn)閡rl地址并沒(méi)有發(fā)生變化,用戶(hù)的瀏覽器可能會(huì)緩存這些文件,導(dǎo)致使用存在問(wèn)題。有Webpack實(shí)際使用經(jīng)驗(yàn)的同學(xué),這時(shí)候肯定會(huì)想到,這個(gè)非常好解決呀,我在資源引用處修改下變成https://xxxx/ddv/index.js?213123123123
用Date.now()
拼接個(gè)字符串上去,或者給打包的文件加上hash,nice!非常聰明。

但是這樣雖然解決了被緩存的問(wèn)題,但是引發(fā)了另外兩個(gè)問(wèn)題。
添加時(shí)間戳,導(dǎo)致了緩存徹底失效,用戶(hù)每次刷新界面都完整了重新加載了資源,有點(diǎn)浪費(fèi)
文件名加上了hash值,資源引用處就需要同步打包后的文件名。這就帶來(lái)了比較大的管理成本【其實(shí)很多大廠或者團(tuán)隊(duì)在實(shí)踐微前端應(yīng)用過(guò)程中,為了精準(zhǔn)控制,是存在對(duì)應(yīng)的管理模塊和對(duì)應(yīng)更新策略的,有些實(shí)踐中是這里的hash,也有在nginx資源處添加了一層目錄就是版本號(hào)的概念】
因?yàn)橛袀€(gè)manifest的存在,筆者實(shí)踐了一套能夠兼顧的辦法,大家可以討論下。
在微前端項(xiàng)目中,改造下資源加載入口,考慮大家理解成本和項(xiàng)目代碼的私密性,放出段簡(jiǎn)化代碼
這里實(shí)際上,也會(huì)有同學(xué)肯定會(huì)差異,manifest.json的請(qǐng)求還是需要每次都請(qǐng)求。的確是的,首先是這個(gè)文件本身大小可觀,再者如果是比較完備的微前端管理策略下,此處實(shí)現(xiàn)也需要去請(qǐng)求相應(yīng)的接口去獲得相關(guān)信息,所以是必要的。因?yàn)閙anifest.json是每次打包產(chǎn)生的,因此在沒(méi)有項(xiàng)目升級(jí)和更新的情況下,入口hash值并不變,比如https://xxxx/adc/index.12asdn.js
,能夠被用戶(hù)瀏覽器緩存,避免每次都去重新請(qǐng)求,在項(xiàng)目代碼發(fā)生改變后,manifest.json的信息發(fā)生改變,瀏覽器又能去請(qǐng)求到最新的資源,一舉兩得。

當(dāng)然,筆者再次聲明,此方案僅限于這么一個(gè)基于現(xiàn)實(shí)場(chǎng)景簡(jiǎn)化得來(lái)的場(chǎng)景討論,實(shí)際生產(chǎn)項(xiàng)目往往會(huì)采用更加復(fù)雜和全面的方案去實(shí)現(xiàn),但是作為理解manifest.json和微前端資源加載本身還是有不錯(cuò)的作用,如果是有些中小型的項(xiàng)目,如果有類(lèi)似的需求,也不妨去完善下再去使用。
參考資料:
Webpack - The Manifest
umi - hash配置
更多內(nèi)容可以關(guān)注公眾號(hào) - 喵爸的小作坊