什么?你還不會 OpenTiny 跨框架組件庫適配微前端?

本文由體驗技術(shù)團隊?TinyVue 組件庫成員陳家梅同學分享,帶你手把手實現(xiàn) TinyVue 組件庫適配微前端~
一、前言
以下是我對微前端的一些粗淺理解,對微前端有一定了解的話可以略過,直接進入第二部分。
1、微前端是什么?
我們首先來點熟悉的東西,以我們最常見的頁面為例,看下圖:

左側(cè)為子應(yīng)用路由切換,通過點擊左側(cè)完成右側(cè)頁面子應(yīng)用的切換,這就是一個最簡單的微前端應(yīng)用架構(gòu)了。
作為一名資深打工人,為了便于理解,我把微前端類比成一家企業(yè),當它發(fā)展到了一定規(guī)模時,效率會變得低下,運行遲緩。此時為了便于管理,提高能效,加強部門之間的協(xié)作;一般會分化出幾家子公司 + 一個總公司(或總部)。
其特點是:每家子公司都可以獨立運作,也可以互相協(xié)作,但都聽從總部的統(tǒng)一管理,至此,我們就有了微前端的基本概念。
微前端借鑒了后端比較成熟的微服務(wù)概念:
形式上:通過將各個子應(yīng)用和一主應(yīng)用統(tǒng)一組織起來,構(gòu)成一個集成應(yīng)用;
獨立性:這些子應(yīng)用可以單獨部署,單獨運行,單獨擴展,相互之間狀態(tài)隔離;技術(shù)棧獨立,相對不受限;
通信上:可以相互通信。子應(yīng)用可以共享主應(yīng)用數(shù)據(jù)。也可共享兄弟應(yīng)用數(shù)據(jù)。
2、為什么需要微前端,它有什么優(yōu)點?
一個優(yōu)秀的微前端框架應(yīng)當有如下優(yōu)點:

①:應(yīng)用之間互相獨立:包括了 js 沙箱、css 隔離等;
②:支持父與子,子與子應(yīng)用之間的通訊;
③:性能方面支持預(yù)加載和按需加載機制;
④:多個公共依賴的共享處理。
一個優(yōu)秀的前端工程像一家優(yōu)秀的企業(yè)一樣,當項目的業(yè)務(wù)達到了一定的規(guī)模,高度集成為一個巨無霸,為了降低運行消耗、維護的時間和人力成本,提升用戶的終端體驗;拆分+整合就勢在必行了。
想象一個場景:(作為一名剛?cè)肼毠镜那岸斯こ處?,不管你是初級還是資深,面對使用不同技術(shù)棧、相互之間業(yè)務(wù)耦合性大的多個項目;或者是一個高度集成、體量龐大,運行緩慢的巨石項目,你要怎么處理才能降低項目維護成本,提升性能,從而提升效率,提升用戶體驗?
第一種情況:項目多且雜我就遇到過,工程師們加班加點的修 bug;但愣是換了一批又一批人,還是沒有改善現(xiàn)狀,進入了一個惡性循環(huán))。
所以我們急需一種能整合所有項目,并且單個項目又能獨立運作的技術(shù)方案。
此時有條件的研發(fā)團隊,一般都會選擇微前端,接入同一套主系統(tǒng),既能獨立運行又可相互通信,兼顧了流暢體驗和信息共享。
在選擇了一款優(yōu)秀的微前端架構(gòu)的前提下,需要注意:此時組件庫的選擇就能展現(xiàn)出工程師眼光的差距了;是有 n 種前端框架就使用 n 個組件庫好,還是 n 種前端框架就使用一個組件庫好呢?
我比較懶、想節(jié)省時間、想早點下班...... 而且一套東西越用越熟練,效率越高,不拘泥于技術(shù)棧,可以一當十(想當年六大門派圍攻光明頂,我張無忌以一當......額,回歸正題),至此 @opentiny/vue 就成了我不二之選。
那么如何做?
3、需要怎么做?
下面我們用 @opentiny/vue 組件庫,在各個子應(yīng)用中引入并使用,共用一套 @opentiny/vue-renderless 方法,實現(xiàn)多個技術(shù)??缍艘谩?/p>
經(jīng)過多方對比,我們選擇了目前比較合適的(無界)微前端框架,接入相對簡單,并兼具一款優(yōu)秀微前端框架的優(yōu)點。
跟著我們一起來動手吧!
二、項目結(jié)構(gòu)
1、動手之前我們先了解一下要實現(xiàn)的項目結(jié)構(gòu),如圖:
根目錄主要分為:pnpm?單包管理.yaml 文件 + packages 目錄;

packages 目錄分為:一個主工程+四個子工程。

主工程目錄如下:我們需要編寫的文件分別是路由文件 router/index.js + views 目錄下的五個展示的頁面。

四個子工程目錄結(jié)構(gòu)分別如下:
前三個我們只簡單的在其首頁編寫 @opentiny/vue 中兩個組件的使用,展示的內(nèi)容都是計時器和按鈕;



最后一個 Vue3 項目我們在一個頁面展示了 pc、mobile 和 watch 三端的內(nèi)容,所以需要編寫的內(nèi)容會多一點;

這樣就完成了我們此次的目的 => 跨框架使用我們的 @opentiny/vue 組件庫。
2、了解了我們要實現(xiàn)的項目結(jié)構(gòu),接下來就是實現(xiàn)的思路:
我們分為三個階段:
初始化 pnpm 和微前端工程;
創(chuàng)建一個主工程
創(chuàng)建四個子工程
最后啟動查看效果。
三、初始化
使用 pnpm 管理組件庫工程和微前端工程
1、創(chuàng)建 monorepo 工程根目錄,使用 gitbash 輸入以下命令(以下所有命令均在 gitbase 環(huán)境下運行):
2、創(chuàng)建組件源代碼目錄:
這里就不再介紹跨端組件庫的實現(xiàn)了(關(guān)于如何實現(xiàn)跨框架組件庫可以參考:原來 TinyVue 組件庫跨框架(vue2、vue3、react、solid)是這樣實現(xiàn)的?),
我們直接將線上文件夾寫好的 components 直接復(fù)制到我們 packages 目錄下的 components ,完成適配 => 線上文件夾地址:https://github.com/opentiny/cross-framework-component/tree/master/packages/components
3、在根目錄下創(chuàng)建 package.json,并修改其內(nèi)容:
package.json 內(nèi)容主要分為兩塊:
(1)定義包管理工具和一些啟動工程的腳本:
? ? "preinstall": "npx only-allow pnpm"? -- 本項目只允許使用pnpm管理依賴
? ? "dev": "node setup.js" -- 啟動無界微前端的主工程和所有子工程
? ? "dev:home": "pnpm -C packages/home dev" -- 啟動無界微前端的主工程(vue3框架)
? ? "dev:react": "pnpm -C packages/react dev" -- 啟動無界微前端的react子工程
? ? "dev:solid": "pnpm -C packages/solid dev" -- 啟動無界微前端的solid子工程
? ? "dev:vue2": "pnpm -C packages/vue2 dev" -- 啟動無界微前端的vue2子工程
? ? "dev:vue3": "pnpm -C packages/vue3 dev" -- 啟動無界微前端的vue3子工程
(2)解決一些 pnpm 針對 Vue 不同版本(Vue2、Vue3)的依賴沖突,packageExtensions 項可以讓 Vue2 相關(guān)依賴可以找到正確的 Vue 版本,從而可以正常加載 Vue2 和 Vue3 的組件。
package.json 文件具體內(nèi)容如下所示:
4、在根目錄創(chuàng)建配置文件 pnpm-workspace.yaml,文件內(nèi)容如下:
至此初始化已經(jīng)完成,我們總共完成了四件事:
創(chuàng)建根目錄+packages 子包目錄;
創(chuàng)建 packages 的 components 子目錄,完成不同框架的適配;
在根目錄下創(chuàng)建包管理文件 package.json,用于定義子應(yīng)用的啟動命令和解決依賴沖突的問題;
在根目錄下創(chuàng)建單包配置文件 pnpm-workspace.yaml;
這樣項目配置基本完成,我們就可以開始將注意力集中于編寫我們的頁面了。
四、創(chuàng)建一個主工程
主工程最重要的是編寫頁面,用來串聯(lián)起四個子應(yīng)用,因此創(chuàng)建頁面后,路由便是我們主工程的重中之重。
主工程路由如下,默認路徑或 /home 是集成展示所有子應(yīng)用的首頁,剩下的四個路徑分別對應(yīng)子應(yīng)用的首頁展示。

1、使用 vite 腳手架創(chuàng)建一個 Vue3 的工程,運行命令如下:
2、下載安裝無界微前端的 Vue3 依賴包和 vue-router 路由:
這里先簡單了解一下無界頁面的編寫<WujieVue> 元素的用法,以如下代碼為例:
3、進入主工程,在 packages/home/src 下新建 views 文件夾,并在文件夾中創(chuàng)建一個主頁面和四個子頁面,分別為:Home.vue(主頁--集成頁面)、React.vue、Solid.vue、Vue2.vue、Vue3.vue 為四個子頁面
Home.vue
React.vue:展示 react 子應(yīng)用的窗口頁面
Solid.vue、Vue2.vue、Vue3.vue 這三個文件和 React.vue 代碼幾乎是相同的,不一樣的只有 name 屬性和端口號;都是用于展示相應(yīng)子工程的窗口頁面;如下圖所示:



5、跟 Vue 創(chuàng)建路由一樣,在 packages/home/src/router 下創(chuàng)建路由文件 index.js,并引入上文創(chuàng)建的幾個頁面,內(nèi)容如下:
6、然后在 Home 主工程的主入口注冊 wujie-vue3 和路由。
至此,我們主工程的頁面和路由已創(chuàng)建完成。每個子工程在主工程都有自己的“展臺”,那么接下來我們就著手編寫我們的子工程。
五、創(chuàng)建四個子工程
在開始創(chuàng)建之前,前面我們已經(jīng)了解了四個子工程的項目結(jié)構(gòu),那就有思路了:
通過 vite 可以很方便快捷完成創(chuàng)建;
通過 vite 配置文件配置端口號和相應(yīng)的插件,需要注意:Vue2 和 Vue3 的配置需額外做別名適配,對應(yīng)上 @opentiny/vue 的 common 層;
每個子工程的 package.json 依賴中,添加我們當時復(fù)制的 components 文件夾下的 npm 包,對應(yīng)實時加載上我們要使用的組件;
最后就是使用我們的組件編寫頁面了;
話不多說,跟著我們的步驟走起來~
1、在主工程 home 的同級目錄,分別使用 React、Solid、Vue 的 vite 套件創(chuàng)建四個子工程,依次為:react/solid/vue2/vue3:
2、然后分別配置四個子工程vite.config.js,設(shè)置不同的端口號(React:2001、Solid:2002、Vue2:2003、Vue3:2004)
React/vite.config.js:
Solid/vite.config.js:
Vue2、Vue3 的 vite.config.js 需要一些別名適配,對接 vue-common 適配層。
Vue2/vite.config.js:
Vue3/vite.config.js:
3、分別在四個子工程根目錄的 package.json 的 dependencies 鍵中添加如下依賴包,用來加載本地跨框架的 button 組件和倒計時 countdown 組件:
4、在四個子工程里使用 button 組件和倒計時 countdown 組件,自定義一些交互邏輯如下:
React/src/app.jsx:
Solid/src/app.jsx:
Vue2/src/app.vue:
Vue3 的頁面涉及到跨 pc、mobile、watch 端,內(nèi)容比較多,可以直接 copy 線上的內(nèi)容:
https://github.com/opentiny/cross-framework-component/tree/master/packages/vue3
六、啟動創(chuàng)建好的微前端
接下來,進入我們的根目錄,分別運行以下命令啟動四個子工程
1、運行 React 子應(yīng)用:
效果如下所示:

2、運行 Solid 子應(yīng)用:
效果入下圖所示:

3、運行 Vue2 子應(yīng)用:
效果如下圖所示:

4、運行 Vue3 子應(yīng)用:
效果如下圖所示:

5、啟動微前端主應(yīng)用:
效果如下圖所示:

6、一鍵啟動(如果覺得繁瑣,那我會選擇這種方式):直接使用腳本一個命令啟動所有微前端工程,在根目錄創(chuàng)建 setup.js,其內(nèi)容如下:
然后在根目錄的 package.json 中的 script 命令中添加以下命令:
最后只需要一個命令就可以啟動所有的微前端工程:
七、源代碼倉庫參考
1、使用以下命令把演示 Demo 克隆到本地:
2、使用 pnpm 下載依賴:
3、工程目錄結(jié)構(gòu)分析
整個工程是基于 pnpm 搭建的多包 monorepo 工程,演示環(huán)境為無界微前端,整體工程的目錄架構(gòu)如下所示:
4、效果展示,啟動本地的無界微前端本地服務(wù)
總共會啟動5個工程,1個主工程和4個子工程,4個子工程分別用到 Vue2、Vue3、React、Solid 框架,并都使用了 OpenTiny 的跨框架組件庫。
效果如下圖所示:

八、結(jié)語
我們通過對微前端的粗淺了解,以及從0到1搭建起整個微前端的項目,能明顯感覺到在單頁面應(yīng)用流行的當下,若變?yōu)榫奘瘧?yīng)用時,微前端的重要性;與此同時,如何選擇一款好的組件庫適配好的微前端框架,也會成為我們前端從業(yè)者考慮的重點。
跟著本文的教程實踐下來,大家應(yīng)該能明顯感覺到,我們 @opentiny/vue 組件庫不管是適配不同技術(shù)棧,還是使用、功能方面,都是很容易上手的。
想當年我張無忌以一敵......
關(guān)于 OpenTiny

OpenTiny 是一套企業(yè)級 Web 前端開發(fā)解決方案,提供跨端、跨框架、跨版本的 TinyVue 組件庫,包含基于 Angular+TypeScript 的 TinyNG 組件庫,擁有靈活擴展的低代碼引擎 TinyEngine,具備主題配置系統(tǒng)TinyTheme / 中后臺模板 TinyPro/ TinyCLI 命令行等豐富的效率提升工具,可幫助開發(fā)者高效開發(fā) Web 應(yīng)用。
歡迎加入 OpenTiny 開源社區(qū)。添加微信小助手:opentiny-official 一起參與交流前端技術(shù)~
OpenTiny 官網(wǎng):https://opentiny.design/
OpenTiny 代碼倉庫:https://github.com/opentiny/
TinyVue 源碼:https://github.com/opentiny/tiny-vue
TinyEngine 源碼:?https://github.com/opentiny/tiny-engine
歡迎進入代碼倉庫 Star??TinyEngine、TinyVue、TinyNG、TinyCLI~
如果你也想要共建,可以進入代碼倉庫,找到?good first issue標簽,一起參與開源貢獻~