做者簡介: 李浩成(Kayo),騰訊廣州研發部 UI 工程師。git
通過長時間的打磨迭代,QMUI Web 做爲騰訊廣研 QMUI 團隊的一個開源項目,正式發佈到 Tencent Github。QMUI Web 是一個 Web UI 的解決方案,從零開始,由編碼規範,到組件和工具方法的製做,再到工做流的整合,不斷在迭代,也不斷在優化,走過了很多的路。趁着發佈的機會,咱們正好回顧這一路的探索過程,分享其中的點滴,也但願能借此讓你們更瞭解 QMUI Web。github
2014 年中,QMUI 團隊支持的主要項目是 QQ 郵箱,Web 端的郵箱是個龐大的項目,但其並無統一的 UI 基礎庫,多年的高速迭代使得項目的 UI 代碼變得混亂,各個模塊之間各自開發,除了在代碼層面表現出混亂和不可控以外,表現層面也並無很好地統一塊兒來。所以,項目急需一套統一的團隊編碼規範以及一個 UI 基礎庫。 剛好,這個時候 Sass 等 CSS 預處理器已經發展成熟,自動化工做流的工做模式也日趨完善,所以,咱們決定基於這些技術製做一套通用於不一樣項目的 Web UI 框架。框架的場景定位很明確:須要控制總體樣式,而且能夠適應頻繁迭代打磨的大型項目。因此,這套即將誕生的 Web UI 框架的特性也很明確:須要方便地控制項目的總體樣式,應對頻繁的界面變更,並保持項目質量穩健。 此後通過三年的發展,QMUI Web 最終發展爲包含編碼規範、樣式工具方法與樣式管理、內置工做流,配套的 GUI 桌面 App,以及擁有完整文檔的解決方案。gulp
在製做框架的過程當中,咱們把框架須要的特性進行整理和思考,造成了一套對於該框架的設計理念,在這些設計理念之中,最核心的關鍵爲通用於多個項目,高效迭代和保持代碼穩健,框架的設計也遵循這三個核心點,體如今框架上,具體就是:瀏覽器
而具體到代碼層面,則能夠概括爲兩個方面:框架
做爲一個 Web UI 框架,編寫代碼主要是 CSS 與 HTML,而提到 CSS 與 HTML 的編寫,首先要處理的是 Class-name 的命名,在過往的開發中,Class-name 的命名並無固定的規範,開發人員各自進行開發,一個項目通過長時間的迭代後,常常會遇到如命名衝突,命名混亂等問題,這使得項目的迭代變得笨重,也很差維護。所以,咱們須要一套具備以下特色的 Class-name 命名規範:工具
所以,最終 QMUI Web 制定了一套以命名空間爲核心的命名方式,這個命名方式主要由「命名空間」,「業務與組件的拆分」,「精確表達 View」三個部分構成。測試
一個 QMUI Web Class-name 應該包含一個命名空間,也是 Class-name 的開頭,若是是業務,則以業務內容爲命名空間,若是是公共組件,則全局使用項目的名字(或縮寫)爲命名空間。如一個名爲 Demo 的項目,項目縮寫能夠是 dm,那麼該項目下的項目組件和公共類能夠這樣命名: dm_btn
(按鈕)、dm_icon
(圖標)、dm_ipt
(輸入框)、dm_toolbar
(工具欄)。 邏輯模塊命名以具體業務做爲前綴,如簡歷(resume)功能裏面的非公共組件部分,以 resume_ 做爲前綴(resume_mod
、resume_text
、resume_list
),我的信息(profile)頁面的非公共組件部分,則能夠以 profile_ 做爲前綴(profile_statge
、profile_stage_title
)。 命名空間做爲一種基礎的隔離,把組件與業務,以及不一樣的業務之間的 Class-name 命名隔離開來,避免衝突,然後父子元素之間逐級展開編寫,保證了項目內多人協助不易衝突,同時命名帶有語義,也方便理解和閱讀。字體
接着,QMUI Web 中把項目的代碼劃分爲通用組件(跨項目的組件),項目全局組件(適用於某個具體項目),業務組件(適用於某個業務),以及業務邏輯代碼,這樣區分出4個顆粒度可使得代碼更容易被組織和複用,一個模塊隨着設計元素迭代,也能夠在這4個顆粒度之間進行迭代,從而使得模塊在迭代時會更加穩健。而 QMUI Web 框架中的組件應該只收納通用組件,即跨項目組件。優化
精準表達 View 是指在命名 DOM 節點時要明確這是一個怎樣的 View,這裏的 View 指的就是 UI 層面上這個元素表示的含義,常見的場景是,一個命名爲 resume_head 的元素,在經歷屢次迭代後實際在代碼中卻充當了頁腳,這樣的命名在多人協做時很容易給後面的開發者形成困擾,而精準表達 View 則要求咱們明確一個 UI 元素的含義,並在命名時準確地表達。編碼
前面的「Class-name 命名規範」主要是在規範層面上去實踐 QMUI Web 的核心理念,而接着更多地就是在代碼層面上去實踐了,主要包括三點:
前文提到,QMUI Web 把組件劃分爲通用組件,項目全局組件,業務組件三種組件,而 QMUI Web 框架收納的則是通用組件,也是跨項目的組件,但每一個項目的 UI 表現並沒有關聯,如何處理跨項目組件就成爲了一個問題。爲此,QMUI 在處理組件時採起的是「半封裝」的處理方式,QMUI 框架封裝的是代碼,所謂半封裝,即封裝那些與項目具體 UI 表現沒有必然聯繫的代碼。例如按鈕組件,QMUI Web 中只封裝了文字居中對齊,鼠標手型,瀏覽器樣式重置,低版本 IE 兼容性處理等代碼,而經常使用的樣式如邊框、背景、字體表現等,都抽取成變量控制,這些組件的變量最終都聚集到一個配置表 Sass 文件中,配合全局的顏色變量、字體變量等變量,就能夠作到跨項目抽取組件,每一個新項目只須要關注具體 UI 表現而無需再處理各類常見的 UI 問題,同時方便地經過調整這些變量的值而快速修改整個項目的樣式。
在處理組件時,繼承的方式是指一個組件類承擔複雜的功能,而組合的方式則是把組件類拆分紅一個基類,以及多個子類,每一個子類承擔的功能不重複,對於咱們的主場景——頻繁迭代,保持穩健,顯然組合會更加適合,這種方式避免了在頻繁的迭代中須要不斷修改組件類,每次迭代只須要修改對應的子類便可。
對於組件的抽取,時常要考慮顆粒度的劃分,顆粒度自己就是一個比較開放性的問題,在這裏與你們分享一些沉澱的經驗:
以上即是 QMUI Web 具體的設計理念,經過命名規範、基礎樣式配置與半封裝組件來保證多人協做時的高效率與可維護性,也使得一個 UI 框架能爲不一樣的項目服務。
做爲一個框架,QMUI Web 主要提供了四種能力來提高 UI 開發的效率與質量,對應前文提到的框架設計理念,QMUI Web 提供的這些功能都是爲了幫助開發者方便地控制項目總體樣式,應對頻繁變更,同時保持代碼穩健。
前文提到,框架中會有一份配置表,是各類 Sass 的變量,這些變量控制了一個網頁基本的字體樣式,連接顏色,通用組件的樣式配置等基礎樣式,在建立一個新項目時,應該先根據設計稿配置好這些信息,當這些信息配置完成,那麼一個項目的基本樣式就能夠快速實現了。例以下圖中這些配置屬於 QMUI 通用配置,經過修改這些配置則能夠快速修改項目的字體策略、正文字體大小,連接顏色等 UI 經常使用的 CSS 屬性。
QMUI 中包含一個基於 gulp 的內置工做流,用於快速解決大量重複勞動力的工做,從而提高效率。QMUI 的 gulp 中預先實現了監控 Sass 文件並自動編譯和優化,雪碧圖處理,模板 include 能力(能夠傳參和使用條件判斷),瀏覽器自動刷新,圖片壓縮,文件清理,文件合併以及自動變動等能力。
QMUI 中提供了大量基於 Sass 的 CSS 預處理的方法,包括 CSS Reset,一些常見的 CSS 類(例如清除浮動),計算長度值的簡便方法(例如獲取 padding 在某個方向的值,計算兩個長度值的中間值),快速實現一些樣式效果的工具方法(例如實現 border 三角形,適應多倍屏幕的 1px 邊框等),這些都是用於提升樣式開發的效率和質量。
擴展組件並非由 QMUI Web 的主源碼提供,而是由 Demo 提供,一般是由於這類組件結構較複雜,所以業務性沒法很好地剝離,從而不能抽取成公共組件,所以這類組件就放在一個 Demo 頁,以參考組件的形式幫助開發。
咱們提供了一個用於管理 QMUI Web 項目的桌面 App,在代碼層面它獨立於 QMUI Web 的源碼。它經過 GUI 界面處理 QMUI Web 的服務開啓/關閉,並提供了編譯提醒,出錯提醒,進程關閉提醒等額外的功能,在處理多項目,多分支時能更方便地進行開發。
在經歷較長時間的迭代後,QMUI Web 也逐漸完善起來,此時咱們也開始將 QMUI Web 進行開源。開源意味着 QMUI Web 會進入更加全面的環境中去打磨,在框架的非主體內容如代碼規範、註釋、文檔上面也須要更費心思,考慮的點也須要更加周全。這對團隊來講無疑是個很好的機會,能夠有更多的渠道審視框架,吸取建議,持續進行優化。
在加入開源的大環境後,咱們從 Github、社區論壇中都獲取了很多建議,除了 bug 的反饋外,也指出了一些待完善的地方和提出一些優化的解決方案,從而使得 QMUI Web 注入了更多活力,所以咱們也逐步進行了如「自動化測試用例」、「gulp 結構化」,「引入 SassDoc 自動化生成文檔」,「編譯 Sass 時引入增長更新」等優化,其中很多優化點咱們也在項目的 Github Wiki 中進行了詳細的分享,有興趣的用戶能夠自行瀏覽。
至此,QMUI Web 發展爲如今這套完整的方案,也終於開源到 Github Tencent 與你們分享,咱們指望經過開源與你們進行更多的交流,也使得 QMUI Web 進入更加全面的環境中去打磨,造成對代碼規範、註釋、項目文檔感謝公司與部門給咱們提供了一個平臺,能夠在大型項目中經歷迭代和沉澱。開源只是一個開始,咱們後續仍會不斷進行探索和優化,期待更好的 QMUI Web。
關注 QMUI Web, 來 Github 給咱們 star 吧!