2C 設(shè)計稿轉(zhuǎn)代碼是怎么實現(xiàn)的?自己做一個可行嗎?
D2C 是指 Design to Code,設(shè)計稿轉(zhuǎn)代碼,輸入是 sketch、figma、PSD 等設(shè)計稿,輸出是 vue、react、小程序等各平臺的前端代碼。
對前端工程師來說,如果能直接把設(shè)計稿轉(zhuǎn)成可用的代碼,是非常有意義的,那這樣一個工具是怎么實現(xiàn)的呢?
vue、react 等各平臺的前端代碼都可以通過一種樹形數(shù)據(jù)結(jié)構(gòu)來描述,比如 vdom。當然這里不是用 vdom,而是需要設(shè)計一種中間數(shù)據(jù)結(jié)構(gòu),叫做 DSL(領(lǐng)域特定語言),專門用于描述界面結(jié)構(gòu)的一種語言。
也就是說我們要把從設(shè)計稿中提取出的信息轉(zhuǎn)成中間的 DSL,然后再通過 DSL 打印成各種代碼。
那怎么從設(shè)計稿提取信息呢?
其實 figma、sketch 等的設(shè)計稿都是矢量的,也就是由各種圖形組合而成,它們設(shè)計稿的存儲也是 json 格式的:
下面就是一個 figma 設(shè)計稿的存儲結(jié)構(gòu):
可以看到是一個節(jié)點的樹,通過 children 關(guān)聯(lián)子節(jié)點,每個節(jié)點有 type 和位置信息。
比如 TEXT 節(jié)點有 absoluteBoundingBox 的位置信息 x、y、width、height,有 fontSize、fontFamily 等文本樣式信息:
比如 RECTANGLE 節(jié)點有 fills 信息表示背景,如果是 image 類型的 fill 會有圖片的 hash 來關(guān)聯(lián)到圖片。
這些所有的節(jié)點都是可以對應到 DOM 節(jié)點的,樣式也可以對應到 CSS。
所以,只要把設(shè)計稿的樹形存儲結(jié)構(gòu),轉(zhuǎn)為描述頁面的 DSL,然后打印成各平臺的代碼就可以了:
看起來好像挺簡單的?
這只是理想的情況下,實際上有很多問題沒處理。
比如布局,按照從設(shè)計稿提取的信息來布局,只能做成絕對布局,這樣的代碼是不好維護的,我們要轉(zhuǎn)成 flex 布局。
比如結(jié)構(gòu),現(xiàn)在是直接把設(shè)計稿結(jié)構(gòu)轉(zhuǎn)換成了 DOM 結(jié)構(gòu),實際上設(shè)計稿的層次結(jié)構(gòu)不一定合理,需要轉(zhuǎn)成適合網(wǎng)頁的結(jié)構(gòu)。
有了絕對的位置,轉(zhuǎn)換成 flex 布局可以使用投影法:
比如左邊這樣的布局,水平投影到右側(cè),可以分成兩組,上面一組,下面一組,投影的間距可以設(shè)置為 margin-top、margin-bottom:
每一組分別豎直投影,可以算出每個元素的間距,分別設(shè)置為 margin-left、margin-right:
然后元素內(nèi)部也這樣做投影,分別設(shè)置 padding-left、padding-top 等。
這樣就可以把絕對定位的布局轉(zhuǎn)換為 flex + margin + padding 的布局,代碼可維護性會更高。
再就是分組,這個可以手工搞,提取完設(shè)計稿信息之后做一個編輯功能,可以自己調(diào)整分組:
但這要求使用者要了解前端需要什么樣的結(jié)構(gòu),還是有一些要求的,能不能自動調(diào)整分組呢?
這就需要 AI 算法的介入了,這里需要聚類算法。
此外,生成的前端代碼是要有 className 的,這個 className 起的是否語義化也是可維護性的一個重要的方面。
這個問題也有兩種解決方式,一個是手工標注,一個是 AI 算法生成。
手工標注就是使用者在設(shè)計稿中添加一個名字的標識,比如這樣:
再就是通過算法來識別不同類型的組件,加上語義化的名字了。
還有一個問題就是現(xiàn)在只能轉(zhuǎn)換成 text、image 這種基礎(chǔ)組件,很多時候我們是有組件庫的,比如可能會用 antd。
能不能直接把設(shè)計稿轉(zhuǎn)換成基于組件庫的代碼呢?
可以的,其實這就是個對應關(guān)系的問題,如果我們能把不同的節(jié)點識別為不同的組件,從中提取不同的參數(shù)信息,之后不就可以生成對應的組件代碼了么?
這種組件標注同樣也有人工和 AI 自動標注兩種方式:
通過 AI 來識別出不同的組件,然后打上自動打上標記,或者通過編輯器來人工打標記。
這個編輯器可以是通過 sketch 插件、figma 插件的形式在設(shè)計軟件里做,也可以是一個獨立的 web 平臺來做。
這個編輯器完全可以對接低代碼編輯器,也就是可以拖拽一些組件進來,再生成 DSL,然后打印成代碼。
不過設(shè)計稿轉(zhuǎn)成的 DSL 不是全部由組件構(gòu)成,和低代碼的 DSL 還是有區(qū)別的。
這就是設(shè)計稿轉(zhuǎn)代碼的實現(xiàn)原理了,理想情況下,直接把設(shè)計稿結(jié)構(gòu)轉(zhuǎn)成 DSL 的結(jié)構(gòu),生成 flex 布局和對應的組件信息,然后打印成代碼就可以。
但很多情況下,設(shè)計稿多少存在一些問題,需要人工編輯或者 AI 自動處理的方式來調(diào)整分組、className、標注組件等,很難做的通用。
而且我們是直接從結(jié)構(gòu)化存儲的矢量設(shè)計稿開始處理的,如果是從圖片開始,那需要通過 AI 的方式先把其中的信息提取出來,再轉(zhuǎn)成 DSL,這樣多了一步用到 AI 的地方。
D2C 的原理還是挺清晰的,但是能夠做的多智能,上限取決于 AI 算法,當然,下限可以通過做一個編輯器來人工干預來保證。
原理理清了,我們再來過一遍現(xiàn)有的各種 D2C 的產(chǎn)品:
Picasso
先看一下 58 的 picasso,他提供了一個 sketch 設(shè)計稿轉(zhuǎn)代碼的 sketch 插件:
直接把設(shè)計稿信息轉(zhuǎn)成 DSL,然后打印成代碼了,沒有做編輯器,所以用起來比較簡單,
但是不能人工干預。
看下它的源碼分包,也是設(shè)計稿信息轉(zhuǎn)成 DSL,做分組和布局的處理,然后打印成代碼的流程:
它支持生成使用絕對布局的運營版代碼,也可以生成使用 flex 布局的可維護性比較高的代碼。
我試了一下,還原度還可以:
設(shè)計稿是這樣:
Picasso 生成的 flex 布局的代碼是這樣:
結(jié)構(gòu)和樣式還原度還行。
再用 Picasso 生成運營版代碼是這樣:
所有元素平鋪,布局使用絕對定位。
這樣的代碼還原度更可靠一些,但是代碼基本沒啥可維護性,做做活動頁還可以。
總體看下來,Picasso 沒有使用 AI 算法,只是做了 sketch 設(shè)計稿數(shù)據(jù)到 DSL 的轉(zhuǎn)換,處理了下分組和布局轉(zhuǎn)換,同時支持絕對定位和 flex 布局,然后打印成各種代碼。
沒有支持編輯器、也沒有做 className 的處理,對組件標注的支持也不好。
Deco
再來看下京東的 deco,它也是支持 sketch 設(shè)計稿轉(zhuǎn)各平臺代碼。
不過它提供了一個 web 版的工作臺,可以選中畫板,點擊導出數(shù)據(jù),之后瀏覽器會打開工作臺:
導出完成后會提示你到工作臺粘貼:
然后會在工作臺展示設(shè)計稿信息轉(zhuǎn)換之后的 DSL 和生成的頁面的預覽,可以修改 DSL 之后再生成代碼。
還原度也還行,生成的是 flex 布局的代碼。
當然這只是它公開的部分,內(nèi)部版本據(jù)說支持了組件標注、數(shù)據(jù)注入、事件綁定等邏輯層的東西,可以直接產(chǎn)出包含了包含了布局和邏輯的可用代碼。
整體看下來,Deco 做的比 Picasso 更完善,內(nèi)部版本實現(xiàn)了編輯器,支持 flex 布局計算,組件標注、通過 AI 算法實現(xiàn)了通過聚類來自動分組、通過推理引擎生成語義化的 className 等,編輯器甚至還支持了邏輯層的處理,可以生成完整的前端代碼。
CodeFun
Code Fun 是國內(nèi)專門做設(shè)計稿轉(zhuǎn)代碼的創(chuàng)業(yè)公司,因為是通用工具,所以它們支持的平臺更多, 提供了 Sketch、PSD、Figma 等的插件來上傳設(shè)計稿數(shù)據(jù),支持生成的代碼也包含的更多,包括 vue、react、uni-app、taro、小程序等,不過現(xiàn)在只是移動端,桌面端后續(xù)也會支持。
可以在 Figma 里上傳設(shè)計稿:
然后在編輯器里打開:
可以標注組件、可以切換 flex 布局和絕對布局,可以手動分組、編輯樣式,之后預覽或者下載代碼。
可以人工干預的地方比較多,當然,他們也做了一些 AI 的智能處理。
整體看下來, code fun 支持的平臺更多,支持的人工干預手段更多,可以手動編組、標記組件、切換布局方式等,下限比較高。
Imgcook
Imgcook 是淘寶開源的設(shè)計稿轉(zhuǎn)代碼的工具,支持 figma、sketch、psd,甚至還支持圖片。
除了通過插件上傳數(shù)據(jù)外,也可以直接上傳設(shè)計稿文件。
通過插件上傳數(shù)據(jù),還可以做一些分組和切圖的標記:
然后在 web 的編輯器里打開,也可以直接導出代碼:
可以編輯樣式、屬性、綁定事件等,但是這還原度一言難盡:
總體來看,imgcook 支持的設(shè)計稿類型比較多,甚至支持從圖片來提取信息,也提供了編輯器功能可以做一些人工干預,功能還是比較全面的。
Locofy
Locofy 是國外的設(shè)計稿轉(zhuǎn)代碼的工具,支持 figma 設(shè)計稿轉(zhuǎn) react、react native、next.js、gatsby 等代代碼。
支持 next.js 和 gastby 這點就可以看出是國外的工具了。
它的編輯器是在 figma 插件里實現(xiàn)的,而不是獨立的 web 工作臺:
可以手動標注組件,然后設(shè)置屬性。
還有低代碼編輯器的功能,可以直接拖拽組件進去:
手工標注比較麻煩,locofy 也支持 AI 自動標注組件。生成的代碼也可以選擇使用不同的技術(shù):
生成代碼之后會在 web 平臺預覽代碼,可能是因為這個在 figma 插件里做不大好吧:
之后可以導出代碼,或者一鍵部署。
總體看下來,locofy 對組件標注的支持做的挺好的,也支持了低代碼的方式編輯,并且都是在 figma 里做的,這是和其他工具的一個很大的區(qū)別,其他工具都是在 figma 里上傳設(shè)計稿數(shù)據(jù),然后在 web 的編輯器里處理,這樣能跨各種工具復用,而 locofy 可能就只想支持 figma 吧,所以在 figma 插件里做了很多功能。
知道了 D2C 的實現(xiàn)原理和已有的各種實現(xiàn),那我們自己實現(xiàn)一個符合自己需求的 D2C 工具可行嗎?成本高么?
其實還是挺高的,做的足夠通用很難,但就算不需要特別通用,只支持某些業(yè)務(wù)場景,也大約需要一到兩個人一年的時間去全職搞這個。這對于小公司來說是很高的成本了,ROI 比較低。但是對中大規(guī)模的公司來說,能夠用在很多項目上,ROI 會相對較高,就值得投入人力長期去做了。
這也不是我個人的觀點,是轉(zhuǎn)轉(zhuǎn)的一篇文章里提到的:
總結(jié)
設(shè)計稿轉(zhuǎn)代碼的原理是從結(jié)構(gòu)化的矢量圖中提取信息,轉(zhuǎn)換成中間 DSL,然后再生成各平臺的代碼。
從設(shè)計稿轉(zhuǎn) DSL 的過程需要處理分組、做絕對布局到 flex 布局的轉(zhuǎn)換,生成語義化的 className,支持組件的標注。
這個過程可以通過編輯器來實現(xiàn)人工干預,也可以通過 AI 來智能化處理。
下限是編輯器人工干預保證的,上限就要靠 AI 了。
然后我們看了一下各種 D2C 工具:
58 的 Picasso 沒有支持編輯器,組件標注支持的也不好,但是支持生成絕對布局和 flex 布局的代碼,還原度也還行,并且是開源的
京東的 Deco 支持了編輯器,通過 AI 做了很多自動化的處理,還支持了邏輯層的處理,但是目前公開的部分還比較簡單,也沒開源
淘寶的 imgcook 支持的設(shè)計稿類型比較多,還支持從圖片來提取信息,也支持了編輯器,在里面實現(xiàn)了低代碼的組件拖拽編輯,功能比較全面
專門做 D2C 工具的 CodeFun 做的比較通用,支持各種矢量設(shè)計稿(不支持圖片),也支持生成很多種代碼,編輯器功能也挺多,還原度不錯,只不過是收費的,沒開源
國外的 Locofy 只做 figma 轉(zhuǎn) react 系列技術(shù)棧,所以在 figma 插件里做了很多功能,比如組件標注、低代碼編輯,之后在 web 預覽代碼,還可以一鍵部署
這些 D2C 工具其實都不夠通用,要支持自己的一些需求估計還得自研,但是自研一個 D2C 的工具還是需要挺高的成本的,對于中大公司來說,如果業(yè)務(wù)場景比較合適,ROI 還行,還是值得長期去做的。