? 前端與 DSL
? 最近一直在想前端與 DSL 的一些聯系與發展,DSL 的概念在后端工程師中可能會更加熟悉,但在前端領域中也是充斥著 DSL 的身影。
? DSL 簡介
??DSL(Domain Specific Language)中文翻譯為領域特定語言,例如 SQL、JSON、正則表達式等。與之形成對比的是 GPL(General Purpose Language),中文翻譯為通用編程語言,我們熟悉的C、C++、JavaScript、Java 語言等就是。
? 特點
? DSL 的特點,在《領域特定語言》這本書中的描述,按照我自己的理解為:
是一門便于人們理解的編程語言或規范語言,并且可以被計算機解釋執行。
相比于通用編程語言,只能表達有限的邏輯。
因為受限的表達性,所以只會在某一些領域廣泛應用。
? ?分類
主要分為三類:外部 DSL、內部 DSL、語言工作臺 。
內部 DSL是一種通用編程語言的特定用法,只不過具有特定的風格。相對于前端最熟悉的就是 jQuery 庫,還有 Grunt、Glup、Mocha 等,其都是基于 JavaScript 語言,在他們所需要解決的領域中形成一定語法風格。
// jQuery
$('#my-div')
? .slideDown()
? .find('button')
? .html('follow');
// Mocha
describe('User', function () {
? describe('#save()', function () {
? ? it('should save without error', function (done) {
? ? ? var user = new User('Luna');
? ? ? user.save(done);
? ? });
? });
});
外部 DSL是一種獨立的編程語言或規范語言,一般有其特定的語法。前端中除了 JavaScript,其實我們大多數使用的都屬于外部 DSL 的范疇,比如 HTML、CSS、LESS、JSX 等。
<div>
? ? <header>title</header>
? ? <section>content</section>
? ? <footer>footer</footer>
</div>
語言工作臺 (Language Workbench)是一種專用的 IDE,可以將 DSL 可視化,并且可以定義和構建一個 DSL。前端工程對于 IDE 和可視化的追求可以說一直是火熱,VS code、各種前端搭建可視化工具。
UI DSL 的發展
Web 前端并不是只有 HTML/CSS/JS ,其實歷史的洪流中還有 Silverlight、Flash、ActiveX 等,然而各種原因互聯網選擇了 HTML/CSS/JS 。JS 的初衷并不是為了構建復雜 UI 而設計的,所以對于越發復雜的 Web 前端,前端的 UI DSL 也是在循序漸進的發展,HTML/CSS/JS 的規范不斷的在改進迭代,業界更是不滿足于現在標準而不斷的擴展,從 CSS 到 Less/Sass 、 JS/JSX、Vue 和 Angular 都有各自的組件和 Template 實現,再使用轉譯器,最終運行等效的代碼。
通過基于現有語言,擴展或結合創造一種新的 UI DSL,對于前端開發者的接受程度可能會高,但現實原因只可能更復雜,各種標準規范委員會、瀏覽器廠商、前端 Runtime 等等。小程序則為了提高交互體驗結合 Native 和 WebView 的各自優勢,UI DSL 趨向于 Web 端語法,對 Web 前端開發人員友好。
相比 Web 端,移動端因為其原生的獨特性 UI DSL 則是出現了斷崖般的升級。例如 Object-C 到 Swift UI、Android 的 Kotlin Anko、跨平臺 Flutter 的 Dart。各語言背后都是大廠商的支持,初衷都是想開發出更好構建 UI 的語言,大家的趨勢都是UI as Code。
UI as Code
本質上移動端、Web 端雖然有些許不同,但都是前端,問題領域高度一致。UI as Code 在我看來,這個 Code 的意思,就是一門通用編程語言,然后基于這個編程語言來創建一門內部 DSL 來構建 UI ,邏輯和 UI 的編程都是同一門語言,更加高效并減輕開發者的負擔。
Web 前端也有類似的發展趨勢。CSS 出現了各種 CSS in JS 的方案,JS/HTML 擴展為 JSX,雖然還是有著濃重的 HTML/CSS 色彩。隨著現在許多成熟的組件框架庫出現,在開發中后臺的時候,除了JS ,很多時候就幾乎只組裝組件和一些簡單的布局,已經沒有寫很多 CSS 和直接操作 DOM。這就感同身受了一句話:“編程就是在為自己的應用程序設計 DSL“ ,就是使用組件針對你開發的應用程序構建內部 DSL(封裝組件、方法),通過犧牲一部分通用性靈活性提高開發效率。
Facebook 可以構建出 JSX ,Microsoft 可以創造出 TS ,國內也有 Vue ,相信前端在語言層面上的更大的機遇是會抽象出更加好用的 DSL。
可視化平臺
前端搭建系統/可視化平臺,難點多難度大,投入風險高,潛在的回報也巨大。大廠商都在投入研發通用性更高的可視化搭建平臺,適用范圍更廣;小廠商則會針對特定業務來開發搭建系統,難度稍低見效快。如果把范圍限定在二者之前,在一個適當的業務領域里,研發與業務領域專家充分溝通,投入研發相關的模型和 DSL ,以可視化作為輔助,在靈活性和效率上找到一個平衡點,可以大大提高領域生產力。
我們經常會去嘗試創建拖拽加配置的可視化搭建系統來解決各種不同的業務。沒有銀彈,系統的復雜度不會消失,只會轉移,這里就容易產生COBOL 謬論:”編程語言很難是因為它不像我們平常交流的語言,如果把編程語言設計為像我們平常用的語言,就會容易多了“。"前端很難,我們把它做成可拖拽的可視化平臺,就不需要前端開發了"。
antd 相當于是就是構建了基于 JSX 的 DSL ,在中后臺前端開發領域,通過抽象基礎的交互展示邏輯, 犧牲了極少的的可擴展性,通用性和靈活性都達到了一定程度。
可視化搭建系統中有一個難題是,當可視化搭建無法實現某些需求,開發者通過修改代碼來實現需求后,之后可能就無法再繼續轉到平臺上。對于代碼和可視化搭建的互轉是一個難題。如果換一個思路,可視化搭建轉成的代碼,不是直接的 HTML/CSS/JS,而是一個新的內部 DSL 或外部 DSL ,這個 DSL 背后的模型的在靈活性和代碼/可視化的互轉上有特定的設計,代碼修改,只要符合這個 DSL 的規范,則可以轉為可視化的平臺中。這就又回到上面的討論,沒有銀彈,以 UI as Code 為趨勢,在某一方面上犧牲,縮小領域,換取高效。
產生的問題
不管是內部 DSL 或外部 DSL,盲目的創造 DSL ,造成的問題就是,大家學習與理解的負擔越來越大,因為使用多種語言比使用一種語言復雜得多,開發可能沒有提效反而更加復雜而容易造成 bug 。
但程序的復雜性不會消失,不使用 DSL,也會需要使用不同的程序庫,好的程序庫的設計就必不可少,可謂 “程序庫設計就是語言設計”。然而一個好的 DSL 也應該是讓人容易理解并且容易使用,降低學習成本。
結束語
當大家陷入大量業務開發的時候,不防跳出細節,看看一些抽象和理論的東西來找找靈感。隨著網絡的提速 5G、6G ,還是 AI、AR/VR 的高速發展,前端交互模式的改變和創新,前端可以探索的東西應該是越來越多的。
想持續了解更多,不妨點贊和關注唄。
創作不易,感謝支持!
Web前端技術交流q群:1137068794,
群里可以一起學習編程,進群能領到學習資料以及源代碼