從業務元件庫看前端工程化

玩弄心裡的鬼發表於2022-03-01

這半年多大部分精力都是在做業務元件庫,而在業務元件庫的開發維護中出我另一個主要做的事就是元件庫(或者說是物料資產)的全套工程化流程。

本文不是一篇教學文章,僅是對近半年一部分工作的流水賬式的總結,也作為自己的一份備忘錄,並且因為是公司內部資產很多地方不能貼原始碼和截圖,如果有對其中內容感興趣的歡迎一起討論。

淺談前端工程化

在我看來,前端工程化就是指把平時工作流程中的一部分繁瑣重複的工作以工具的形式沉澱出來,從而減少開發同學機械化的重複勞動。這裡的工具不限於本地專案指令碼、雲端服務等。例如:我們通過 CRA 去初始化工程專案、通過 Webpack / Vite 對專案進行打包構建、通過雲端服務對前端專案進行上線等等。

從我個人的經驗而言,一切開發中涉及到的簡單的重複機械性勞動,都能或多或少的通過工程化能力得到明顯改善。

前端工程化就和效能優化一樣旁系眾多,而本文的主要切入點在於前端工程中的自動化,利用工程自動化的能力滲透物料體系的初始化->開發->構建->上線全部生命週期,拒絕一切不高效。

從生命週期看工程化全流程

111.png

初始化階段

對於初始化階段,物料側提供了元件/區塊的初始化模版以方便元件/區塊的快速初始化。

開發階段

作為物料體系的展示站點,包含了元件、區塊、解決方案、工具集合等多維度的前端資產,因此採用 MutiRepo 架構,並完全脫離傳統的 npm link 包開發模式。

  • 在元件側 & 物料側,開發指令碼啟動後,實時監聽原始碼的變更並同步到站點的快取目錄。
  • 在站點側,增加 .dev 目錄作為本地開發的快取目錄,在 dev 模式下將元件庫 alias 到 .dev 開發目錄下。並在 Vite 的加持下,持續提升開發體驗。

    • 冷啟動階段,本地開發指令碼預檢測 .dev 目錄合法性,如不合法則全量拷貝 node_modules 下元件原始碼作為臨時快取檔案。
    • 熱更新階段,devServer 監聽 .dev 目錄檔案的變更實時熱更新。

更多本地開發相關可檢視我之前寫的文章:用 Vite 加速你的生產力

構建階段

物料側構建階段只是構建生成 ESM 包和 ES5 的包,這裡主要說下站點側構建時做的事情。

222.png

生成文件

由於元件庫完全是通過 ts + 符合 jsdoc 規範的註釋開發的,因此在文件這一步我們通過指令碼:

  • 掃描全部元件目錄;
  • 通過 typedoc 解析元件型別宣告以及註釋生成文件 AST JSON;

之後站點在執行時解析文件 AST JSON 並生成文件。

生成依賴關係

我們的展示站點又一個功能是展示當前業務元件所依賴的原子元件並生成依賴關係圖,和生成文件的邏輯類似,我們會通過指令碼掃描業務元件目錄分析業務元件的 AST 生成依賴關係 JSON,站點會在執行時動態載入 JSON 展示依賴桑吉圖。

生成元件基本資訊

元件的後設資料已經寸在元件原始碼裡存在了,那在站點側就不需要二次維護了,因此,在生成依賴關係的同時,我們通過 AST 解析了元件內的後設資料,生成了元件基礎資訊 JSON。站點會在執行時動態載入 JSON 展示元件名、元件設計師、元件描述、元件設計稿等資訊。

同步區塊程式碼

之前的文章從業務元件庫看前端物料生態分享過,我們的區塊以原始碼的形式儲存,那麼在構建時實時拉取最新的原始碼就是剛需,因此,我們通過工程化指令碼實現瞭如下功能:

  • 對於區塊:

    • 讀取區塊 Container 目錄;
    • 分析 Container 下區塊變體依賴;
    • 通過工具拉取主 / 子區塊;
    • 站點執行時載入程式碼;
  • 對於解決方案:

    • 讀取解決方案下 material.json 檔案獲取解決方案依賴;
    • 通過工具拉取主 / 子區塊;
    • 站點執行時載入程式碼;

上傳 Demo

我們業務元件庫的 Demo 預覽實現方式不同於其他元件庫,其他元件庫是在開發時通過在 markdown 上編寫 Demo,編譯時將 markdown 解析成 HTML。我們的業務元件庫 Demo 會在站點測以 tsx 原始碼形式儲存,構建時上傳到 CDN 上,執行時載入 CDN 原始碼資源實時預覽。

釋出階段

對於從物料到站點的釋出,我們有嚴格的鏈式釋出流程:

333.png

首先對於元件和區塊,我們通過自動化釋出工具 materials-tools-release 自動化釋出 NPM 和 CDN,減少了程式碼合併、分支檢查、版本檢測、自動化指令碼、釋出等步驟的成本並降低了出錯的風險。

以前的釋出(以元件庫為例):

555.png

  • 這是一種規範,沒啥好說的;
  • 這一步你可能忘了;
  • 這一步你也可能忘了;
  • 這一步你也也可能忘了;
  • 這一步你也也也可能忘了;
  • 這一步可能是你忘的最多的一步,但是可以通過 prepublish 勾子彌補;
  • 這一步可能是你唯一會執行的;
  • 我覺得你可能都不知道這是個啥;

現在的釋出:

777.png

步驟少了,出錯就少了。

最後是站點部署。

工具沉澱

在此過程中,我們沉澱了一套服務於通用元件庫場景的工具集合。

materials-tools-ast

基於 babel 做了二次封裝,可以方便的獲取檔案的匯入匯出等能力。分析元件衍生關係

materials-tools-cli

material-tools-cli 主要提供了兩部分能力:物料拉取核心 + 物料拉取 cli 工具。其中核心服務於 cli 工具和 vscode 外掛主要做了以下這些:

  • 識別物料是否存在,識別當前目錄是否存在同名物料名;
  • 根據物料名從 CDN 拉取物料;
  • 根據拉取下的物料依賴合併依賴並提示;

materials-tools-utils

對工程化指令碼開發過程中常用工具函式做了封裝:

  • file.ts:檔案操作;
  • log.ts:日誌輸出;
  • command.ts:命令列執行操作;

materials-tools-release

自動化釋出工具,減少了程式碼合併、分支堅持、版本檢測、自動化指令碼、釋出等步驟的成本並降低了出錯的風險。

工具集的自動化釋出

工具集採用基於 lerna 的 MonoRepo 架構,但是 lerna 並不滿足我們的一些訴求(例如,我們有很多統一的自定義 npm 勾子的訴求),因此我們在 lerna 的基礎上做了二次封裝:

  • 通過 lerna changed 獲取已更新帶釋出的包版本資訊;
  • 通過 lerna version 更新待發布的包版本;
  • 根據配置檔案排序,例如,a 依賴 b,b 依賴 c,那麼排序後就是 c -> b -> a;
  • 根據排序後的 list 依次執行 按自定義 hooks 執行順序依次執行;
  • 釋出;

相關文章