大家好,我卡頌。
這麼多年大家習慣了使用JSX
描述UI
的React
。甚至部分場景下使用Vue
時也會選擇JSX
而不是模版語法
。
好像一切就這麼自然而然發生了。
然而,如果梳理歷史的走向,模版語法
才是更自然的選擇。接下來讓我們看看React
選擇JSX
背後的邏輯是什麼?這是React
如今生態繁榮的關鍵因素麼?
本文參考HTML模板語言縱覽
模版語言簡史
前端在有足夠複雜度之前都是作為後端MVC
框架的V
(view,即檢視層)存在的,操作view
的主流方法是模版語法
。
雖說PHP
是最好的語言,但在早期PHP
更多是作為HTML
模版語言出現的,這也能從他的全稱Hypertext Preprocessor
(超文字前處理器)中窺探出一絲端倪。
當瀏覽器請求網頁時,服務端會執行模版中的PHP
程式碼,將填充了變數值的HTML
會作為資料返回。
比如如下模版,name
會被填充為變數值:
<h1>
<?php echo "My name is {$name}"; ?>
</h1>
很多服務端語言都實現了PHP
風格的模版語法,比如:
- 基於
Java
的JSP
- 基於
PHP
二次封裝的smarty
- 基於
Ecmascript
的EJS
這類模版語法雖然功能全面,但是當頁面結構複雜時,邏輯(PHP
程式碼)會不可避免的和UI
(HTML
)混雜在一起。
為了更好的展示UI
,Github
的聯合創始人Chris Wanstrath
開發了Mustache
。
這是一款重UI
而輕邏輯的模版解析引擎,主流程式語言幾乎都有各自的Mustache
實現。
對於上面的例子,Mustache
語法為:
<h1>
My name is {{name}}
</h1>
Mustache
能直觀的表達UI
,但是缺失對邏輯的表達能力。更多模版語法
則嘗試在UI
與邏輯之間尋找平衡。
比如Django
的DTL
(Django Template Language)除了使用與Mustache
相同的 {{}}
語法表達UI
中的變數,還包含大量的常見邏輯,比如:
if else
等流程控制邏輯{% if condition %} ... display {% endif %}
for in
迭代邏輯<ul> {% for user in userList %} <li>{{ user.name }}</li> {% endfor %} </ul>
- 過濾器
/* 將name轉化為小寫形式 */
<p>{{ name | lower }}</p>
現如今,前端框架的模版語法
中可以看到很多服務端曾使用的模版語法
的影子。
如果你是個服務端工程師,看到如下Vue
模版語法時想必會很親切:
<h1>my name is {{name | lower}}</h1>
所以,從後端view
層分離並逐漸發展的前端框架,最符合直覺的方式就是採用模版語法
描述檢視,比如09年出現的現象級前端框架angular
。
然而,React
並不這麼認為。
用逆向思維思考
前端框架需要描述兩樣東西 —— UI
與邏輯。
模版語言
的底層邏輯是:即然前端使用HTML
描述UI
,那麼我們就擴充套件HTML
語法,讓他能描述邏輯。
即:從UI
出發,擴充套件UI
,描述邏輯。
那我們換個思路,在前端用什麼描述邏輯呢?JS
。
那我們能不能從邏輯(即JS
)出發,擴充套件邏輯,讓他能描述UI
,不就達到同樣的效果嗎?
這,就是JSX
—— 一種JS
語法糖。
後記
由於JSX
以邏輯為起點,所以能輕鬆描述複雜的UI
變化。這使得React
社群的早期參與者可以快速實現各種複雜的基礎庫,豐富社群生態。
對於前端框架的選型,一個重要的考量是:社群生態是否繁榮?
換言之,對於日常業務開發遇到的需求,能否很快速在社群中找到成熟的解決方案?
專案一旦確定了技術選型,中途再切換其他技術棧會付出極高成本。這進一步推動更多開發者參與社群建設,最終形成源源不斷的正反饋。使得React
長期霸榜工程師最願意使用的前端框架。
這一切,從另闢蹊徑發明JSX
那一刻就埋下了伏筆。
歡迎加入人類高質量前端框架研究群,帶飛