微前端webpack升級Vite

背景

我們代碼采用的是webpack的微前端架構鲫咽,但是由于代碼越來越多,巨石應用越來越大,本地啟動編譯時間需要10s分尸,所以決定升級本地啟動環(huán)境為vite锦聊,提升開發(fā)效率。但是由于是微前端架構寓落,升級過程中遇到了很多問題括丁,逐個分析解決。

核心原理

Vite 是一種現(xiàn)代化的前端開發(fā)構建工具伶选,它的核心原理和特性可以歸納為以下幾個方面:

  1. 基于 ES 模塊的開發(fā)模式:Vite 通過基于 ES 模塊的開發(fā)模式史飞,可以讓開發(fā)者在開發(fā)過程中以更加自然的方式編寫代碼。開發(fā)者可以通過 import/export 語句來引用其他模塊仰税,而無需使用其他工具將這些模塊打包在一起构资。

  2. 快速的冷啟動:Vite 采用了一種“按需編譯”的策略,只會在需要時編譯文件陨簇,這樣就避免了像其他打包工具一樣需要一次性編譯所有的文件吐绵,導致啟動時間較長的問題。因此河绽,Vite 的冷啟動速度非臣旱ィ快,可以顯著提高開發(fā)效率耙饰。

  3. 開發(fā)模式下的緩存:在Vite開發(fā)模式下纹笼,當一個模塊被第一次引用時,Vite會將該模塊的依賴關系分析并緩存到.vite/deps目錄下苟跪。這樣在下一次重新編譯時廷痘,Vite就可以直接使用緩存的依賴關系,Vite可以減少重復的依賴分析和編譯操作件已,從而加快編譯速度笋额。同時,由于緩存的依賴關系是按照模塊路徑組織的篷扩,因此Vite還可以檢測到依賴關系的變化兄猩,并在需要時自動更新緩存。

  4. 輕量快速的熱重載HMR:Vite 采用了一種基于原生 ES 模塊系統(tǒng)的高效的熱更新機制(HMR)瞻惋,可以在開發(fā)過程中快速地更新代碼厦滤,并在瀏覽器中實時地查看更新效果,而無需刷新頁面歼狼。這也大大提高了開發(fā)效率掏导。

  5. 支持多種開發(fā)語言:Vite 不僅支持 JavaScript 和 TypeScript,還支持 Vue羽峰、React趟咆、Svelte 等多種前端開發(fā)框架添瓷,可以讓開發(fā)者在開發(fā)過程中更加靈活。

總之值纱,Vite 的核心原理是通過基于 ES 模塊的開發(fā)模式鳞贷、快速的冷啟動、高效的 HMR 以及對多種開發(fā)語言的支持虐唠,來提高前端開發(fā)的效率搀愧。

微前端改造

1、vite-plugin-federation 替換ModuleFederationPlugin

由于我們代碼使用的是微前端框架疆偿,主要使用webpack的ModuleFederationPlugin來實現(xiàn)各個模塊之間的獨立咱筛,升級為vite時我們首先采用的是使用針對vite的插件vite-plugin-federation 來進行整體升級改造。

vite-plugin-federation的使用方式與Webpack 5中的模塊聯(lián)邦相似杆故,通過配置來定義不同子應用程序之間的依賴關系和公共模塊迅箩,從而實現(xiàn)代碼的復用和分發(fā)。在實際應用中处铛,可以將一個大型的應用程序拆分成多個獨立的子應用程序饲趋,通過這種方式實現(xiàn)微服務架構和多人合作開發(fā)等需求。

但是在改造過程中發(fā)現(xiàn)撤蟆,該plugin實現(xiàn)的核心原理是各個模塊之間的remote和exposes需要先build奕塑,build的時候相當于使用rollup進行打包編譯,這樣就失去了vite本身最難得的快的屬性家肯。所以最后我們決定放棄使用該插件爵川。

2、采取本地開發(fā)模式摒棄微前端多個server模式息楔,準備通過alias將多個子模塊合并成一個子模塊。

核心原理:rewrite文件間/模塊間的引用路徑扒披,本地開發(fā)只需要單個vite server

1)alias方案初期嘗試過程中遇到兩個卡點

  1. 子模塊之間互相調(diào)用值依,通過commonLibs,commonApp這種別名進行引用碟案,我們需要識別出文件的真正路徑愿险,這個主要是通過原模塊中導出的remotes文件導出的exposes,能找到真正的路徑价说。
    [圖片上傳失敗...(image-f35d07-1705649743183)
    [圖片上傳失敗...(image-d89aea-1705649639438)]

解決方案:vite提供的resolve的alias配置中支持customResolver辆亏,其中的id和importer可以提供一些自定義的方案,id是代碼中要解析的from后邊的path鳖目,importer是該文件的目錄扮叨。所以我們可以先根據(jù)id去exposes中找到最終的路徑,這樣就可以解析這種子模塊的引用方式领迈。

[圖片上傳失敗...(image-cb3d7f-1705649639438)]

  1. 各個子模塊的app開頭的引用一般都指向自己的子模塊的src彻磁,我們改成一個server之后碍沐,需要識別app所屬的模塊,并指向?qū)膕rc位置衷蜓。

[圖片上傳失敗...(image-6fe9c-1705649639438)]

解決方案:從importer中提取出所屬模塊累提,然后把app替換成該子模塊下的src路徑

[圖片上傳失敗...(image-135c0e-1705649639438)]

2)遇到的問題和解決方案

  1. vite模式下子模塊中的node_modules的引用會優(yōu)先取離他最近的node_modules中去取,所以由于該特性無需處理npm包的alias磁浇。

  2. connected-react-router問題斋陪,啟動過程中報錯了,查一下原因是connected-react-router和react-router置吓、react-dom的兼容性問題无虚,由于connected-react-router缺少維護,和路由版本兼容要求高交洗,因此解決方案是下掉connected-react-router骑科,下掉connected-react-router的過程中需要注意幾個點,后續(xù)大家也不要用這種方式去使用了构拳。

[圖片上傳失敗...(image-6a206d-1705649639438)]

下線的過程中發(fā)現(xiàn)報了一個錯咆爽,是使用useHistory或者useLocation的時候,Context找不到置森。一開始以為是單例問題斗埂,嘗試了很多解決方案,只保留一個模塊的這個npm包還是不行凫海,排除單例問題呛凶,后來發(fā)現(xiàn)這個文件報錯位置在react-router里,但我們由于下掉connected-react-router的過程中行贪,BrowserRouter使用的是react-router-dom的漾稀,Context也是通過react-router-dom下發(fā)的,但我們代碼里使用的useHistory等是引入的react-router,因此改掉了這個引用就解決了問題建瘫。

[圖片上傳失敗...(image-fe816-1705649639438)]

    • 下掉最外層的入口

[圖片上傳失敗...(image-8eb8de-1705649639438)]

    • 下掉路由對history的注入和監(jiān)聽崭捍;注意要同時下掉state.router的取用邏輯。

[圖片上傳失敗...(image-f7212a-1705649639438)]

[圖片上傳失敗...(image-527cdb-1705649639438)]

[圖片上傳失敗...(image-b02b9c-1705649639438)]

    • 下掉dispatch(puh(url))的使用啰脚;采用useHistory進行跳轉(zhuǎn)殷蛇。

[圖片上傳失敗...(image-351304-1705649639438)]

  1. alias副作用導致的單例問題。

vite中alias相對路徑會把文件打到有后綴的文件橄浓,我們alias的子模塊的替換由于exposes中披露了文件后綴粒梦,所以也會打到有后綴的文件,但是app的alias打到的是無后綴的文件荸实,這樣就會生成兩份匀们,對于使用context這樣全局數(shù)據(jù)的來說,就會由于無法保證單例導致context數(shù)據(jù)清空的bug泪勒。

這邊把用sharedInfo的context的引用路徑改成了相對路徑昼蛀,或者加上.js后綴即可宴猾。

還有app/utils/flags的引用也要加上后綴或者使用相對路徑。

[圖片上傳失敗...(image-ef7fe2-1705649639438)]

對大部分的app引用沒有影響叼旋,只是影響這種需要保證單實例的仇哆。

[圖片上傳失敗...(image-e5e100-1705649639438)]

[圖片上傳失敗...(image-353150-1705649639438)]

  1. 微前端模塊中除了alias引入的非單實例問題,也有一些模塊需要單實例夫植,以前維護在sharedInfo里去保證讹剔,如果有多個npm包的話,在vite中自身支持導出的是一個模塊详民,來保證單實例問題延欠,從vite的預構建輸出結(jié)果可以看出。

在 Vite 中沈跨,不同的 Node.js 模塊(node_modules 目錄下的不同包)可以共享一個單例模式的包由捎,這是通過 Vite 的模塊解析器和緩存機制來實現(xiàn)的。具體來說饿凛,Vite 會對每個模塊進行緩存狞玛,當?shù)谝淮握埱笠粋€模塊時,Vite 會解析該模塊及其依賴項涧窒,然后將其保存在內(nèi)存中心肪,下次請求該模塊時,會直接從緩存中讀取纠吴,而不是重新解析和構建硬鞍。

在 Vite 中,當多個模塊引用同一個依賴時戴已,Vite 會將這些模塊中的依賴項映射到同一個緩存中的實例固该,從而實現(xiàn)了單例模式。這樣做可以提高應用程序的性能糖儡,減少內(nèi)存占用和加載時間蹬音。

需要注意的是,Vite 的單例模式只是在開發(fā)模式下生效休玩。在生產(chǎn)模式下,由于 Vite 會對依賴項進行代碼拆分和壓縮劫狠,因此每個模塊都會引用自己的依賴項的獨立實例拴疤,這樣可以減小應用程序的大小并提高性能。

[圖片上傳失敗...(image-f4f425-1705649639438)]

[圖片上傳失敗...(image-b41d46-1705649639438)]

  1. mockService中間件

vite也支持啟動服務時做一些mock服務独泞,具體改造方式如下

[圖片上傳失敗...(image-eecaf4-1705649639438)]

  1. css注入變量

啟動過程中發(fā)生如下報錯呐矾,是因為less的一些全局變量沒有注入,增加vite配置注入即可懦砂。

[圖片上傳失敗...(image-3c3d00-1705649639438)]

[圖片上傳失敗...(image-a03728-1705649639438)]

  1. 靜態(tài)資源解析

代碼中引入了一些html或者docx結(jié)尾的靜態(tài)資源蜒犯,啟動過程中會報錯组橄,增加靜態(tài)資源的配置即可。

[圖片上傳失敗...(image-fcac48-1705649639438)]

[圖片上傳失敗...(image-396fbe-1705649639438)]

  1. 全局變量注入

可以通過define配置注入一些全局變量罚随。

[圖片上傳失敗...(image-8c14b4-1705649639438)]

  1. babel插件問題

react插件中支持babel的一些presets和plugin玉工,但是有一些會和react插件內(nèi)置的沖突,要注意避坑淘菩,比如之前我就把原來代碼庫中的babel配置直接抄過來傳入了react插件中遵班,結(jié)果就報錯了。比如presets中的@babel/preset-env和@babel/preset-react就會和react插件有沖突潮改。

[圖片上傳失敗...(image-e5d4a8-1705649639438)]

[圖片上傳失敗...(image-75e027-1705649639438)]

效果評估

現(xiàn)狀

[圖片上傳失敗...(image-f95bf0-1705649639438)]

改進后指標

冷啟動:8s左右

熱更新:保存即更新狭郑,幾乎實時更新,不需要刷新和等待時長汇在。

注意事項

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翰萨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子糕殉,更是在濱河造成了極大的恐慌亩鬼,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糙麦,死亡現(xiàn)場離奇詭異辛孵,居然都是意外死亡,警方通過查閱死者的電腦和手機赡磅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門魄缚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人焚廊,你說我怎么就攤上這事冶匹。” “怎么了咆瘟?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵嚼隘,是天一觀的道長。 經(jīng)常有香客問我袒餐,道長飞蛹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任灸眼,我火速辦了婚禮卧檐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焰宣。我一直安慰自己霉囚,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布匕积。 她就那樣靜靜地躺著盈罐,像睡著了一般榜跌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盅粪,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天钓葫,我揣著相機與錄音,去河邊找鬼湾揽。 笑死瓤逼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的库物。 我是一名探鬼主播霸旗,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戚揭!你這毒婦竟也來了诱告?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤民晒,失蹤者是張志新(化名)和其女友劉穎精居,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潜必,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡靴姿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了磁滚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佛吓。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖垂攘,靈堂內(nèi)的尸體忽然破棺而出维雇,到底是詐尸還是另有隱情,我是刑警寧澤晒他,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布吱型,位于F島的核電站,受9級特大地震影響陨仅,放射性物質(zhì)發(fā)生泄漏津滞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一灼伤、第九天 我趴在偏房一處隱蔽的房頂上張望据沈。 院中可真熱鬧,春花似錦饺蔑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孔祸。三九已至,卻和暖如春发皿,著一層夾襖步出監(jiān)牢的瞬間崔慧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工穴墅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惶室,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓玄货,卻偏偏與公主長得像皇钞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子松捉,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容