webpack5(Module Federation)+vue3.0實(shí)現(xiàn)微前端

項(xiàng)目源碼地址:

https://github.com/wuxiaohuaer/webpack5-vue-admin

一泉唁、什么是微前端

微前端是一個比較宏觀的概念鹅龄,他的核心就是獨(dú)立,開發(fā)獨(dú)立游两、部署獨(dú)立砾层,比較適合大的團(tuán)隊(duì)來進(jìn)行重量級項(xiàng)目開發(fā)。

從Micro Frontends 官網(wǎng)可以了解到贱案,微前端概念是從微服務(wù)概念擴(kuò)展而來的肛炮,摒棄大型單體方式,將前端整體分解為小而簡單的塊宝踪,這些塊可以獨(dú)立開發(fā)侨糟、測試和部署,同時仍然聚合為一個產(chǎn)品出現(xiàn)在客戶面前瘩燥★踔兀可以理解微前端是一種將多個可獨(dú)立交付的小型前端應(yīng)用聚合為一個整體的架構(gòu)風(fēng)格。

二厉膀、為什么要用微前端溶耘?

一個公司有多個類似的項(xiàng)目,大家可能會共用一個dialog組件服鹅,那我們可以封裝起來凳兵,以便其他的項(xiàng)目一起使用。

這個時候大家會有一個疑問企软,直接打包放在npm上不就完了庐扫,為什么要用微前端這么復(fù)雜的東西?
我們把公用的組件打包以后上傳到npm包管理器上仗哨,確實(shí)可以讓公司的其他項(xiàng)目一起使用形庭,但是會有兩個弊端。

1厌漂、程序繁瑣

開發(fā)三個管理后臺應(yīng)用項(xiàng)目萨醒,將相同的業(yè)務(wù)子模塊抽離成npm包方式,這時候桩卵,如果要更新該業(yè)務(wù)子模塊的邏輯時验靡,那么需要做以下的流程操作:

更新npm包版本

更新A管理系統(tǒng)應(yīng)用的npm包版本

發(fā)布部署A管理系統(tǒng)應(yīng)用

對B和C管理系統(tǒng)應(yīng)用循環(huán)2和3步驟

因?yàn)殡m然相對是獨(dú)立的倍宾,有了npm這么一個中間商,但是要改一個組件胜嗓,所有的項(xiàng)目都要摸一遍高职。

如果我們使用微服務(wù),就可以把公用的組件全部放到一個容器應(yīng)用當(dāng)中辞州,專門用來放組件怔锌,需要更新的時候只要重新部署這個容器應(yīng)用,其他項(xiàng)目刷新就能得到最新的模塊变过。

2埃元、構(gòu)建速度慢

如果項(xiàng)目當(dāng)中引用了n個組件,除了需要從npm上更新以外媚狰,構(gòu)建部署的時候岛杀,也是需要全部打包一遍的,開發(fā)體驗(yàn)就會越來越差崭孤。

而微服務(wù)并不需要本地構(gòu)建這些子模塊的代碼类嗤,從而減小了構(gòu)建體積,提高了開發(fā)效率辨宠。

三遗锣、微前端實(shí)現(xiàn)方案

目前業(yè)內(nèi)最火的微前端解決方案應(yīng)該是螞蟻團(tuán)隊(duì)維護(hù)的qiankun:
https://qiankun.umijs.org/zh/guide

有興趣可以去官網(wǎng)了解

本身沒有開發(fā)過非常大量級的系統(tǒng),所以對微服務(wù)沒有太大的興趣嗤形。前段時間正好在學(xué)webpack5精偿,發(fā)現(xiàn)webpack5有一個聯(lián)邦模塊功能(mf),對于微前端的公共依賴加載是比較好的解決方案赋兵。

鑒于mf的能力笔咽,我們可以完全實(shí)現(xiàn)一個去中心化的應(yīng)用部署群:每個應(yīng)用是單獨(dú)部署在各自的服務(wù)器,每個應(yīng)用都可以引用其他應(yīng)用霹期,也能被其他應(yīng)用所引用拓轻,即每個應(yīng)用可以充當(dāng)host的角色,亦可以作為remote出現(xiàn)经伙,無中心應(yīng)用的概念。

目前基于mf勿锅,比較成熟的微前端架構(gòu)是YY團(tuán)隊(duì)的EMP微前端方案

https://github.com/efoxTeam/emp

作為一個vue狗帕膜,就基于最新的vue3.0+webpack5實(shí)現(xiàn)一個基礎(chǔ)的微服務(wù)。

四溢十、搭建環(huán)境

1垮刹、創(chuàng)建文件夾

// 創(chuàng)建文件夾

mkdir hand-vue3-project && cd hand-vue3-project

// 初始化項(xiàng)目
npm init -y

2、安裝依賴

yarn add webpack webpack-cli -D

3张弛、創(chuàng)建文件

在根目錄下創(chuàng)建src文件夾荒典、index.html和webpack.config.js酪劫,src文件夾里面創(chuàng)建main.js

4、配置webpack.config.js

// webpack.config.js
const path = require('path')

module.exports = {
  mode: 'development', // 環(huán)境模式
  entry: path.resolve(__dirname, './src/main.js'), // 打包入口
  output: {
    path: path.resolve(__dirname, 'dist'), // 打包出口
    filename: 'js/[name].js' // 打包完的靜態(tài)資源文件名
  }
}

在package.json 的 scripts 屬性加上:

"dev": "webpack --config ./webpack.config.js"

先做一些基礎(chǔ)的打包配置寺董,后面引入vue再加

5覆糟、運(yùn)行環(huán)境

在main.js打印一下

console.log('hello,world!')

運(yùn)行命令:

yarn dev

這個時候就可以看到dist文件夾下有個打包好的js文件

五、引入vue3.0

公司項(xiàng)目不敢用vue3.x遮咖,也只能在demo上騷一騷了

安裝依賴

yarn add vue@next -S
@next -S才能下載到最新的vue版本

yarn add html-webpack-plugin -D
將 index.html 作為模板滩字,打出到 dist 文件夾

yarn add vue-loader@next 
解析和轉(zhuǎn)換 .vue  文件,提取出其中的邏輯代碼 script御吞、樣式代碼 style麦箍、以及 HTML 模版 template


yarn add @vue/compiler-sfc
Vue 2.x 時代,需要 vue-template-compiler 插件處理 .vue 內(nèi)容為 ast 陶珠, Vue 3.x 則變成 @vue/compiler-sfc 挟裂。

yarn add vue-style-loader css-loader

配置項(xiàng)目

1、webpack.config.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 最新的 vue-loader 中揍诽,VueLoaderPlugin 插件的位置有所改變
const { VueLoaderPlugin } = require('vue-loader/dist/index')

module.exports = {
  mode: 'development',
  entry: path.resolve(__dirname, './src/main.js'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name].js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          'vue-loader'
        ]
      },
      {
        test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './index.html'),
      filename: 'index.html',
      title: '微前端框架1'
    }),
    // 添加 VueLoaderPlugin 插件
    new VueLoaderPlugin()
  ]
}

2诀蓉、src下的文件

main.js

import { createApp } from 'vue' // Vue 3.x 引入 vue 的形式
import App from './app.vue' // 引入 APP 頁面組建

const app = createApp(App) // 通過 createApp 初始化 app
app.mount('#root') // 將頁面掛載到 root 節(jié)點(diǎn)

新建的app.vue

<template>
  <div>距離2021年歐洲杯還有?</div>
</template>

<script>
export default {
  
}
</script>

這個時候運(yùn)行yarn dev寝姿,dist文件夾下就會包出來一個index.html交排,打開就能看到效果,但是每次都要打包打開太麻煩

引入WDS

yarn add webpack-dev-server -D

webpack.config.js

devServer: {
  contentBase: path.resolve(__dirname, './dist'),
  port: 8080,
  publicPath: '/'
}

package.json

"dev": "webpack serve --progress --config ./webpack.config.js"

運(yùn)行yarn dev

六饵筑、使用聯(lián)邦模塊實(shí)現(xiàn)微服務(wù)

剛才那個項(xiàng)目我們給他稱之為項(xiàng)目A埃篓,現(xiàn)在需要創(chuàng)建項(xiàng)目A的某個公用組件,并導(dǎo)出

1根资、新建一個組件

mountDown.vue

<template>
    <div>{{ sum }}天</div>
</template>
<script>
import { defineComponent, onMounted, ref, computed } from 'vue'
export default {
    setup() {
        let sum = computed(() => parseInt((new Date('2021-06-13'.replace(/-/g, '/')).getTime() - new Date()) / (1000*3600*24)));
        return {
            sum
        }
    }
}
</script>

2架专、導(dǎo)出組件

webpack.config.js

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

new ModuleFederationPlugin({
  name: "A", // 暴露出去的模塊名
  filename: "remoteEntry.js", // 構(gòu)建出來的文件名
  exposes: {
    './countDown': './src/components/countDown.vue' // 暴露出去。key玄帕,要寫相對路徑
  }
})

3部脚、B項(xiàng)目引入

webpack.config.js

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

new ModuleFederationPlugin({
  name: "B", // 暴露出去的模塊名
  filename: "remoteEntry.js", // 構(gòu)建出來的文件名
  remotes: {
    A: 'A@http://localhost:8080/remoteEntry.js' // 引用
  }
})

app.vue

<template>
  <div>距離2021年歐洲杯還有?</div>
  <countDown/>
</template>

import { defineAsyncComponent } from 'vue'

const countDown = defineAsyncComponent(() =>
        import('A/countDown')
)

export default {
  components: { countDown },
  setup() {
    return {
    }
  }
}

在A項(xiàng)目上改代碼裤纹,B項(xiàng)目也會及時更新委刘,不同應(yīng)用中有相同的組件,就不需要復(fù)制粘貼相同的代碼到每一個應(yīng)用的代碼中鹰椒,解決了跨應(yīng)用代碼共享的問題锡移。

七、基本概念和配置

一些基本概念

? 使用Module Federation 時漆际, 每個應(yīng)用塊都是一個獨(dú)立的構(gòu)建淆珊,這些構(gòu)建都將被編譯為 容器。
? 被應(yīng)用的容器奸汇,被稱為 remote
? 引用者施符,被稱為 host
? 暴露出去被使用的模塊往声,稱為remote模塊

一個容器 , 使用戳吝、暴露浩销,是雙向的。一個項(xiàng)目可以引用別的項(xiàng)目的組件骨坑,也可以將自己的組件暴露給別的項(xiàng)目用撼嗓。

原理

感覺原理,就是利用了jsonp欢唾。根據(jù)模塊創(chuàng)建一個全局變量且警,根據(jù)全局變量來獲取不同組件的源代碼。

參考鏈接

https://juejin.cn/post/6921161482663100423#heading-2

https://www.yuque.com/violet-coyxa/ib3u7d/etzwyg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末礁遣,一起剝皮案震驚了整個濱河市斑芜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祟霍,老刑警劉巖杏头,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沸呐,居然都是意外死亡醇王,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門崭添,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寓娩,“玉大人,你說我怎么就攤上這事呼渣〖椋” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵屁置,是天一觀的道長焊夸。 經(jīng)常有香客問我,道長蓝角,這世上最難降的妖魔是什么阱穗? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮使鹅,結(jié)果婚禮上颇象,老公的妹妹穿的比我還像新娘。我一直安慰自己并徘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布扰魂。 她就那樣靜靜地躺著麦乞,像睡著了一般蕴茴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姐直,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天倦淀,我揣著相機(jī)與錄音,去河邊找鬼声畏。 笑死撞叽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的插龄。 我是一名探鬼主播愿棋,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼均牢!你這毒婦竟也來了糠雨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤徘跪,失蹤者是張志新(化名)和其女友劉穎甘邀,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垮庐,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡松邪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了哨查。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逗抑。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖解恰,靈堂內(nèi)的尸體忽然破棺而出锋八,到底是詐尸還是另有隱情,我是刑警寧澤护盈,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布挟纱,位于F島的核電站,受9級特大地震影響腐宋,放射性物質(zhì)發(fā)生泄漏紊服。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一胸竞、第九天 我趴在偏房一處隱蔽的房頂上張望欺嗤。 院中可真熱鬧,春花似錦卫枝、人聲如沸煎饼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吆玖。三九已至筒溃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沾乘,已是汗流浹背怜奖。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翅阵,地道東北人歪玲。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像掷匠,于是被迫代替她去往敵國和親滥崩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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