webpack-模塊聯(lián)邦(ModuleFederation)

是什么

是一個用來解決多個應(yīng)用之間代碼共享的問題丁稀,可以讓我們更加優(yōu)雅的實現(xiàn)跨應(yīng)用的代碼共享的webpack插件送矩。

解決了什么

解決如何高效實現(xiàn)模塊共享的問題

怎么發(fā)展來的

1. npm
這是最原始簡單的方法悯搔,也是我們最常用的方法轧钓。
缺點: npm發(fā)包需要經(jīng)歷構(gòu)建蓬坡,發(fā)布骏啰,引用三階段离斩,過程繁瑣银舱。

2. UMD模式打包
根據(jù)傳入的參數(shù),判斷是執(zhí)行AMD模式還是CommonJs模式跛梗。
缺點:包體積很大寻馏,不同庫之間容易沖突

3. 微服務(wù)
可以做到多個獨立的構(gòu)建組成一個應(yīng)用程序,這些獨立的構(gòu)建之間不存在依賴關(guān)系核偿,因此可以單獨開發(fā)和部署它們诚欠。
缺點:獨立的構(gòu)建一多,就需要多次部署維護(hù)漾岳,對運維來說工作量很大轰绵。另外微服務(wù)一般是子應(yīng)用獨立打包,耦合度很低尼荆,但是沒辦法做到公共模塊共用左腔。

4. MouduleFedration
直接將一個應(yīng)用的包應(yīng)用于另一個應(yīng)用,同時具備整體應(yīng)用一起打包的公共依賴抽取能力捅儒。(因為之前的方案液样,大都是無法抽離出公共模塊,導(dǎo)致整體打包很慢)野芒。讓應(yīng)用具備模塊化輸出能力蓄愁,其實開辟了一種新的應(yīng)用形態(tài),即 “中心應(yīng)用”狞悲,這個中心應(yīng)用用于在線動態(tài)分發(fā) Runtime 子模塊撮抓,并不直接提供給用戶使用。

有什么重要的概念

  • webpack構(gòu)建:一個獨立項目通過webpack打包編譯而產(chǎn)生資源包摇锋。
  • remote:一個暴露模塊供其他webpakc構(gòu)建消費的webpack構(gòu)建丹拯。(生產(chǎn)者)
  • host:一個消費其他remote模塊的webpack構(gòu)建。(消費者)
    一個構(gòu)件既可以是生產(chǎn)者荸恕,也可以是消費者乖酬。

怎么用

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  // other webpack configs...
  plugins: [
    new ModuleFederationPlugin({
      name: "app_one_remote",
      remotes: {
        app_two: "app_two_remote",
        app_three: "app_three_remote"
      },
      exposes: {
        AppContainer: "./src/App"
      },
      shared: ["react", "react-dom", "react-router-dom"]
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      chunks: ["main"]
    })
  ]
};
配置說明
  1. name 當(dāng)前應(yīng)用名稱,需要全局唯一融求。(到時候別的應(yīng)用來消費就是根據(jù)這個name找到這個應(yīng)用的)
  2. remotes 可以將其他項目的 name 映射到當(dāng)前項目中咬像。(消費)
  3. exposes 表示導(dǎo)出的模塊,只有在此申明的模塊才可以作為遠(yuǎn)程依賴被使用。(生產(chǎn))
  4. shared 是非常重要的參數(shù)县昂,制定了這個參數(shù)肮柜,可以讓遠(yuǎn)程加載的模塊對應(yīng)依賴改為使用本地項目的 React 或 ReactDOM。如果不配就容易出現(xiàn)多次加載的情況(也就是說消費者知道生產(chǎn)者自己擁有這樣的模塊時才會用到這個配置)

使用場景

一共有三個微應(yīng)用:lib-app倒彰、component-app审洞、main-app,角色分別是:

  • lib-appas remote,暴露了兩個模塊react和react-dom
  • component-app as remote and host,依賴lib-app,暴露了一些組件供main-app消費
  • main-app as host,依賴lib-app和component-app

lib-app

module.exports = { 
    //...省略 
  plugins: [ 
    new ModuleFederationPlugin({ 
        name: "lib_app", 
        filename: "remoteEntry.js", 
        exposes: { "./react":"react", "./react-dom":"react-dom" } 
     })], 
     //...省略 
}

除去生成的map文件待讳,此次編譯后生成四個文件:main.js芒澜、remoteEntry.js、...react_index.js创淡、...react-dom_index.js痴晦;

  • 第一個是本項目的入口文件(該項目只是暴露接口,所以該文件為空)
  • 第二個是遠(yuǎn)程入口文件辩昆,其他webpack構(gòu)建使用阅酪、訪問本項目暴露的模塊時,須通過它來加載
  • 第三個和第四個是暴露的模塊汁针,供其他項目消費

component-app

module.exports = {
 //...省略 
 plugins:[ 
     new ModuleFederationPlugin({ 
         name: "component_app", 
         filename: "remoteEntry.js", 
         exposes: { 
             "./Button":"./src/Button.jsx"
         }, 
         remotes:{ 
             "lib-app":"lib_app@http://localhost:3000/remoteEntry.js" 
         } 
      }), 
  ]
}

這里依賴了lib-app术辐,后面的值就是lib-app ModuleFederation應(yīng)用的入口文件地址。暴露出來Button組件施无。

main-app

//webpack.config.js
module.exports = {
 //...省略 
 plugins:[ 
     new ModuleFederationPlugin({ 
         name: "main_app", 
         filename: "remoteEntry.js",  
         remotes:{ 
             "lib-app":"lib_app@http://localhost:3000/remoteEntry.js", 
             "component-app":"component_app@http://localhost:3001/remoteEntry.js"
         } 
      }), 
      new HtmlWebpackPlugin({
          template: "./public/index.html",
        })
  ]
}

這里和上面的ModuleFederation配置基本一樣辉词,重點是建立依賴之后怎么用?
由于需要等待基礎(chǔ)模塊加載完畢猾骡,所以需要配置懶加載入口bootstrap.js.

bootstrap.js

import ReactDOM from 'lib-app/react-dom';
import React from 'lib-app/react'
ReactDOM.render(<App />, document.getElementById("app"));

App.jsx

import Button from 'component-app/Button'
export default class App extends React.Component{
  constructor(props) {
    super(props)
    //省略...
  }
  //省略...
  render(){
    return (<div>
      //省略...
    </div>)
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瑞躺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子兴想,更是在濱河造成了極大的恐慌幢哨,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫂便,死亡現(xiàn)場離奇詭異捞镰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)毙替,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門岸售,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厂画,你說我怎么就攤上這事凸丸。” “怎么了袱院?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵屎慢,是天一觀的道長瞭稼。 經(jīng)常有香客問我,道長腻惠,這世上最難降的妖魔是什么弛姜? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮妖枚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苍在。我一直安慰自己绝页,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布寂恬。 她就那樣靜靜地躺著续誉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪初肉。 梳的紋絲不亂的頭發(fā)上酷鸦,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機(jī)與錄音牙咏,去河邊找鬼臼隔。 笑死,一個胖子當(dāng)著我的面吹牛妄壶,可吹牛的內(nèi)容都是我干的摔握。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼丁寄,長吁一口氣:“原來是場噩夢啊……” “哼氨淌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起伊磺,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤盛正,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后屑埋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豪筝,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年雀彼,在試婚紗的時候發(fā)現(xiàn)自己被綠了壤蚜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡徊哑,死狀恐怖袜刷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情莺丑,我是刑警寧澤著蟹,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布墩蔓,位于F島的核電站,受9級特大地震影響萧豆,放射性物質(zhì)發(fā)生泄漏奸披。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一涮雷、第九天 我趴在偏房一處隱蔽的房頂上張望阵面。 院中可真熱鬧,春花似錦洪鸭、人聲如沸样刷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽置鼻。三九已至,卻和暖如春蜓竹,著一層夾襖步出監(jiān)牢的瞬間箕母,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工俱济, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嘶是,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓姨蝴,卻偏偏與公主長得像俊啼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子左医,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

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