天天看點

前端元件化開發思考

作者:衆安科技ZATech

筆者介紹

王随鵬,目前任職于衆安金融事業部前端開發工程師,主要參與衆安優保小程式、新媒體營運、GMP 營銷流程等相關業務的開發。

文章目錄

一、前言

二、為什麼實施前端元件化

三、什麼是元件化

四、元件化的演變

五、元件化的使用背景

六、元件化的職能劃分

七、元件化在現代項目中的實作

八、元件化的價值

九、總結

一、前言

元件化對于任何一個業務場景複雜的前端應用以及經過多次疊代之後的産品來說都是必經之路。元件化要做的不僅僅是表面上看到的子產品拆分解耦,其背後還有很多工作來支撐元件化的進行,例如結合業務特性的子產品拆分政策、子產品間的互動方式和建構系統等等 。

元件化并不是前端獨有的,當今前端生态裡面,React、Angular和Vue三分天下。雖然這三個架構的定位各有不同,但是它們有一個核心的共同點,那就是提供了元件化的能力。

二、為什麼要實施前端元件化

1.從前端發展過程思考

1) 随着技術的發展,開發的複雜度也越來越高,傳統開發模式總是存在着開發效率低,維護成本高等弊端。

2) 傳統開發方式效率低以及維護成本高的主要原因在于很多時候是将一個系統做成了整塊應用,而且往往随着業務的增長或者變更,系統的複雜度會呈現指數級的增長,經常出現的情況就是一個小小的改動或者一個小功能的增加可能會引起整體邏輯的修改,造成牽一發而動全身。

3) 我們希望一個大且複雜的場景能夠被分解成幾個小的部分,這些小的部分彼此之間互不幹擾,可以單獨開發,單獨維護,而且他們之間可以随意的進行組合。

2.從效率的角度思考

1) 疊代速度慢,公共代碼互相耦合,需要全量回歸;

2) 多人協作是極其困難的一件事;

3) 代碼沖突多,每次送出代碼可能需要解決沖突;

4) 版本風險高,修改會影響很多需求之外的功能。

3.從技術的角度思考

1) 代碼整體結構混亂、缺少層次;

2) 優秀的代碼應該是高内聚,低耦合;

3) 龜速編譯,開發體驗極差;

4) 無法很好地支援A/BTest;

5) 每次發版在QA回歸上耗時很久。

三、什麼是元件化

前端的元件化,其實是對項目進行自上而下的拆分,把通用的、可複用的功能以黑盒的形式封裝到一個組間中,然後暴露一些開箱即用的函數和屬性配置供外部元件調用,實作與業務邏輯的解耦,來達到代碼間的高内聚、低耦合,實作功能子產品的可配置、可複用、可擴充。

前端元件化開發思考

四、元件化的演變

1.函數化程式設計思想

1) 以函數(方法)來分離行為;

2) 每個函數僅在做一件事情。

如下圖:

前端元件化開發思考

2.子產品化程式設計思想

1) 以子產品(js檔案)來分離行為;

2) 每個子產品負責一類事情。

3.元件化程式設計思想

1) 以元件來分離行為;

2) 每個元件擁有獨立的結構、視圖和行為,代表一個完整的個體。

如下圖:

前端元件化開發思考

五、元件化的使用背景

1.業務的疊代和堆積

1) 單個檔案有上千行代碼,可讀性非常差,維護不友善;

2) 有大量重複的代碼,相同或者類似的功能實作了很多遍 ;

3) 新功能的開發成本巨大。

2.場景的多樣化

1) 不同的項目,類似的場景;

2) 相同的項目,越來越多的相同場景。

六、元件化的職能劃分

元件最大的不穩定性來自于展現層,一個元件隻做一件事,基于功能做好職責劃分:

前端元件化開發思考

1.容器型元件

一個容器性質的元件,一般當作一個業務子子產品的入口,比如一個路由指向的元件;容器型元件需要知道如何擷取子元件所需資料,以及這些資料的處理邏輯,并把資料和邏輯通過props提供給子元件使用。容器型元件一般是有狀态元件,因為它們需要管理頁面所需資料。

前端元件化開發思考

2.展示型元件

主要表現為元件是怎樣渲染的,就像一個簡單的模版渲染:

1) 隻通過props接受資料和回調函數,不充當資料源;

2) 通常用props.children(react) 或者slot(vue)來包含其他元件;

3) 可以有狀态,在其生命周期内可以操縱并改變其内部狀态,職責單一,将不屬于自己的行為通過回調傳遞出去,讓父級去處理。

前端元件化開發思考

3.業務元件

通常是根據最小業務狀态抽象而出,業務元件也具有一定的複用性,但大多數是一次性元件

前端元件化開發思考

4.通用元件

可以在一個或多個項目内通用的元件

前端元件化開發思考

七、元件化在現代項目中的實作

我們把一個項目的生命周期分為如下幾個階段:

前端元件化開發思考

元件化開發方案主要關注的是在疊代開發階段的對團隊效率的提升。

1.單一職責

1) 單一職責強調一個元件具備一項“能力”。

2) 單一職責可以保證元件是最細的粒度,且有利于複用。但太細的粒度有時又會造成元件的碎片化。是以單一職責元件要建立在可複用的基礎上,對于不可複用的單一職責元件,我們僅僅作為獨立元件的内部元件即可。

3) 單一職責同時也具備簡化元件的能力,遵守該原則在一定程度上能夠使代碼足夠簡單,意味着易讀、易維護。

2.封裝

1) 良好的元件封裝應該隐藏内部細節和實作意義,并通過props來控制行為和輸出。同時還要具備減少通路全局變量能力,因為通路全局變量會打破封裝,創造了不可預測的行為。

2) 封裝能夠将不用邏輯代碼分離,能夠幫助開發中快速定位問題。

3.可配置性

1) 一個元件,要明确它的輸入和輸出分别是什麼。

2) 元件除了要展示預設的内容,還需要做一些動态的适配,比如:一個元件内有一段文本,一個圖檔和一個按鈕;字型的顔色、圖檔的規則、按鈕的位置、按鈕點選事件的處理邏輯等,都是可以做成可配置的。

4.組合

1) 單一責任原則描述了如何将需求拆分為元件,封裝描述了如何組織這些元件,組合描述了如何将整個系統粘合在一起;

2) 具有多個功能的元件,應該轉換為多個單一職責的小元件,這些小的元件又可以組合成為一個職責更大、功能單一的元件。

5.複用

1) 通常來說我們進行元件設計的目的有兩種:

a. 抽取公共功能部分,友善複用;

b. 複雜設計/功能分解,便于代碼管理和提高代碼閱讀性。

2) 提高元件的複用性,使得一處代碼的封裝能夠在各個不同的地方使用。複用性能夠使代碼的修改/編輯更加友善,隻需要修改元件代碼,各個引用的地方會同步進行修改和更新。

6.可測試

1) 現在前端開發過程中一直都在強調單元測試,一個完成的項目單測是不可缺少的一部分,單測可以保證代碼正确性、一部分依賴的正确性、以及減少調試時間等。

2) 單元測試的目的不是為了減少代碼覆寫率,而是為了減少bug出現的機率,以及防止bug回歸。

八、元件化的價值

1.技術價值

1) 降低系統的耦合度:在保持接口不變的情況下,我們可以把目前元件替換成不同的元件實作業務功能更新。

2) 提高可維護性:由于每個元件的職責單一,在系統中更容易被複用,是以對某個職責的修改隻需要修改一處,就可獲得系統的整體更新。

3) 降低上手難度:新成員隻需要了解接口和職責即可開發元件代碼。

4) 利于調試:由于整個系統是通過元件組合起來的,在出現問題的時候,可以用排除法直接移除元件,或者根據報錯的元件快速定位問題。

5) 提升團隊協同開發效率:通過對元件的拆分粒度控制來合理配置設定團隊成員任務,讓團隊中每個人都能發揮所長,維護對應的元件,最大化團隊開發效率。

2.業務價值

1) 元件的複用和移植,減少開發人力;

2) 便于組合不同的場景和業務;

3) 促進業務安全和快速疊代。

九、總結

元件化并非一蹴而就,而是一個持續的過程。在沉澱業務元件的同時還需考慮元件包的大小,不能因為元件包的體積大而導緻頁面加載過慢,以及元件釋出前的測試等。但可以通過一些方法和規範去解決挑戰,讓元件化設計更好的服務于系統。是以,了解元件化可以幫助開發者更好地使用架構進行工作内容的拆分和維護,才能在實際開發中結合具體的業務場景,設計出合理的元件,實作真正的前端元件化。

繼續閱讀