天天看點

vivo 商城前端架構更新-總覽篇

本文主要以 vivo 商城的前端開發經驗,結合實際案例,探讨如何在業務版本高速疊代的情況下,進行大幅度的架構改造,讓前端開發從蠻荒的 Java Web 時代躍進到高速的資訊時代。

本文首發于 vivo網際網路技術 微信公衆号

連結: https://mp.weixin.qq.com/s/vD9yvYNaxTQBLABik6aqNg

作者:官網商城前端團隊

【背景】

一年前 vivo 商城還是以 Java 為技術核心,前背景一起,Java 既要負責服務、資料庫,也要負責頁面的渲染。在早期這種開發模式也能夠很好的運作。然而随着業務疊代的加快,前端技術的發展,這種開發模式的弊端越來越明顯。主要突出的有以下兩個方面:

  • 前端技術棧架構繁雜且陳舊,導緻疊代速度很難提升

到2018年12月,整個商城前端系統随着不同需求疊加積累的原因,造成了不同頁面使用不同的技術,比較典型的有jQuery,Vue,FreeMarker,artTemplate,這些不同的技術棧從開發來看,相同的内容,在不同的頁面可能使用不同的技術棧,導緻需要開發很多遍,對開發、測試來說工作量都是成倍的增長。

  • 無法适用多端開發的需求

自2017年微信上線小程式功能後,各種小程式如雨後春筍般出現,vivo 商城一開始也推出了自己的微信小程式,然而由于業務發展,需要适配的端越來越多,原先使用原生開發的小程式方式,無法做到一套代碼編到多個平台。

為了提升開發效率,滿足高速發展的業務需求,在過去的一年裡,我們通過對商城内外部系統的全面分析,按照分層的邏輯整理出前端架構的更新指導說明。

【分層架構】

在《前端架構-從入門到微前端》一書中提到,前端架構自上而下可以設計為四個層次,分别為系統級、應用級、子產品級、代碼級,我們通過這四個層次來分析vivo商城前端架構更新過程中的種種思考和實踐,最終形成了一套以Vue + Node.js為核心的全端架構方案。

技術演進過程:

vivo 商城前端架構更新-總覽篇

分層架構實施圖:

vivo 商城前端架構更新-總覽篇

一、系統級

即應用在整個系統内的關系,比如如何和背景通訊,如何與其他應用內建。針對這一級别,我們進行了前後端分離、多端統一、BFF、SSR等方面的探索和實踐。

1、前後端分離

架構更新,第一步面臨的問題便是前後端分離,vivo 商城仍然處于業務高速發展時期,不能因為技術重構而停下業務版本的疊代, 是以業務版本疊代必須要和前後端分離同時進行,那怎麼才能做到雙線并行,平滑更新?

這裡舉個小例子:當我們分離完成訂單子產品後,就會通過 Nginx 将關于訂單子產品的所有請求轉發到新的靜态資源服務上,如下圖:

vivo 商城前端架構更新-總覽篇

通過前後端分離,我們徹底解放前端,讓前端開發效率提升了至少2個檔次。

更多技術細節比如:新老頁面如何同步資訊,如何容災容錯等等,請關注我們的系列第二篇《vivo商城前端架構更新(二):前後端分離篇》

2、多端統一

從 PC 浏覽器,到移動端浏覽器、到 App 内嵌,再到各個小程式,再到服務端、用戶端。繁榮的生态,猶如百家争鳴,百花齊放。然而,繁榮的背後,對前端工程師的挑戰,則與日俱增。

我們承接的端越來越多,新的端不斷的出現,如小程式、快應用等。前端工程師陷入了如下套娃陷阱:

  1. 現有代碼、新代碼要适配新的端開發場景
  2. 已經适配新的端開發場景的代碼成為了現有代碼
  3. 循環...

我們希望解決這種問題,希望做到一套技術架構方案【代碼】,可以覆寫現在的端和未來的端。

通俗點說,我們希望做到如下圖所示的能力:

vivo 商城前端架構更新-總覽篇

在這種前端開發背景下,多端統一出現了。它是前端的一個未來趨勢,它也是解決上面套娃陷阱的一劑良藥。

更多細節内容,請關注我們的系列第三篇《vivo商城前端架構更新(三):多端實踐篇》

3、BFF

  • 業務現狀

随着端的增多,新的接口數量呈現爆發式增長,老的接口為了适配各端,也會增加了各種不同的字段,導緻前後端适配多端的工作量越來越大。但是抽象來看,大部分端的變動都是UI層級的變動,很少有底層服務的改變,是以帶來了一個問題接口究竟是面向UI,還是面向通用服務?

為了解決這個問題,Sam Newman 發表了一篇文章,講述了這種體驗者專用 API 的方式,并将其稱為BFF(Backends for Frontends)模式。

在BFF理念中,最重要的一點是:服務自治,誰使用誰開發。服務自治減少了溝通成本,帶來了靈活和高效。

  • 關鍵技術

商城前端積極适應前端技術的發展,為了提供一流的使用者體驗,積極推動BFF層在商城業務中的實作。

vivo 商城前端架構更新-總覽篇
  • 直連Dubbo:
Apache Dubbo 是一款高性能、輕量級的開源Java RPC架構,它提供了三大核心能力:面向接口的遠端方法調用,智能容錯和負載均衡,以及服務自動注冊和發現。

我們使用了社群提供的 Dubbo2.js 進行 Dubbo 服務的調用,并且做了一些封裝來優化發開體驗。

vivo 商城前端架構更新-總覽篇
  • 內建GraphQL網關:

GraphQL 是一個開源的 API 資料查詢和操作語言及實作為了實作上述操作的相應運作環境。相較于REST以及其他 web service架構提供了一種高效、強大和靈活的開發 web APIs的方式。

(1)請求你所要的資料 不多不少

vivo 商城前端架構更新-總覽篇

(2)擷取多個資源 隻用一個請求

vivo 商城前端架構更新-總覽篇

(3)強大的API調試工具

vivo 商城前端架構更新-總覽篇

4、SSR

自從前後端分離後,前端采用了SPA技術,走的都是CSR(用戶端渲染)的模式。使用CSR的優勢在于節省後端資源、局部重新整理等,但随着應用的日益複雜,首屏渲染時間不斷變長, 并且存在嚴重的 SEO 問題。是以為了解決SPA應用遇到的這些問題, 我們必須考慮 SSR。

SSR 即服務端渲染,是指由伺服器端完成頁面的HTML 結構拼接,并且直接将拼接好的HTML發送到浏覽器,然後為其綁定狀态與事件,成為完全可互動頁面的處理技術。
vivo 商城前端架構更新-總覽篇

主要優勢在于:

  1. 更好的 SEO,由于搜尋引擎爬蟲抓取工具可以直接檢視完全渲染的頁面。
  2. 更快的内容到達時間 (time-to-content),特别是對于緩慢的網絡情況或運作緩慢的裝置。

為了避免重複造輪子,我們使用了社群非常優秀的SSR架構nuxt,通過一系列的優化,比如:頁面緩存、元件緩存、API緩存、最小化渲染等方式,最終讓我們頁面在500ms内就能全部展示,這是使用者體驗上的極大提升。

二、應用級

即應用外部的整體架構,如多個應用之間如何共享元件、如何通信、如何開發通用腳手架等。在應用級别的架構上面,我們主要沉澱了适用于商城的UI庫,為其他商城衍生項目提供基礎元件支援。

1、元件庫

移動端的設計千變萬化,市場上非常流行的移動端的元件庫比如antd-mobile , vant,他們對于開發通用型的 App,非常高效且美觀,然而大部分自主研發的 App都有自己的一套設計風格和理論。如果使用流行的元件庫,就會出現頻繁需要修改源碼,以适應UI風格的變化。這樣的工作量日積月累,就會變得越來越大。是以我們還是建議如果是做自己特色的App,還是要自建UI庫。如果感覺自建UI庫難度較大,可以先fork一份流行的元件庫,學習其中的各種實作,慢慢形成自己的UI庫。

商城也實作了自己的UI庫,目前已經在商城、秒殺、vivo 内購、v客聯盟等應用中廣泛使用,極大的提高了開發效率。如下圖:

vivo 商城前端架構更新-總覽篇

三、子產品級

應用内部的子產品架構,如代碼的子產品化、資料和狀态的管理等,在項目中比較典型的是我們設計了針對 Vue 的極緻子產品化方案,頂層 page 設計,資料自治等方面的工作。

1、極緻子產品化

我們的方案擯棄了官方推薦的按檔案類型組織子產品,而采用按照功能組織子產品,這種"可插拔式"元件設計,讓代碼按照功能聚合。

vivo 商城前端架構更新-總覽篇

一個檔案包裡面包含該功能的所有實作,包括圖檔、樣式、腳本、資料流、元件等等,這樣另一個項目想要使用,直接遷移即可,極大地減少了遷移的成本,并且還有一個優勢是,如果這個功能以後下架,直接删除即可,不必各個檔案夾下找檔案,極大地提升了代碼的簡潔性和可維護性。

➜  confirm git:(dev_abtest_gray) tree 
.
├── api.js     // 接口資源
├── components // 内部元件
│   ├── component1
│   │   ├── images
│   │   ├── index.scss
│   │   └── index.vue
│   ├── component2
├── images   // 圖檔資源
├── index.scss // 樣式資源
├── index.vue  // 邏輯實作
├── module.js  // 資料流
└── trackData.js // 埋點      

2、頂層 page 設計

所有的頁面都會有很多通用的功能,比如加載前的骨架圖、出錯後的處理邏輯、資料采集邏輯、上拉重新整理、下滑分頁加載,全局 iOS 适配等等,這些功能在邏輯上是需要抽象的,避免各個頁面多次實作,導緻浪費開發資源和降低程式的可維護性。

針對此我們實作了一個頂級 page 元件,所有的頁面都繼承于這個 page 。做到通用性的功能全局管理。

頂級 page 的部分 API 使用如下:

<template>
  <v-page
    // 頁面是否完成
    :pageInit="true"
    // 頁面是否出錯
    :pageError="false"
    // 頁面監控開啟,包括pv,uv,渲染時間
    :pageMonitor="true"
    // 上拉重新整理
    @pullDownRefresh="pullDownRefresh"
    // 下拉監聽
    @reachBottom="reachBottom"
    // 滾動監聽
    @pageScroll="pageScroll"
  >
    <template slot="header">
      <!-- 自定義頭部,如果沒有則使用預設頂部導航菜單 -->
      <Header />
    </template>
    <template slot="skeleton">
      <!-- 自己實作的骨架圖,如果沒有則使用預設骨架圖-->
      <Skeleton />
    </template>
    <template slot="footer">
      <!-- 自己實作的底部,吸底顯示,如果沒有則不顯示-->
      <Footer />
    </template>
  </v-page>
</template>      

3、資料自治

本着誰使用,誰負責的原則,對于頁面中的資料流也是一樣的,我們開發了針對page的全局mixin,負責自動注冊和解除安裝頁面資料,并将各個頁面之間的資料進行隔離。

import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'

export default (name, module) => ({
  computed: {
    ...mapState(name, Object.keys(module.state)),
    ...mapGetters(name, Object.keys(module.getters))
  },
  created () {
    // todo 要加判斷是否已經注冊,動态注冊子產品
    if (!(name in this.$store._modules.root._children)) {
      this.$store.registerModule(name, module)
    }
  },
  methods: {
    ...mapActions(name, Object.keys(module.actions)),
    ...mapMutations(name, Object.keys(module.mutations))
  }
})      

四、代碼級

當我們開始編寫代碼的時候,就要考慮代碼的規範和品質。規範的目的是為了提升維護性,而品質則是開發的門面,一個好的項目離不開這這兩個内容的限制。

1、規範

一個好的規範應該做到簡單、好記、易于執行。為了實作這個目标,我們制定了一系列的規範,最主要的是開發規範、送出規範。

每個項目組的規範可能都不一樣,需要根據自己的項目特色,可以參考優秀的項目實踐,整理出自己的項目規範,小組内部讨論優化,達成一緻意見,最後釋出執行。每一位新進項目組的成員,首先要做的就是學習這些規範,用規範引導開發。

(1)開發規範

包含但不局限于以下内容:命名規範、HTML 規範、css規範、js規範。

(2)送出規範:

為了規範送出代碼,進而友善開發者追蹤項目的開發資訊和功能特性,我們封裝了**@vivo/commit**,對我們的送出進行強制校驗。比如:

vivo 商城前端架構更新-總覽篇

每一條commit由四個部分組成,如下圖:

vivo 商城前端架構更新-總覽篇
  • 修改類型

style: 樣式修改

fix: bug修複

feat: 功能開發

refactor: 代碼重構

test: 測試類修改

doc: 文檔更新

conf: 配置修改

merge: 代碼合并

  • 影響子產品

每一條commit,應明确指出其影響範圍是哪個子產品,如果是通用子產品,注釋上(全局)字樣,友善code reviewer對方案進行評估

  • 跟蹤單号

每一條commit,必須要有單号,每個公司都有自己的缺陷跟蹤系統,單号的目的是為了讓每一條送出有據可循,友善後續對問題的回溯。

  • 問題描述

問題描述應該簡潔明了,讓其他人一看就知道這條commit修改了什麼,禁用一些通用描述,比如:'修改了一個bug','添加了一個功能'

2、品質

關于品質我們從兩個方面進行提升,代碼檢視 和 代碼覆寫率。

(1)代碼檢視:

為了提高代碼檢視的效率,調研了市場上面衆多的代碼檢視工具,好用都需要收費,并且功能比較複雜,比如:upsource。于是開發了一個基礎vscode的code review插件,支援GitLab,實時消息通知。

添加評論

vivo 商城前端架構更新-總覽篇

(2)代碼覆寫率:

商城的業務疊代速度非常快,使得開發單元測試開發的成本非常大,然而我們有時又想看看測試場景的覆寫情況,為了實作這些目标,我們研發了內建測試代碼覆寫率平台。通過這個平台可以清晰的看到每一行代碼被測試執行的情況。保證了開發的品質,并能給測試提供精确的指導建議。

  • 服務端架構
vivo 商城前端架構更新-總覽篇
  • 前台架構
vivo 商城前端架構更新-總覽篇
  • 自動內建 GitLab
vivo 商城前端架構更新-總覽篇
  • 結果展示
vivo 商城前端架構更新-總覽篇
vivo 商城前端架構更新-總覽篇

【小結】

本篇文章介紹了 vivo 商城架構更新的背景,并從系統級、應用級、子產品級、代碼級四個層次,總結了 vivo 商城前端架構更新過程中的種種實踐和探索,希望能給有類似需求的團隊帶來幫助。

我們在前端技術方面的探索并未結束,作為前端架構更新的第一篇,後面會圍繞架構更新帶來一系列的文章,為大家更詳細的講解其中的難點和經驗,敬請期待。

更多内容敬請關注vivo 網際網路技術微信公衆号

vivo 商城前端架構更新-總覽篇

注:轉載文章請先與微信号:Labs2020聯系

分享 vivo 網際網路技術幹貨與沙龍活動,推薦最新行業動态與熱門會議。

繼續閱讀