wordpress 換域名插件關(guān)鍵詞排名優(yōu)化江蘇的團(tuán)隊(duì)
微前端學(xué)習(xí)以及分享
注:本次分享demo的源碼github地址:https://github.com/rondout/micro-frontend
什么是微前端
微前端的概念是由ThoughtWorks
在2016年提出的,它借鑒了微服務(wù)的架構(gòu)理念,核心在于將一個(gè)龐大的前端應(yīng)用拆分成多個(gè)獨(dú)立靈活的小型應(yīng)用,每個(gè)應(yīng)用都可以獨(dú)立開(kāi)發(fā)、獨(dú)立運(yùn)行、獨(dú)立部署,再將這些小型應(yīng)用融合為一個(gè)完整的應(yīng)用,或者將原本運(yùn)行已久、沒(méi)有關(guān)聯(lián)的幾個(gè)應(yīng)用融合為一個(gè)應(yīng)用。微前端既可以將多個(gè)項(xiàng)目融合為一,又可以減少項(xiàng)目之間的耦合,提升項(xiàng)目擴(kuò)展性,相比一整塊的前端倉(cāng)庫(kù),微前端架構(gòu)下的前端倉(cāng)庫(kù)傾向于更小更靈活。
它主要解決了兩個(gè)問(wèn)題:
- 隨著項(xiàng)目迭代應(yīng)用越來(lái)越龐大,難以維護(hù)。
- 跨團(tuán)隊(duì)或跨部門(mén)協(xié)作開(kāi)發(fā)項(xiàng)目導(dǎo)致效率低下的問(wèn)題。
微前端架構(gòu)有以下特點(diǎn):
-
技術(shù)棧無(wú)關(guān)
主框架不限制接入應(yīng)用的技術(shù)棧,微應(yīng)用具備完全自主權(quán) -
獨(dú)立開(kāi)發(fā)、獨(dú)立部署
微應(yīng)用倉(cāng)庫(kù)獨(dú)立,前后端可獨(dú)立開(kāi)發(fā),部署完成后主框架自動(dòng)完成同步更新 -
增量升級(jí)
在面對(duì)各種復(fù)雜場(chǎng)景時(shí),我們通常很難對(duì)一個(gè)已經(jīng)存在的系統(tǒng)做全量的技術(shù)棧升級(jí)或重構(gòu),而微前端是一種非常好的實(shí)施漸進(jìn)式重構(gòu)的手段和策略
-
獨(dú)立運(yùn)行時(shí)
每個(gè)微應(yīng)用之間狀態(tài)隔離,運(yùn)行時(shí)狀態(tài)不共享
現(xiàn)有的微前端解決方案
現(xiàn)在主流的微前端解決方案有以下幾種:
-
qiankun
:qiankun
孵化自螞蟻金融科技基于微前端架構(gòu)的云產(chǎn)品統(tǒng)一接入平臺(tái),在經(jīng)過(guò)一批線上應(yīng)用的充分檢驗(yàn)及打磨后,我們將其微前端內(nèi)核抽取出來(lái)并開(kāi)源,希望能同時(shí)幫助社區(qū)有類(lèi)似需求的系統(tǒng)更方便的構(gòu)建自己的微前端系統(tǒng)。 -
MicroApp:
micro-app
是由京東前端團(tuán)隊(duì)推出的一款微前端框架,它借鑒了WebComponent
的思想,通過(guò)js沙箱
、樣式隔離
、元素隔離
、路由隔離
模擬實(shí)現(xiàn)了隔離特性,從而實(shí)現(xiàn)微前端的組件化渲染,旨在降低上手難度、提升工作效率。micro-app
和技術(shù)棧無(wú)關(guān),也不和業(yè)務(wù)綁定,可以用于任何前端框架。 -
Wujie
:無(wú)界微前端方案基于 webcomponent 容器 + iframe 沙箱,能夠完善的解決適配成本、樣式隔離、運(yùn)行性能、頁(yè)面白屏、子應(yīng)用通信、子應(yīng)用?;睢⒍鄳?yīng)用激活、vite 框架支持、應(yīng)用共享等用戶的核心訴求。
目前而言,這三種方案都是不錯(cuò)的微前端解決方案,但是目前而言qiankun
對(duì)vite的支持仍然不友好,qiankun
本身是不支持vite構(gòu)建的應(yīng)用的,還需要使用社區(qū)的插件,而且我也有去做demo,然后覺(jué)得坑太多了,就選擇了 MicroApp
方案來(lái)做微前端技術(shù)調(diào)研學(xué)習(xí)的方案。
學(xué)習(xí)目標(biāo)
本次學(xué)習(xí)目標(biāo)有以下幾個(gè):
-
設(shè)計(jì)微前端架構(gòu)
-
實(shí)現(xiàn)基座應(yīng)用和子應(yīng)用之間的通信
-
不同子應(yīng)用之間的通信
-
數(shù)據(jù)共享以及數(shù)據(jù)私有
-
部署整個(gè)微前端架構(gòu)以及有關(guān)應(yīng)用
基座和子應(yīng)用
微前端架構(gòu)中很重要的一個(gè)概念就是基座和子應(yīng)用
,基座就是整個(gè)應(yīng)用的基礎(chǔ),所有的子應(yīng)用就是一個(gè)個(gè)單獨(dú)的前端應(yīng)用(工程)。在微前端架構(gòu)中,子應(yīng)用是可以單獨(dú)開(kāi)發(fā)然后適配基座的,最終整個(gè)應(yīng)用運(yùn)行后,子應(yīng)用是掛載在基座上的。
我這邊設(shè)計(jì)的整個(gè)微前端架構(gòu)的目錄結(jié)構(gòu)如下:
- assets
- base-app
- child-vue3-app
- child-react-app
- child-native-app
- servers
- package.json
- tsconfig.json
這其中 base-app
、 child-vue3-app
、 child-react-app
、 child-native-app
都是一個(gè)單獨(dú)的應(yīng)用,可獨(dú)立運(yùn)行,也可和微前端架構(gòu)一起整體運(yùn)行。
在 package.json
中配置啟動(dòng)腳本:
"install:main": "cd base-app && pnpm install","install:vue": "cd child-vue3-app && pnpm install","install:react": "cd child-react-app && pnpm install","install:native": "cd child-native-app && pnpm install","install:server": "cd servers && pnpm install","dev:main": "cd base-app && pnpm dev","dev:vue": "cd child-vue3-app && pnpm dev","dev:react": "cd child-react-app && pnpm dev","dev:native": "cd child-native-app && pnpm dev","dev:server": "cd servers && pnpm dev","install": "pnpm install:main && pnpm install:vue && pnpm install:react && pnpm install:native && pnpm install:server","dev": "concurrently \"pnpm dev:main\" \"pnpm dev:vue\" \"pnpm dev:react\" \"pnpm dev:native\"",
我們?cè)谶\(yùn)行項(xiàng)目的時(shí)候可以先通過(guò)pnpm install
命令安裝所有的依賴(包括每一個(gè)子應(yīng)用),然后通過(guò)pnpm dev
命令啟動(dòng)項(xiàng)目。
這里大致解釋一下 concurrently
這個(gè)工具,就是用來(lái)同時(shí)啟動(dòng)多個(gè)命令,比如我們這里啟動(dòng)了基座應(yīng)用和子應(yīng)用,因此我們可以通過(guò)pnpm dev
命令同時(shí)啟動(dòng)基座應(yīng)用和子應(yīng)用。
搭建基座和子應(yīng)用
我們可以用任意的技術(shù)棧來(lái)搭建基座應(yīng)用。由于我們現(xiàn)在目前以及后續(xù)的技術(shù)棧是 vue3 + ts + vite
這套。因此這里我也就以該技術(shù)棧搭建基座。
子應(yīng)用我們可以使用各種技術(shù)棧搭建不同的子應(yīng)用來(lái)進(jìn)行技術(shù)實(shí)踐,我這邊準(zhǔn)備了一下幾種技術(shù)棧:
vue3 + ts + vite
react + ts + vite
- 原生
native app (使用nodejs搭建靜態(tài)資源服務(wù)器)
搭建基座應(yīng)用和子應(yīng)用的流程這里就無(wú)需多講了。也不是本次分享的重點(diǎn),因此這里略過(guò)。
我們?cè)O(shè)想的整個(gè)應(yīng)用的結(jié)構(gòu)如下:
我們把整個(gè)應(yīng)用分為3個(gè)部分:
- 頭部 headers
- 側(cè)邊 aside
- 內(nèi)容區(qū)域 Content
我們期望的是頭部和側(cè)邊區(qū)域是基座應(yīng)用,內(nèi)容區(qū)域是子應(yīng)用。比如我們的 demo
里面的,側(cè)邊欄有首頁(yè)
、VUE APP
、 REACT APP
以及 NATIVE APP
,首頁(yè)是基座應(yīng)用,VUE APP 和 REACT APP 以及 NATIVE APP
是子應(yīng)用。
初始化基座
首先是安裝依賴:
npm i @micro-zoe/micro-app --save
// 或者
pnpm add @micro-zoe/micro-app
// 或者
yarn add @micro-zoe/micro-app
然后根據(jù)官方文檔操作步驟,初始化基座的 MicroApp
有關(guān)的配置代碼:
import microApp from "@micro-zoe/micro-app";export function startMicro() {console.log("MicroApp start!");microApp.start();
}
這樣子,我們的基座應(yīng)用就初始化完成了,非常簡(jiǎn)單。
加載子應(yīng)用
在基座應(yīng)用中直接使用 <micro-app>
標(biāo)簽加載子應(yīng)用:
<template><!-- name:應(yīng)用名稱, url:應(yīng)用地址 --><micro-app name='my-app' url='http://localhost:3000/'></micro-app>
</template>
這里是以 vue
子應(yīng)用為例,后續(xù)完整代碼會(huì)有react
版本的。這里注意name
和url
只是這個(gè)標(biāo)簽的屬性之二,該標(biāo)簽還支持多種屬性,后續(xù)我們遇到一個(gè)說(shuō)一個(gè)。比如我們?cè)诩虞d vite
構(gòu)建的子應(yīng)用就需要加上iframe
屬性。因?yàn)槟壳?code>vite構(gòu)建的子應(yīng)用目前只支持 iframe
沙箱。
子應(yīng)用TS配置
由于子應(yīng)用無(wú)需安裝 micro-app
依賴,并且子應(yīng)用通過(guò)window對(duì)象實(shí)現(xiàn)微前端功能以及和基座應(yīng)用之間的通信,因此我們最好是給子應(yīng)用聲明一下window對(duì)象上面的有關(guān)屬性和方法:
env.d.ts
:
/** @Author: shufei.han* @Date: 2024-08-02 09:29:40* @LastEditors: shufei.han* @LastEditTime: 2024-08-29 12:05:55* @FilePath: \micro-frontend\child-vue3-app\env.d.ts* @Description: */
/// <reference types="vite/client" />
import type { MicroMessageType } from '@/models/base.model';
import 'ant-design-vue/typings/global'declare global {interface MicroMessage<T = any> {type: MicroMessageType;value?: T;}interface Window {microApp: {addDataListener:(dataListener: (data: MicroMessage) => any, autoTrigger?: boolean) => void;removeDataListener:(dataListener: (data: MicroMessage) => any, autoTrigger?: boolean) => void;removeGlobalDataListener:(dataListener: (data: MicroMessage) => any, autoTrigger?: boolean) => void;addGlobalDataListener:(dataListener: (data: MicroMessage) => any, autoTrigger?: boolean) => void;clearDataListener: () => void;getData: () => MicroMessage;dispatch: <T extends MicroMessage = MicroMessage, C extends Function>(data:T, cb?: C) => void;getGlobalData: () => MicroMessage;setGlobalData: <T extends MicroMessage = MicroMessage, C extends Function>(data:T, cb?: C) => void;};/** 應(yīng)用名稱 */__MICRO_APP_NAME__: string;/** 判斷應(yīng)用是否在微前端環(huán)境中 */__MICRO_APP_ENVIRONMENT__: boolean;/** 子應(yīng)用的靜態(tài)資源前綴 */__MICRO_APP_PUBLIC_PATH__: string;/** 子應(yīng)用的基礎(chǔ)路徑 */__MICRO_APP_BASE_ROUTE__: string;/** 判斷當(dāng)前應(yīng)用是否是主應(yīng)用 */__MICRO_APP_BASE_APPLICATION__: string;/** 獲取真實(shí)window(即主應(yīng)用window) */rawWindow: Window;/** 獲取真實(shí)document(即主應(yīng)用document) */rawDocument: Document;}
}export {}
子應(yīng)用跨域配置
如果我們直接像上述配置一樣直接接入子應(yīng)用,由于瀏覽器的同源策略,如果子應(yīng)用不支持跨域,則會(huì)報(bào)跨域錯(cuò)誤。因此我們需要在子應(yīng)用所在的 web server
進(jìn)行跨域配置:
vite
配置:
export default defineConfig({server: {headers: {'Access-Control-Allow-Origin': '*',}}
})
nodejs
配置(我的 native app
是使用express
搭建的靜態(tài)資源服務(wù),因此這里以該技術(shù)棧舉例):
private setCors() {this.instance.use((req, res, next) => {res.header("Access-Control-Allow-Origin", "*");res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,Content-Type, Accept");next();});}
環(huán)境變量
Micro App
提供了一下環(huán)境變量,用于我們開(kāi)發(fā)過(guò)程中的某些環(huán)境有關(guān)的邏輯判斷,這些環(huán)境變量大多都通過(guò)綁定為 window
對(duì)象的屬性的方式來(lái)使用,因此如果我們使用Typescript
開(kāi)發(fā)子應(yīng)用的話,就要進(jìn)行這些全局變量的變量聲明,我們?cè)谖覀冏討?yīng)用中的聲明文件(vite
構(gòu)建的應(yīng)用的默認(rèn)聲明文件就是根目錄下面的env.d.ts
):
/// <reference types="vite/client" />declare global {interface Window {/** 應(yīng)用名稱 */__MICRO_APP_NAME__: string;/** 判斷應(yīng)用是否在微前端環(huán)境中 */__MICRO_APP_ENVIRONMENT__: boolean;/** 子應(yīng)用的靜態(tài)資源前綴 */__MICRO_APP_PUBLIC_PATH__: string;/** 子應(yīng)用的基礎(chǔ)路徑 */__MICRO_APP_BASE_ROUTE__: string;/** 判斷當(dāng)前應(yīng)用是否是主應(yīng)用 */__MICRO_APP_BASE_APPLICATION__: string;/** 獲取真實(shí)window(即主應(yīng)用window) */rawWindow: Window;/** 獲取真實(shí)document(即主應(yīng)用document) */rawDocument: Document;}
}export {}
生命周期
micro-app
通過(guò)CustomEvent
定義生命周期,在組件渲染過(guò)程中會(huì)觸發(fā)相應(yīng)的生命周期事件。
生命周期列表
-
created:
<micro-app>
標(biāo)簽初始化后,加載資源前觸發(fā)。 -
beforemount:
加載資源完成后,開(kāi)始渲染之前觸發(fā)。 -
mounted:
子應(yīng)用渲染結(jié)束后觸發(fā)。 -
unmount:
子應(yīng)用卸載時(shí)觸發(fā)。 -
error:
子應(yīng)用加載出錯(cuò)時(shí)觸發(fā),只有會(huì)導(dǎo)致渲染終止的錯(cuò)誤才會(huì)觸發(fā)此生命周期。
監(jiān)聽(tīng)方式
Vue
:
<micro-appname='xx'url='xx'onCreated={() => console.log('micro-app元素被創(chuàng)建')}onBeforemount={() => console.log('即將渲染')}onMounted={() => console.log('已經(jīng)渲染完成')}onUnmount={() => console.log('已經(jīng)卸載')}onError={() => console.log('加載出錯(cuò)')}
/>
React
:
因?yàn)镽eact不支持自定義事件,所以我們需要引入一個(gè)polyfill
。
在標(biāo)簽所在的文件頂部
添加polyfill
,注釋也要復(fù)制。
/** @jsxRuntime classic */
/** @jsx jsxCustomEvent */
import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event'<micro-appname='xx'url='xx'onCreated={() => console.log('micro-app元素被創(chuàng)建')}onBeforemount={() => console.log('即將渲染')}onMounted={() => console.log('已經(jīng)渲染完成')}onUnmount={() => console.log('已經(jīng)卸載')}onError={() => console.log('加載出錯(cuò)')}
/>
數(shù)據(jù)通信
數(shù)據(jù)通信這一節(jié)的內(nèi)容在微前端的領(lǐng)域非常重要,這關(guān)乎著各個(gè)子應(yīng)用之間,以及子應(yīng)用與主應(yīng)用之間如何進(jìn)行數(shù)據(jù)通信。
數(shù)據(jù)通信主要分為以下幾種:
- 主應(yīng)用向子應(yīng)用發(fā)送數(shù)據(jù)
- 子應(yīng)用向主應(yīng)用發(fā)送數(shù)據(jù)
- 各個(gè)子應(yīng)用之間的互相通信
主應(yīng)用向子應(yīng)用發(fā)送數(shù)據(jù)
主應(yīng)用給子應(yīng)用傳遞數(shù)據(jù)有兩種方式:
- 通過(guò)data屬性發(fā)送數(shù)據(jù)
- 通過(guò)方法手動(dòng)發(fā)送數(shù)據(jù)
通過(guò)data屬性發(fā)送數(shù)據(jù)
data作為 micro-app
標(biāo)簽的屬性,用該屬性作為主應(yīng)用向子應(yīng)用傳遞數(shù)據(jù)的中介:
<micro-app :name="SubApps.REACT" @created="created" :data="data" keep-alive url="http://localhost:4003/" iframe @datachange="handleChange"></micro-app>const data = ref<MicroMessage>({type: MicroMessageType.TEXT_MSG,value: 'This is a initial TextMessage'
})onMounted(() => {setInterval(() => {data.value.value = 'new value'}, 1000)
})
這種方式類(lèi)似于我們平時(shí)組件中的父子組件傳參,區(qū)別就是,在子應(yīng)用中需要通過(guò)getData
方法區(qū)手動(dòng)獲取數(shù)據(jù),該數(shù)據(jù)不是全響應(yīng)式的(基座中綁定的數(shù)據(jù)如果發(fā)生變化會(huì)動(dòng)態(tài)更改傳給子應(yīng)用的值,但是子應(yīng)用需要通過(guò)getData
方法手動(dòng)獲取更改后的值。)。
子應(yīng)用:
const data = window.microApp.getData()
通過(guò)microApp.setData
方法發(fā)送數(shù)據(jù)
除了通過(guò)data屬性傳遞數(shù)據(jù),還可以通過(guò)microApp.setData
方法動(dòng)態(tài)發(fā)送數(shù)據(jù):
microApp.setData(name, message)
這兩種方法是有區(qū)別的,第一種方法只能通過(guò)getData
方法去手動(dòng)的獲取數(shù)據(jù),數(shù)據(jù)更新時(shí)子應(yīng)用是無(wú)感知的。而第二種方法類(lèi)似于發(fā)布訂閱機(jī)制,子應(yīng)用可以隨時(shí)監(jiān)聽(tīng)到數(shù)據(jù)變化。
子應(yīng)用通過(guò)注冊(cè)事件監(jiān)聽(tīng)數(shù)據(jù)
子應(yīng)用可以使用window.microApp.addDataListener
方法監(jiān)聽(tīng)來(lái)自主應(yīng)用的事件消息:
window.microApp.addDataListener((data: MicroMessage) => {handleMessage(data)
})
我們?cè)谑盏较⒑笸ㄟ^(guò)handleMessage
方法來(lái)統(tǒng)一處理消息。
這里建議:雖然microApp
只要求我們的消息格式是 Object
就可以,但是我這邊建議,我們需要對(duì)消息進(jìn)行一個(gè)統(tǒng)一的格式管理,方便維護(hù)。
比如我這邊利用TS
的特性,對(duì)基座和子應(yīng)用之間的消息進(jìn)行枚舉,然后再定義接口來(lái)約束消息的格式,這樣基座和子應(yīng)用之間處理消息的時(shí)候根據(jù)消息類(lèi)型來(lái)去做對(duì)應(yīng)的處理邏輯:
// 對(duì)消息類(lèi)型進(jìn)行枚舉
export enum MicroMessageType {CHANGE_THEME = 'change_theme',SET_COUNT = 'set_count',TEXT_MSG = 'text_msg',
}// 約束來(lái)基座和子應(yīng)用之間通信的消息格式
interface MicroMessage<T = any> {type: MicroMessageType;value?: T;
}
總的來(lái)說(shuō):通過(guò)data屬性傳遞數(shù)據(jù)和通過(guò)發(fā)布訂閱的模式(消息事件監(jiān)聽(tīng))傳遞數(shù)據(jù)是有區(qū)別的,在實(shí)際場(chǎng)景中根據(jù)自己需要選取使用。
子應(yīng)用向主應(yīng)用發(fā)送數(shù)據(jù)
在微前端種,不僅有主應(yīng)用向子應(yīng)用發(fā)送消息的場(chǎng)景,通常也可能會(huì)有子應(yīng)用向主應(yīng)用發(fā)送消息的場(chǎng)景,在
micro-app
中,子應(yīng)用通過(guò) window.microApp.dispatch
方法發(fā)送數(shù)據(jù),這里同樣為了約束子應(yīng)用向主應(yīng)用發(fā)送的數(shù)據(jù)的格式,我們可以在聲明文件中約定子應(yīng)用推送消息的格式:
dispatch: <T extends MicroMessage = MicroMessage, C extends Function>(data:T, cb?: C) => void
然后我們就可以定義一個(gè)公用的方法用來(lái)向主應(yīng)用發(fā)送數(shù)據(jù):
export const sendMessageToBase = (message: MicroMessage) => {window.microApp.dispatch(message)
}// 使用
const handleSend = () => {sendMessageToBase({type: MicroMessageType.TEXT_MSG,value: {value},});
};
全局?jǐn)?shù)據(jù)通信
全局?jǐn)?shù)據(jù)通信會(huì)向主應(yīng)用和所有子應(yīng)用發(fā)送數(shù)據(jù),在跨應(yīng)用通信的場(chǎng)景中適用。
主應(yīng)用發(fā)送數(shù)據(jù):
import microApp from "@micro-zoe/micro-app";export const sendGlobalData = (message: MicroMessage) => {microApp.setGlobalData(message)
}
子應(yīng)用發(fā)送數(shù)據(jù):
// setGlobalData只接受對(duì)象作為參數(shù)
window.microApp.setGlobalData({type: '全局?jǐn)?shù)據(jù)'})
主應(yīng)用獲取數(shù)據(jù):
microApp.addGlobalDataListener((msg) => {Modal.info({title:`BaseApp收到全局?jǐn)?shù)據(jù)`, content: JSON.stringify(msg), centered:true})mainStore.setGlobalMessages(msg)
}// 或者使用getGlobalData手動(dòng)獲取數(shù)據(jù)
const data = microApp.getGlobalData()
子應(yīng)用獲取數(shù)據(jù):
window.microApp.addGlobalDataListener((data) => {handleGlobalMessage(data)
})// 或者使用getGlobalData手動(dòng)獲取數(shù)據(jù)
const data = window.microApp.getGlobalData()
虛擬路由系統(tǒng)
MicroApp
通過(guò)攔截瀏覽器路由事件以及自定義的location
、history
,實(shí)現(xiàn)了一套虛擬路由系統(tǒng),子應(yīng)用運(yùn)行在這套虛擬路由系統(tǒng)中,和主應(yīng)用的路由進(jìn)行隔離,避免相互影響。建議全局配置路由模式:
microApp.start({'router-mode':'native'
});
MicroApp
提供一下這幾種路由模式:
- search模式
- native模式
- native-scope模式
- pure模式
- state模式
這里就不詳細(xì)說(shuō)明這些路由模式了,這里只說(shuō)常用的兩種:
search模式路由
search是默認(rèn)模式,通常不需要特意設(shè)置,search模式下子應(yīng)用的路由信息會(huì)作為query參數(shù)同步到瀏覽器地址上。這種模式最簡(jiǎn)單也不需要去做其他的配置。
但是這種模式的路由,在頁(yè)面上看起來(lái)會(huì)很奇怪,不建議使用。
native模式路由
native模式是指放開(kāi)路由隔離,子應(yīng)用和主應(yīng)用共同基于瀏覽器路由進(jìn)行渲染,它擁有更加直觀和友好的路由體驗(yàn),但配置方式更加復(fù)雜。需要基于vue-router
的base
配置或者react-router
的basename
配置:
Vue3
中的配置方法:
我們使用4.x版本的vue-router
,在生成路由的方法createWebHashHistory
中傳入base
配置:
history: createWebHashHistory(import.meta.env.VITE_BASE_URL)
這里需要注意這里配置的base
需要和主應(yīng)用中的該子應(yīng)用的routerPath
保持一致,因此推薦使用另一種方法來(lái)設(shè)置而非通過(guò)環(huán)境變量:
<micro-app :name="SubApps.VUE" @created="created" url="http://192.168.8.125:4002/" baseroute="/vue/" iframe @datachange="handleChange"></micro-app>// router/index.ts
const router = createRouter({..............history: createWebHashHistory(window.__MICRO_APP_BASE_ROUTE__ || '/'),..............
}
React中使用
可以根據(jù)官方文檔進(jìn)行配置。
注意:根據(jù)子應(yīng)用和主應(yīng)用不同的路由模式,我們可能需要進(jìn)行不同的配置或者不需要配置,具體查閱官方文檔。
native模式的路由看著就比較清晰了:
總結(jié)
本次分享是對(duì)自己學(xué)習(xí)MicroApp
的過(guò)程的一個(gè)分享,本次demo也只是一個(gè)非常基礎(chǔ)的demo,微前端架構(gòu)需要考慮的內(nèi)容還很多,需要再實(shí)戰(zhàn)中遇到問(wèn)題再積累總結(jié)。
最后:本次demo的源碼放在了https://github.com/rondout/micro-frontend,個(gè)人認(rèn)為這個(gè)demo還是有一定的參考價(jià)值,不光是微前端,還包含了一些前端工程化的內(nèi)容,大家有興趣的話可以clone下來(lái)參考,后續(xù)如果有時(shí)間我也會(huì)繼續(xù)維護(hù)和補(bǔ)充優(yōu)化該demo。