微前端架構初探以及個人前端技術盤點

前言

最近幾年微前端一直是前端界的熱門議題, 它相似於微服務架構, 主要面向於瀏覽器端,能將一個複雜而龐大的單體應用拆分爲多個功能模塊清晰且獨立的子應用,且共同服於務同一個主應用。各個子應用能夠獨立運行、獨立開發和獨立部署。javascript

微前端架構概念的誕生及應用對於提供複雜應用服務的企業來講顯然是一種機遇, 一樣也是一種挑戰.本文主要就微前端架構的概念和實現方案作一個總結和覆盤,而且經過一個實際案例來實踐微前端架構,但願能對一樣有此需求的朋友們提供一些幫助和思路.css

你將收穫

  • 什麼是微服務以及微服務能給企業帶來什麼
  • 微前端架構概念及方案
  • umi下的微前端架構方案實戰
  • 一個程序員的技術覆盤與展望

正文

在總結微前端架構以前,讓咱們來先看看微服務是什麼.html

1.什麼是微服務以及微服務能給企業帶來什麼

微服務是一種用於構建應用的架構方案。微服務架構有別於更爲傳統的單體式方案,可將應用拆分紅多個核心功能。每一個功能都被稱爲一項服務,能夠單獨構建和部署,這意味着各項服務在工做(和出現故障)時不會相互影響。前端

傳統的web軟件開發架構每每以下圖所示: vue

雖然咱們在傳統應用中能夠採用 模塊化來拆分業務邏輯和開發方式,但最終它們會打包並部署爲單體式應用。這種架構每每更適合中小型項目, 開發簡單直接,更適合集中化管理應用.但每每也會存在不少缺點,好比可擴展性不足,相同或者類似業務複用困難,部署時間長, 業務複雜以後很難維護等問題.

對於複雜系統和業務來講,咱們通常會採用微服務架構。其思路是將一個完整的應用分解爲小的、互相鏈接的微服務,每一個服務完成特定的功能, 而且某些特定的服務還能爲其餘服務提供API接口. java

由上圖能夠發現微服務給咱們帶來的好處:

  • 將一個龐大的單體拆解成多個子服務,大大下降了開發複雜度
  • 任務邊界劃分明確, 每一個子服務之間單獨開發, 不一樣服務之間可並行由不一樣的開發人員開發,提升開發效率
  • 更細粒度的增強了模塊化進程, 可維護性和可讀性更高
  • 團隊之間只要制定好API約定, 那麼不一樣成員或者團隊能夠採用不一樣的技術開發服務
  • 可用共享服務, 使得不一樣子服務可組合實現更復雜的功能
  • 每一個微服務可獨立部署發佈,使得自動化CI(持續集成)/CD(持續交付)成爲可能

但微服務並非任何場景下都是合適的, 微服務的目標是充分分解應用程序,以促進敏捷開發和持續集成部署。在部署微服務時咱們須要作好適當的邊界劃分,並處理不一樣微服務之間的併發問題,這些都是對整個項目帶來的挑戰,須要更加專業的技術成員來把控.目前市面上也有不少開源的微服務框架好比Dubbo, Spring Cloud等,筆者以前公司採用的Spring Cloud就是一個很好的微服務架構方案.node

2.微前端架構概念及方案

2.1 理解微前端架構

上面簡單介紹了一下微服務架構,接下來咱們進入主題,來聊聊微前端. 微前端微服務實現的目的相似,都是將應用由單一的單體應用轉變爲多個小型子應用,差異就在於:react

  1. 微前端應用於瀏覽器端,主要是對web應用進行拆解,最後將不一樣子系統(模塊)聚合成一個完整的應用.
  2. 微前端主要目的是聚合,即將不一樣子系統聚合成一個大系統,而微服務架構目前更可能是解耦,即解耦不一樣服務間的依賴.

咱們先來看看微前端的一些思考者. jquery

Michael Geers 大佬發表了一些對微前端的一些思考,內容大體總結一下就是:

「 微前端 」是將微服務的概念擴展到前端領域。爲了構建一個功能強大的瀏覽器應用程序(也稱爲單頁應用程序),當前廣泛的趨勢是將其創建在微服務架構之上。可是隨着時間的流逝,一般由獨立團隊開發的前端層會不斷增加,而且變得更加難以維護。Micro Frontends背後的想法是將Web應用程序視爲由獨立團隊擁有的功能的組合。每一個團隊都有本身關心和專長的不一樣業務或任務領域。每一個團隊能夠跨職能,而且從數據庫到用戶界面,端到端地開發其功能。webpack

正以下面的例子所示:

當咱們的系統中有多個不一樣的子模塊,而且子模塊之間有相對獨立且完整的功能體系時, 一旦子模塊變得愈來愈多, 那麼整個應用將變得很是龐大且臃腫,開發和維護成本大大提升.若是在這種場景下咱們採用SPA模式開發,那麼項目後期將變得不可想象,頁面首次加載將變得很是慢(筆者曾經就經歷過,開發一個複雜系統頁面首次加載花了20多秒,因此不得不採用MPA來處理); 可是咱們採用MPA(多頁應用)模式,雖然解決了應用臃腫的問題, 但仍然存在不少有待處理問題,好比模塊切換須要從新刷新頁面, 公共組件沒法共享,子模塊直接,父子模塊之間的通訊問題,開發部署繁瑣等.這寫都是傳統開發模式會遇到的問題.

試想一下,若是面對以上問題, 若是有一種架構模式, 可讓咱們在主應用中共享公共組件和狀態(可是要保證子應用運行時內部的狀態隔離), 而且不一樣子模塊之間能夠單獨開發部署, 模塊間切換不刷新頁面, 而且模塊之間,父子應用之間能夠經過某種簡單的方式實現通訊,這樣是否是就完美了?不錯, 這也許就是微前端要解決的問題.

每每企業的中後臺系統更加適合使用微前端架構,由於B端大部分都是業務驅動,而每每這些業務之間會很是複雜, 好比Saas, Paas等系統.像相似於雲平臺,CRM,ERP系統每每是微前端架構的拯救對象.

筆者曾經接手的ERP系統,因爲開發時間比較早,每每有不少遺留的歷史包袱,好比新老技術棧的糅合, 前端業務代碼龐大而毫無違和感,爲了對其繼續迭代開發, 重構是必經之路,微前端另外一個重要的做用筆者認爲就是解放.解放不可挽回的痛😭.

筆者以前在寫從0到1教你搭建前端團隊的組件系統(高級進階必備)這篇文章時簡單提了一下微前端的一些知識,這裏先回放一張筆者以前作的簡陋的圖,方便你們理解微前端架構.

但咱們所看到的不是事實的所有,在文章後面筆者會總結一張更全面的圖,來整理微前端的一些實踐應用.

2.2 微前端架構實現的方案

上面內容咱們大體瞭解了一下微前端的概念和做用,接下來筆者總結一下曾經經歷過的微前端實現方案.

1. 基於MPA + iframe + requirejs實現的微前端架構 這是筆者接手最先的一個項目,主要是服務於企業內部的ERP系統,當時採用的技術棧主要是jquery+layui+requirejs,記得仍是筆者剛畢業時參與的項目.主要是利用AMD模塊化機制來複用代碼,當時項目代碼及其龐大複雜,大體架構以下:

傳統實現方式通常是通多多頁面的方式來對應用解耦,並採用模塊化加載機制來導入可複用組件.系統間通型採用storage+window.opener+iframe.好比咱們一個大系統的首頁可能會有來自不一樣子系統的頁面,已iframe的方式嵌入.不一樣子系統間由不一樣的人維護,雖然作到了微前端的模式,可是仍是有不少缺點.
改架構的通常分工是架構組主要負責制定架構標準和規範,維護公共模塊(相似於如今的組件,當時因爲採用jquery生態,能夠簡單的說成公共UI插件的維護);業務組主要負責編寫業務代碼,實現某個系統的具體交互和功能。

2. 基於MPA + iframe + Webpack實現的微前端架構 基於MPA + iframe + Webpack實現的微前端架構實現和上面介紹的傳統架構實現相似,只不過採用了更新的技術棧,以及真正的模塊化,組件化技術。筆者以前作的Saas系統就是一個很典型的該方案的例子:

上圖可知不一樣子系統之間能夠各自維護,單獨打包部署,最後經過node或者nginx作路由分發。咱們採用公共的ui組件庫和js類庫來抽離公共組件,可是前提是不一樣組件庫和技術棧強相關,若是沒有歷史遺留的新項目,建議採用一致的技術棧。

以上兩個方案的缺點就是組件庫只能複用而沒法真正共享,而且切換路由會致使頁面從新渲染刷新。父子系統通訊困難,仍然須要iframe最爲容器來通訊。(有關iframe父子頁面通訊的各類方式筆者在記一次老項目中的跨頁面通訊問題和前端實現文件下載功能

3. 基umi + qiankun實現的微前端架構 目前市面上也有很是成熟的微前端架構方案,好比single-spa,以前的美團外賣微前端架構和螞蟻金服基於single-spa開發的微前端架構qiankun(乾坤),都是很是不錯的方案。

qiankun主要採用HTML Entry模式,直接將子應用打出來 HTML做爲入口,主框架能夠經過 fetch html 的方式獲取子應用的靜態資源,同時將 HTML document 做爲子節點塞到主框架的容器中。這樣不只能夠極大的減小主應用的接入成本,子應用的開發方式及打包方式基本上也不須要調整,並且能夠自然的解決子應用之間樣式隔離的問題。

其方案具備以下特色:

  • 支持子應用並行
  • 支持js沙箱環境(js隔離)
  • css隔離
  • HTML Entry,簡化開發者使用
  • 按需加載
  • 公共依賴加載
  • 父子應用通訊機制
  • 子應用嵌套

由於咱們的前端項目基於umi生態開發構建(以前採用webpack搭建,後面發現umi使用也很爽,就直接基於umi二次開發了),因此很天然的選擇了乾坤做爲微前端架構。具體架構以下:

3.umi下的微前端架構方案實戰

接下來我具體介紹如何使用乾坤來搭建咱們的微前端架構,因爲咱們內部採用umi,因此這裏咱們直接使用其提供的@umijs/plugin-qiankun插件來實現。(好處就是改動成本幾乎爲零) 首先咱們來實現這樣一個場景:咱們有一個主應用做爲基座工程,而後有3個子系統,他們是獨立建立維護的,能夠採用不一樣的git倉庫來管理。當咱們在主應用中切換路由時會切換到對應的子系統,且不刷新頁面,徹底的SPA體驗,接下來咱們來具體實現一下吧。

這裏咱們採用umi2.0來開發,關於如何安裝與使用umi,這裏就不作詳細介紹了。

  1. 建立工程
mkdir mainSystem subSystemA subSystemB subSystemC
// 分別進入各系統目錄下,執行如下命令建立咱們的項目
yarn create umi
複製代碼
  1. 在各個系統下安裝@umijs/plugin-qiankun插件
yarn add @umijs/plugin-qiankun
複製代碼
  1. 主應用下的配置
// .umirc.js
export default {
  plugins: [
    [
      '@umijs/plugin-qiankun',
      {
        master: {
          // 註冊子應用信息
          jsSandbox: true, // 是否啓用 js 沙箱,默認爲 false
          prefetch: true, // 是否啓用 prefetch 特性,默認爲 true
        },
      },
    ],
  ],
};
// app.js
const isDev = process.env.NODE_ENV === 'development'
export const qiankun = {
  apps: [
    {
      mountElementId: 'root-subapp-container',  // 洗子應用掛載的節點
      name: 'subSystemA', // 惟一 id,和package對應的name字段最好保持一致
      entry: isDev ? '//localhost:8001' : '/subSystemA/index.html', // html entry
      base: '/subSystemA',  的路由前綴,經過這個前綴判斷是否要啓動該應用,一般跟子應用的 base 保持一致
      history: 'browser', // 子應用的 history 配置,默認爲當前主應用 history 配置
    },
    {
      mountElementId: 'root-subapp-container',
      name: 'subSystemB',
      entry: isDev ? '//localhost:8002' : '/subSystemB/index.html',
      base: '/subSystemB',
    },
    {
      mountElementId: 'root-subapp-container',
      name: 'subSystemC',
      entry: isDev ? '//localhost:8003' : '/subSystemB/index.html',
      base: '/subSystemC',
    }
  ],
  fetch: url => {
    return fetch(url)
  }
};
複製代碼

以上是基本的配置,固然咱們還能夠在app.js裏面加入lifeCycles等鉤子來控制不一樣生命週期下的行爲。

在子應用中咱們一樣須要引入@umijs/plugin-qiankun這個插件,具體配置以下:

export default {
  base: `/${appName}`, // 子應用的 base,默認爲 package.json 中的 name 字段
  plugins: ['@umijs/plugin-qiankun', { slave: true }],
};
複製代碼

基本準備工做已經完成,剩下就是編寫業務代碼了,咱們要想讓整個應用一塊兒跑起來,須要先啓動基座工程,而後再啓動對應的子工程(固然他們能夠單獨運行)。

可是值得注意的是咱們在開發環境中採用devServer提供的帶來才能跨域抓取資源,若是應用發佈到線上,若是不一樣子應用採用不一樣域名,咱們還須要解決跨域問題(跨域解決的方案及安全機制也有不少,已經再也不是個問題)。實際開發環境咱們須要考慮的問題還有不少,這裏只作簡單介紹,不過根據官方提供的api基本上能夠知足大部分的需求場景,因此仍是很是值得一試的。筆者後期也會寫一個微前端的實際案例發佈到github上,能夠一塊兒交流學習。

4.一個程序員的技術覆盤與展望

因爲今年受疫情影響,工做任務比較緊張,覆盤的時間也比較少,可是筆者仍是會堅持每週更新1-2篇文章,來總結和覆盤工做中或學到的新技術。本身寫的零零散散的文章是時候作一個分類和梳理,以便更加清晰將來的方向和不足的補救。

1.node相關

2.工程化相關

3. 設計模式

4.react相關

5.vue/angular相關

6.css相關

7.算法相關

8. H5遊戲

9.原生javascript類庫設計封裝

10.工做問題彙總

最後

若是想學習更多H5遊戲, webpacknodegulpcss3javascriptnodeJScanvas數據可視化等前端知識和實戰,歡迎在公號《趣談前端》加入咱們的技術羣一塊兒學習討論,共同探索前端的邊界。

相關文章
相關標籤/搜索