前端框架的圖形化探索方向一個嘗試, Respo Composer
之前參加活動的時候想起一個問題, 怎麼樣才能讓設計做出的稿子能更多被前端複用. 特別是在程式碼方面. 應該說設計工具已經包含了前端介面的大量資訊, 編寫程式碼包含相當多的重複勞動的. 但這是一個問題.
包括 React Vue 這些年逐步演進, 最初 React 的 Virtual DOM 能夠在 Virtual DOM 的基礎上通過熱替換大幅提升前端的開發效率, 以及 ClojureScript 工具鏈進一步優化了熱替換的使用體驗, 給開發的效率帶來提升. 現在, React Vue 本身講更多的精力投入到效能的優化還有邏輯複用的問題上.
我想問的問題是, 介面和互動的開發效率怎樣進一步提升?
提出這個問題同時也意味著另外的問題會暫時被擱置, 比如說框架的程式碼執行效率和最終體積, 比如說程式碼的複用和維護性. 對於大公司來說可以用錢弱化的一些問題. 而我的問題側重點是, 如果介面和互動的規模不是很大, 維護週期也不長的話, 為了提升開發效率, 我們能作出怎樣的改進?
Respo Composer 方案介紹
題圖當中是我在春節前後進行的嘗試, 開發了一個 Respo Composer App, 用來圖形化建構 Todolist 的介面. 這個工具的功能非常侷限, 但是完整展示了我最初的意圖:
- 有個 DOM 樹的編輯工具, 可以設定頁面的佈局和節點的樣式.
- 工具將 DOM 節點元件化做編輯, 並且提供一些內建的元件, 方便快速編寫.
- 有基本的插入 Mock 資料的方式, 介面能夠根據 Mock 資料通過邏輯節點渲染不同的樣式.
- 節點當中支援 Action, 渲染函式能夠收集 Action, 可以外部響應 Action 修改資料, 資料再傳入函式渲染新版的介面.
基礎的介面基於 DOM 樹的形態. 對於前端來說不陌生, 對於設計師來說可能不夠優化. 最左邊的是元件列表,實際上應該是說模板. 中間是樹, 右邊是選中節點的屬性(型別, 佈局, 樣式..等等).

每個節點實際上對應著一個數據結構. 這些基本上都應該說是模板引擎的範疇. 同時, 也提供了預覽區域, 編輯元件的同時, 能看到渲染的效果, 比如上面的 task 渲染出來之後, 是一個簡化的任務, 包含卡片, 文字, 圖示這些元素:

關於具體的操作, 我簡單錄製了過相關的視訊, 因為沒有裁剪所以內容略長,
Composer Todolist 開發版本 Demo (12分鐘) v-wb.youku.com
這個介面修改之後會儲存一份 EDN 格式的一份檔案, 相當於 Clojure 的 JSON, 這份資料可以被用在後續的程式碼操作當中,
https://github.com/Erigeron/composer-todolist/blob/master/src/composed/composer.edn github.com關於操作, 我也錄製過視訊, 大致介紹了步驟,
Composr Todolist 互動部分初步演示(12分鐘) v-wb.youku.com
更連貫一些的一個基礎的 Todolist 新增任務的功能, 通過 Composer 可以實現, 完整的操作有個比較長的錄屏做了演示:
Respo Composer 使用演示 (31分鐘) v.youku.com
前面的操作, 加上 Respo 生態提供的工具鏈, 最終可以生成一個 Todolist 出來. 雖然功能上是有殘缺的, 不過我覺得足夠表明這個方案的可行性了.
Todolist repo.erigeron.orgRespo Composer 實現原理
上面的 Demo 託管在 GitHub 上, 有興趣的話可以嘗試, 私有的一些工具比較多, 不容易上手, 不過按照 README 執行應該不難把 Composer 介面開啟,
Erigeron/composer-todolist github.com
基礎工具的 Respo 還有 Composer 的程式碼, 可以在 Respo 的 GitHub 主頁 找到. 目前 Composer 支援的節點有限, 首先每一個節點都用這樣資料結構表示出來:
{ :id "r", :type :button, :layout nil :props {"text" "Archive", "action" "~:archive"} :attrs {} :presets #{} :style {} :children {} }
這些屬性跟 DOM 自帶的屬性有不小的差異,
- type - 節點的型別, 包含下面一些元件.
- props - 節點支援的屬性, 每個型別的節點有各自的屬性:
TypepropsAction ---- boxaction, data spacewidth, height dividerkind, color textvalue somevalue, kind buttontextaction, data linktext, hrefaction, data iconnameaction, data templatename, data listvalue inputvalue, textareaaction, data slotdom inspecttitle popupvisible casevalue(?) elementname
- attrs - DOM 屬性
- presets - 一些內建樣式, 目前主要是 flexbox 屬性還有字型樣式,
- style - CSS 樣式
- children - 子節點.
熟悉前端開發的應該不難聯想到這樣的設計, 對應的是模板引擎和樣式, 比如前面的圖片當中 task 就是一個模板, 定義了 DOM 結構, 定義了樣式. 程式碼當中提到的 action 和 data 類似於事件繫結, 當然這裡是寫不了業務邏輯的, 只能用來定義 Action 和引數.
內建的元件主要是佈局和介面元件, 除此之外, 還有在比較重要的判斷邏輯,

這些判斷邏輯基本上對應的是模板引擎的功能:
- Some - 對應 if, 判斷資料是否存在, 或者陣列是否為空.
- Template - 進行模板的巢狀.
- List - 生成陣列.
- Slot - 直接插入 Virtual DOM.
至於屬性部分, 主要是 props 和 style. props 當中由於要進行資料的傳遞, 使用了 Clojure 配合表示式用. 目前的版本僅僅是試驗性的, @
表示從作用域當中取值, ~
表示解析字串的值.. 很奇怪的寫法, 後續要調整.

Mock 資料部分做得比較簡單, 只是提供了切換多個版本的資料的入口. 提供了資料之後, 就可以模擬不同的狀態, 快速除錯介面. 這一點在真實的開發當中, 為了調整介面而操作介面狀態來模擬資料, 應該是有幫助的.
有了模板引擎, 有了 Mock 資料, 再進行排列組合, 就能夠預覽所有的介面的樣子了.

延伸的思考
大概 iOS 開發, 或者 Flash 的開發, 以及 3D 遊戲的開發當中, 相關的開發工具圖形化已經用不少了. 我沒有相關經驗不好評論, 但是對於前端來說, 這一步應該也值得去做試驗.
目前 Composer 提供的主要是演示的目的, 後續能不能變成實用, 還需要再思考和改進. 而且適用的介面也僅限於 Store Action View 這樣簡單的分層和極為簡單的互動. 只是說理論上有著擴充套件的可能性. 同時在元件化, 在複雜互動放方面, 沒有清晰的方案.
但是從試用當中印證了一些想法.
我認為前端開發是可以再進行細化和分工的. 製作介面和編寫邏輯, 可以分為兩個流程, 甚至介面這個流程, 就應該跟介面設計合併在一起. 比如說介面部分提供好上面介面當中的元件形態, 然後再由開發人員介入, 優化元件結構, 增加 Action, 編寫配套的邏輯, 編譯程式碼.
其次, 以往那麼多前端框架, 試驗了模板引擎的多種語法, 試驗了 JSX 的語法. 誠然 JSX 有著強大的表達能力, 但是出於開發效率的考慮, 我們還是要有一個圖形化的工具, 才能在開發速度上有進一步的提升. 而且圖形介面可以延伸到 Pad 上進行多指觸控的操作, 比起敲鍵盤是要快的.
這樣一套方案我是基於 ClojureScript Respo 試驗的. 道理講 React 或者 Vue 當中依然可以實現一遍, EDN 可是也是通用的. 我覺得基於這樣的方案可以繞過很多文字語法的限制, 並且做一些之前可能並不方便做的優化. 值得繼續嘗試.