html
三年前剛開始作 Sketch 生成代碼插件時,定位的就是原型工具,不是可用頁面。我當時認爲直接由設計稿生成可用代碼是走不通的,緣由有兩個:前端
關於第二點這裏詳細說明一下。設計稿中的圖層一般表達的是離人眼先後順序,前面的覆蓋後面。而圖層的分組也只是爲了管理而已,沒有邏輯上的聚合關係。以下圖,背景的紅色圖層與形狀圖層是平級的,沒有展現出包含關係。react
而且在設計中經常會按類型而不是按邏輯歸屬把一些東西放在同一圖層,這樣設計師在修改的時候比較容易批量操做。而在前端的組件化中,組件幾乎必定是按邏輯功能劃分的。而組件的層級表達也是邏輯上的包含關係。這種關係只有一部分能和視覺上的從前到後匹配。以 React 爲例,不少組件層級的表達就不是先後關係。git
所以,想要實現視覺上到邏輯上的完美轉化,只有兩種可能,一是按邏輯的要求約束視覺上的圖層、分組使用。二是靠機器學習之類的方式去智能識別(社區已有開源項目)。github
第一種方式其實技術上可行,可是不人性。兩個方面,一是給設計師形成了巨大的學習成本。這個巨大指的不是設計師學不會,而是指規則有可能由於開發者設計得不完善或者不夠簡便,使得設計師要作不少他本身無心義的額外操做。例如原本設計師一個圖層能夠畫完的元素,在規則的要求下要進行分組分層。二是這些規則極可能忽視了設計師的需求,例如以前所提到的同一圖層管理同一類元素的的問題。我有嘗試使用社區內的一些方案,從設計師的角度來講,那種體驗就像:web
第二種方式當時雖然有想過,可是沒有深刻去探索,緣由也是當時的前端變化太快,我認爲找不到足夠穩定的樣本能去訓練。ajax
有了以上結論後,我想到了雖然直接生成可用頁面不行,可是生成原型仍是有可能的。設計師和前端的溝通成本也是一個須要解決的問題。最多見的就是設計師須要告訴前端某個元素 hover 上去是什麼效果,點擊是什麼效果等。這些東西既然設計師已經畫出來了,那麼能不能把這個表達的方式自動化掉,省去人工溝通的成本。像 Axure 之類的原型工具就有相似的功能。只是這些工具通常都定位給產品作最初的原型設計,缺乏了視覺上的細節,不能徹底取代設計師和前端的溝通。編程
所以我開始作從視覺稿到原型的 Sketch 插件 Blade。這個插件雖然也在必定程度上要求設計師按某種規則來設計,可是這種規則對設計師已是有意義的了,能省去他的口頭描述。後端
在開發完初版後,因爲工做的調動就沒再維護了。後來更是因爲 Sketch 升級後的 api 變化致使不能用了。讓我比較意外的是這兩年間持續不斷地有人開 issue,寫 email 但願我繼續更新。我在 issue 中委婉的表示項目已經再也不維護,你們能夠試試社區的其餘方案。但社區的其餘方案屈指可數,而且方向和定位其實也都不太相同。api
按我所接觸的順序一一介紹一下。
Marketch,也是生成 html 文件,可是專一於標註功能,方便前端同窗取位置和樣式信息。這個定位很是精確,讓前端再也不須要本身裝 Sketch。
從 Sketch 的生態體系看來其實插件能夠分紅兩大類,一類是用來方便設計師的操做的,例如快速生成一些經常使用的元素,如頭像、地圖等。另外一類就是擴展設計以外功能,例如生成標準、原型。對我的開發者來講開發前一類的插件難度比較小,並且收益很明確。然後者相對來講難度和收益就都不樂觀了。在後來我再看到的第二類插件中,幾乎都是團隊進行開發的。例如 Framer 和 Proto.io。
這兩個工具的共同點是都已經脫離了 Sketch 體系,變成了獨立應用。以導入的方式來整合 Sketch/Photoshop 等工具的產出物。但定位也仍然是可交互的原型產品。直到 Launchpad 出現,纔算得上我知道的第一個定位於生成可用頁面的 plugin。
從 Lauchpad 所提供的功能看來,生成頁面功能很是簡單,只有簡單的連接、表單,還不涉及到複雜的交互邏輯。生成的代碼也不能二次開發。可是 Launchpad 作成了一門生意,而且好像運營得還不錯。從跟我進行郵件溝通的設計師中,我也發現了很多想要直接建站的需求。再回過來看我以前認爲這條路不能成功的兩個緣由,反思一下是我想錯了嗎?
第一個緣由是我認爲生成的代碼必需要前端能接受才行。Launchpad 沒有提供二次開發這個能力,彷佛就回避掉了這個問題。但同時也就限制了能力。
第二個緣由是設計語言和編程語言的差別。一樣的,縮小了須要覆蓋的場景,不提供二次開發,也使得對設計師形成的負擔最小化。
這樣看來不是對錯的問題,而是原本定位就不同。我在思考這個問題的時候其實並無區分場景,定位的是從簡單頁面到複雜的單頁應用應該都能適用的狀況。Launchpad 提供了一個新思路,就是縮小場景後能實現一部分。
前面列舉的相關的插件都是從設計的角度出發製做的。而不久前 Airbnb 的 react-sketch 插件則提供了一個新的角度。
它的目標是設計資產的管理。它的能力是將組件這種設計資產從代碼導入到 Sketch,同時也能從 Sketch 導出到代碼。因此便可以說站在了設計師的角度也能夠說是站在了前端的角度。在知乎上有一個評價 react-sketch 的問題。前兩個回答很是的透徹。讀者能夠看一看。回答裏提到的這種工具在真實團隊的適用並不樂觀,我有同感。由於它站在了一個新的角度看問題,那麼必須也得有一個站在同一角度的新角色(設計工程師?)出現才能顯示出它的價值。不然單獨對設計師、對前端,都會感受意義不大。
一樣,react-sketch 也提供了一個新思路,就是以設計資產這個維度來實現代碼和設計元素的統一是有必定價值的。這種統一,其實也就是能互相轉換。
僅僅對 Sketch 插件演變的觀察還不足以引起對文題的新思考。真正的機緣來自於最近一兩年作框架和可視化搭建平臺的經驗。仍然回顧最初我認爲不能成功的兩個緣由,或者說兩個問題,看看通過這兩年,是否發生了新的變化。
順着上一節講到的設計資產的思路,咱們先看第二個設計語言與編程語言的差別問題。以組件的維度來統一設計與代碼,其實本質上是對設計的一種補償。既然設計師須要遵照統一的約定來使用或者修改組件的設計,不能再按照我的的習慣,那就讓這種約定的負擔減到最小,即由插件來自動生成,不須要額外記憶。同時將資源的全自動管理做爲補償提供給設計師。用工具來管理能夠經過團隊的平臺進行共享,若是將來整個團隊須要升級或者統一的修改,就能經過工具來統一完成,再也不須要人肉同步。
再進一步,因爲組件自己是一個邏輯單位。雖然設計師在設計師可能不聽從邏輯單位,可是在接受信息,與他人溝通時仍然是以邏輯單位爲準的。這樣在設計工具上其實能夠作更多方便設計師的功能。例如能「快速選擇全部按鈕、表單、幻燈片等組件的圖層進行批量修改該」等。用技術的方式置換掉設計師們以往人肉提高效率的習慣。
這樣,經過轉換一點點角度,主動爲設計師作一些改變,第二個問題看起來是能夠解決的。
再看第一個問題,產出什麼樣的代碼才能讓前端接受。首先,至少在支付寶內部,前端框架的爭論幾乎已經沒有。你們已經廣泛接受了 React 及其生態體系。然而實際編寫的 React 代碼中,一般原子類型的組件會被包裝成相應的業務組件,有業務邏輯。而最頂層也只會看到相應的幾個業務組件。不像在設計稿中,全部組件都是原子的,頂層可見的。想到這裏時,突然意識到這也再也不是個問題,由於在可視化的搭建平臺中,咱們已經使用的是一種平鋪的,頂層可見的組件結構。只要有合適的應用層框架,在頁面結構比較穩定的狀況下,它是能解決問題的。以下圖中右下角的組件樹,表示的就是相似圖層的平鋪方式。
咱們對平鋪的組件結構,抽象出了數據樹的概念。經過對數據樹的操做,能夠完美的控制整個組件樹,也就是整個應用。而一些上升到應用框架層的高級功能,例如表單的校驗等,也是創建在數據樹上的。有了數據樹,實際上就等於有了真個頁面的邏輯入口。下圖展現着在調試模式下,用戶能夠直接看到的數據樹。
要進行二次開發,生成的代碼不必定要符合手工編碼規範,甚至不必定要可讀啊!
咱們徹底能夠把生成的界面看作是一個黑盒子程序,只要能保證二次開發者能經過 api 進行控制就夠了!(詳見前端服務化——頁面搭建工具的死與生)。而這種方式所能支持的應用複雜度,其實也就是對應的邏輯編寫方式能支持的應用複雜度,再也不和界面自己有關。
至此,兩個問題都已有了解決方案,在可視化自動生成這條路上算是投出了一個新石子。
從設計到代碼的自動化其實能夠看作是可視化平臺的最後一塊補全。截止到今日,以前的可視化搭建平臺已經支持了 56 個系統,在無前端參與的狀況下輸出了1000+的頁面。鏈路完成了從研發到自動化測試再到上線。測試工具效果如圖:
若是成功加上設計鏈路的話,能夠暢想的頁面開發場景是:
搭完這條流水線,就會產出足夠規範的樣本,或許就能做爲足夠好的人工智能原料,實現讓本身下崗的夢想。
一樣,想要參與到這件事的讀者能夠找我來聊聊 ariesate@outlook.com。
最近收到了一些很是高質量的讀者提問,摘取部分整理到這裏(部分回答也從新進行了修改):
問:
從組件層面的沉澱感受沒法在效率上得到更大的突破了。可是對於功能降級到相似CURD頁面的可視化搭建,我都發現有大量潛在的問題,可能歸根結底就是「靈活性」和「高效率」之間的平衡。後臺類系統最大的問題倒不是展現層的標準化,也不是展現層是如何拖拽產生。 最大的問題就是「界面數據層面以及相關邏輯的錯綜複雜的關係」。例如:一個日期組件的展現,多是和前一個分類Select的選擇有關,而這個分類Select的值又多是某個異步接口動態獲取,而這個異步接口又多是其它組件的query拼裝而成。 我不排除,構建一個完整的邏輯數據控制流程,並提供複雜的配置界面能夠解決這一系列的問題。但若是這種方式帶來了超大的配置成本,是否是反而不如直接投入前端人力?傳統手寫代碼的方式,至少開發者面對是本身直接可控的代碼,雖然代碼量會更多,但更直觀也更以維護,而不是一坨黑盒。
答:
在面對真實場景時,確實遇到了「靈活性」與「高效率」權衡的問題。靈活性意味着絕大部分場景倒要考慮到,那一定系統意味要提供各類各樣的能力去解決各類各樣的問題,同時也就意味着會提升學習成本。在前端框架中 Angular1 的設計其實就是一個例子,他所提供了 service、filter 等各類機制雖然能覆蓋足夠的場景,但也讓學習成本陡升。而咱們在搭建這個系統時,提出的方案其實算是繞過了這個問題。咱們的方案是:提供一種「漸進式的、易擴展的、程序可讀」的抽象,目標是讓後端能作前端的事。先解釋下方案。
漸進是指,這個系統對於一些簡單的頁面,讓他確實能把頁面搭一搭,配置一下組件數據就完成了(不少相似系統都是提供一個「配置數據源」的方式來作的)。而對於複雜的頁面,系統又能提供一些其餘方式,例如寫一些簡單的邏輯代碼來處理邏輯。簡而言之,就是隨着用戶對用戶處理的場景進行一個複雜度的分級,升一級就提供一些新的方案給他解決遇到的新的問題。這裏面的關鍵在於,方案應該是儘可能向下兼容的。例如在 http://www.cnblogs.com/sskyy/p/6496287.html 中最後提到的組件數據樹的這個方案,這是最底層的,用戶用邏輯代碼來操做數據源自己能夠解決任何問題,這在簡單的場景中已經足夠用了。可是在一些更復雜的場景、例如「先要查詢一下表單中的每一項是否都已驗證,再決定發不發請求」等場景時,讓用戶一個一個讀組件數據很不方便,那咱們就在這個基礎上對用戶的邏輯代碼中注入一個 form 的對象,這個對象上的方法能幫他快速讀取表單組件數據。但本質上,仍是基於本來的組件數據樹。這樣對用戶來講不管哪一種場景,不管代碼怎麼寫,都是兼容的。學習是一點一點遞進的。
一樣,易擴展指的也是和漸進同樣的場景,只不過描述的對象是開發者。有了上述的這個統一操做數據樹的方案,咱們就能夠不斷的增長新的輔助對象(稱爲util),來處理不一樣的場景。例如發送 ajax 時組件自動呈現 loading 狀態等。有了易擴展的特性,才能是系統以最小的成本去適應不一樣的場景,同時也提供了讓第三方開發者來爲平臺提供能力的可能。
最後的「程序可讀」則是保障系統穩定、應用不失控的關鍵。咱們的系統中一開始就定好了用戶寫的代碼只是對「組件事件」的響應代碼,而且如何操做組件數據樹、如何使用util都是有嚴格規定的。有了這個基礎,咱們就能夠對用戶的邏輯裏的意圖有很是強了解,例如咱們如今能夠經過掃描代碼來在運行前就直接提示,哪一個組件會受到哪些邏輯的影響。組件改了名字,哪些邏輯代碼也要改等等。一樣的,經過 debug 狀態下對 api 包裝等手段,還能作到更強大的調試功能。這也是對「用戶積累必定經驗後,憑什麼放棄靈活性,繼續用你的系統」的回答,由於用戶放棄的靈活性,咱們能夠爲他提供更強的保駕護航。
最後,回到前面的話題,我很是贊成 「靈活」 和 「高效」 是天平的兩端。但其實能夠不去糾結這個事情。以前有一本講交互設計的書給了我很大的啓發,其中提到要把用戶設想成「聰明可是很忙的人」。「聰明」意味着你給他抽象若是比較常見或者簡單,他是可以很快掌握的。忙意味着你要從他的角度思考,當掌握了這個抽象以後,怎麼樣能加速他的工做,或者能提供給他什麼途徑讓他能本身加速本身的工做。只要達成了「讓聰明人很快的幹完了事」,其實就算成功了,用不了你產品的人可能就真的不適合用你的產品。從這個角度去想就會發現,之前糾結的「靈活和高效有矛盾」的緣由是,高效裏面有「聰明人的高效」和「蠢人的高效」。「蠢人的高效」意味着你什麼都要封裝好給他,這會和「靈活」相悖。因此放棄掉「蠢人的高效」,也就不用考慮這個問題了。
問:
從設計稿直接上線可用的代碼,其實最難的是須要設計師來配合,由於這會給他們增長約束,如何來處理這個問題?
答:
相比於具體的技術問題,這個問題其實確才實是最難解決的。我在文章裏其實稍微提到了點,約束是「自動化」的關鍵,是沒法避免的。在 airbnb 的這篇文章 https://airbnb.design/building-a-visual-language/ 中也提到了這個。既然沒法避免,那最關鍵的就是這種約束如何爲設計師也帶來好處。咱們的文章裏提到了對設計師的約束其實只有一個:「要以某種指定形式來規範圖層,例如命名,這樣才能將圖層和要生成的組件關聯起來」。咱們如今已經啓動了這個項目,設計師是直接參與進來的,和他們交流中總結出來的對他們有價值的幾個關鍵點:
1. 流程上受益。若是平臺能保證只要設計師按規範出圖,那麼最後上線的效果就必定和設計效果同樣的話,那設計師就不用在最後上線前複查真實頁面了。
2. 對設計資產的管理。「組件」這個概念實際上是前端和設計師通用的,前端一般是以代碼庫的方式來管理組件,而設計師目前缺少相應的工具或者規範。若是設計稿裏能經過程序讀出設計師使用了什麼組件,如何使用的,那麼咱們就有機會爲設計師去也去作一些設計資產管理的工具。例如設計的組件庫管理工具,當總體設計風格升級時,能自動告訴設計師哪些頁面上相應的組件也要升級,若是設計的搞好,甚至能夠自動升級視覺稿。
3. 知足設計師的產品心。若是這個系統穩定性、易用性好到必定程度的話,設計師其實也有機會直接做出能夠用的產品。這自己對設計師也是很大的誘惑。
除了上述這些具體的點,其實最重要的是要讓設計師直接參與進來編程系統的設計者,這樣天然就破除了職能之間自己存在的隔閡。
問:
爲何會想到作這樣的東西,另外何時開源?
答:
這幾年不管是作框架仍是工具,我一直是朝着提高 web 應用的研發效率這個方向前進的。在見證了前端新的基礎技術(瀏覽器環境、語言)和框架的不斷變革後我意識一點:
「對我的來講其實不存在研發效能的問題」。由於一我的能處理的問題有限,一樣要用到的東西也是有限的,工具很差用換一個就是。編程理念不對學點新東西就是。可是對於大公司來講,問題就發生了質變。首先,資源的不對等會產生「短板效應」,例如前端人不夠,不可能由於這個拖累整個產品的研發吧?因此有的部門加班,有的閒。再例如職能劃分的過細、流程太長致使中間的溝通成本急劇增長,也會極大拖累總體效能。
以前我一直在框架、工具中探索,「找到某種正確的抽象」、「實踐某種編程理念」,這其實都是針對我的的方案。而業界所看到針對團隊的方案廣泛也就是創建「組件庫」、創建各類「發佈平臺」、「監控平臺」等等。這些都是從提高「某個工具的複用能力」去解決的。而比較少看到專門針對流程的方案。見證了那麼多框架、工具的興起和死亡以後。我認爲從「流程自動化」的方向去解決問題才更能幫助大團隊和大公司解決問題。所以這篇文章裏的其實最重要的並非具體的實現技術,而是 「設計-研發-測試-部署」 的全流程串聯,而且在流程上實現自動化。關於這一點我會再單獨寫一篇文章,咱們在 web 應用研發這個方向應該已經慢慢進入新的階段。也歡迎有興趣的讀者來信和我交流。我會持續更新到這篇文章中。
平臺會逐步以工具的形式開源,若是但願參與也能夠先聯繫我。