微前端模塊共享你真的懂了嗎

圖怪獸_f2911b7334900625211d82943fb7cb8d_31696.jpg

前言:咱們運用微前端架構解決了應用體積龐大的問題,經過實踐微前端的理念,將前端應用拆分爲多個微應用(可獨立部署、鬆散耦合的應用)。同時微應用的存在,使得咱們無需在構建一個龐大的應用,而是按需構建,極大了加快了構建效率。但只是解決了應用層面的問題,在中後臺應用場景中,不一樣微應用和基座之間可能存在通用的模塊依賴,那麼若是應用間能夠實現模塊共享,那麼能夠大大優化單應體積大小html

image.png

1.Npm 依賴

最簡單的方式,就是把須要共享的模塊抽出,多是一個工具庫,有多是一個組件庫,而後講其打包成爲npm包,而後在每一個子應用中都安裝該模塊依賴,以此達到多個項目複用的效果前端

也就表明每一個應用都有相同的npm包,本質上沒有真正意義上的實現模塊共享和複用,只是代碼層次共享和複用了,應用打包構建時,仍是會將依賴包一塊兒打包vue

image.png

劣勢有如下👇 幾點:node

  • 每一個微應用都會打包該模塊,致使依賴的包冗餘,沒有真正意義上的共享複用
  • npm包進行更新發布了,微應用還須要從新構建,調試麻煩且低效 (除非用npm link

2.Git Submodule (子模塊)

阿樂童鞋: 那若是咱們沒有搭建npm內網,又不想把模塊開源出去,並且依賴npm,只要涉及變動須要從新發布,有沒有其餘方式能夠解決以上問題呀?react

image.png

2.1 對比 npm

你能夠試試 Git Submodule ,它提供了一種相似於npm package的依賴管理機制,二者差異以下圖所示👇webpack

image.png

2.2 如何使用

經過在應用項目中,經過git submodule add <submodule_url>遠程拉取子模塊項目,這時會發現應用項目中多了兩個文件.gitmodules子模塊目錄git

image.png

這個子模塊就是咱們共享的模塊,它是一個完整的Git倉庫,換句話說:咱們在應用項目目錄中不管使用git add/commit都對其不影響,即子模塊擁有自身獨立的版本控制github

總結: submodule本質上是經過git submodule add把項目依賴的模塊加起來,最終構成一個完整的項目。並且add進來的模塊,項目中並不實際包含,而只是一個包含索引信息,也就是上文提到的 .gitmodule來存儲子模塊的聯繫方式, 以此實現同步關聯子模塊。當下載到本地運行的時候纔會再拉取文件web

部分命令行:vue-router

  • git submodule add <子模塊repository> <path> : 添加子模塊

  • git submodule update --recursive --remote : 拉取全部子模塊的更新

2.3 Monorepo

阿樂童鞋: 🌲 樹醬,我記得有個叫Monorepo又是什麼玩意,跟 Git Submodule 有啥區別?

image.png

Monorepo 全稱叫monolithic respoitory,即單體式倉庫,核心是容許咱們將多個項目放到同一個倉庫裏面進行管理。主張不拆分repo,而是在單倉庫裏統一管理各個模塊的構建流程、版本號等等

這樣能夠避免大量的冗餘node_module冗餘,由於每一個項目都會安裝vue、vue-router等包,再或者本地開發須要的webpack、babel、mock等都會形成儲存空間的浪費

那麼Monorepo是怎麼管理的呢? 開源社區中諸如babel、vue的項目都是基於Monorepo去維護的(Lerna工具)

咱們以Babel爲例,在github中能夠看到其每一個模塊都在指定的packages目錄下, 也就意味着將全部的相關package都放入一個repository來管理,這不是顯得項目很臃腫?

image.png 也就這個問題,啊樂同窗和啊康同窗展開了辯論~

image.png

最終是選用Monorepo單體式倉庫仍是Multirepo多倉庫管理, 具體仍是要看你業務場景來定,Monorepo集中管理帶來的便利性,好比方便版本、依賴等管理、方便調試,但也帶來了很多不便之處 👇

  • 統一構建工具所帶來更高的要求
  • 倉庫體積過大,維護成本也高

🌲 醬 不當心扯多了,還有就是Monorepo 跟 Git Submodule 的區別

  • 前者:monorepo在單repo裏存放全部子模塊源碼

  • 後者:submodules只在主repo裏存放全部子模塊「索引」

目前內部還未使用Monorepo進行落地實際,目前基於微前端架構中後臺應用存在依賴重疊過多的狀況,後期會經過實踐來深刻分享

3. Webpack external

咱們知道webpack中有externals的配置,主要是用來配置:webpack輸出的bundle中排除依賴,換句話說經過在external定義的依賴,最終輸出的bundle不存在該依賴,主要適用於不須要常常打包更新的第三方依賴,以此來實現模塊共享。

下面是一個vue.config.js 的配置文件,經過配置exteral移除不常常更新打包的第三方依賴👇 carbon (26).png

你能夠經過在packjson中script定義的命令後添加--report查看打包📦後的分析圖,若是是webpack就是用使用插件webpack-bundle-analyzer

阿樂童鞋: 🌲 樹醬,那移除了這些依賴以後,如何保證應用正常使用?

瀏覽器環境:咱們使用cdn的方式在入口文件引入,固然你也能夠預先打包好,好比把vue全家桶打包成vue-family.min.js文件,最終達成多應用共享模塊的效果

<script src="<%= VUE_APP_UTILS_URL %>static/js/vue-family.min.js"></script>

總結:避免公共模塊包(package) 一塊兒打到bundle 中,而是在運行時再去從外部獲取這些擴展依賴

經過這種形式在微前端基座應用加載公共模塊,並將微應用引用一樣模塊的external移除掉,就能夠實現模塊共享了 可是存在微應用技術棧多樣化不統一的狀況,可能有的使用vue3,有的使用react開發,但externals 並沒有法支持多版本共存的狀況,針對這種狀況該方式就不太適用

4. Webpack DLL

官方介紹:"DLL" 一詞表明微軟最初引入的動態連接庫, 換句話說個人理解,能夠把它當作緩存,經過預先編譯好的第三方外部依賴bundle,來節省應用在打包時混入的時間

Webpack DLL 跟 上一節提到的external本質是解決一樣的問題:就是避免將第三方外部依賴打入到應用的bundle中(業務代碼),而後在運行時再去加載這部分依賴,以此來實現模塊複用,也提高了編譯構建速度

webpack dll模式下須要配置兩份webpack配置,下面是主要兩個核心插件

image.png

4.1 DllPlugin

DllPlugin:在一個獨立的webpack進行配置webpack.dll.config.js,目的是爲了建立一個把全部的第三方庫依賴打包到一塊兒的bundle的dll文件裏面,同時還會生成一個manifest.json的文件,用於:讓使用該第三方依賴集合的應用配置的DllReferencePlugin能映射到相關的依賴上去 具體配置看下圖👇

carbon.png

image.png

4.2 DllReferencePlugin

DllReferencePlugin:插件核心是把上一節提到的經過webpack.dll.config.js中打包生成的dll文件,引用到須要實際項目中使用,引用機制就是經過DllReferencePlugin插件來讀取vendor-manifest.json文件,看看是否有該第三方庫,最後經過add-asset-html-webpack-plugin插件在入口html自動插入上一節生成的vendor.dll.js 文件, 具體配置看下圖👇 carbon (1).png

5. 聯邦模塊 Module Federation

模塊聯邦是 Webpack5 推出的一個新的重要功能,能夠真正意義上實現讓跨應用間作到模塊共享,解決了從前用 NPM 公共包方式共享的不便利,同時也能夠做爲微前端的落地方案,完美秒殺了上兩節介紹webpack特徵

用過qiankun的小夥伴應該知道,qiankun微前端架構控制的粒度是在應用層面,而Module Federation控制的粒度是在模塊層面。相比之下,後者粒度更小,能夠有更多的選擇

與qiankun等微前端架構不一樣的另外一點是,咱們通常都是須要一箇中心基座去控制微應用的生命週期,而Module Federation則是去中心化的,沒有中心基座的概念,每個模塊或者應用都是能夠導入或導出,咱們能夠稱爲:host和remote,應用或模塊便可以是host也能夠是remote,亦或者二者共同體

image.png

看看下面這個例子👇

carbon (3).png

核心在於 ModuleFederationPlugin中的幾個屬性

  • remote : 示做爲 Host 時,去消費哪些 Remote;
  • exposes :表示做爲 Remote 時,export 哪些屬性提供給 Host 消費
  • shared: 可讓遠程加載的模塊對應依賴改成使用本地項目的 vue,換句話說優先用 Host 的依賴,若是 Host 沒有,最後再使用本身的

後期也會圍繞 Module Federation 去作落地分享

🌲 推薦閱讀:

你好,我是🌲 樹醬,請你喝杯🍵 記得三連哦~

1.閱讀完記得點個贊哦,有👍 有動力

2.關注公衆號:前端那些趣事,陪你聊聊前端的趣事

3.文章收錄在Github frontendThings 感謝Star✨
複製代碼
相關文章
相關標籤/搜索