預測2024年之后的前端開發模式
大家好,我卡頌。
最近AIGC?(AI Generated Content,利用AI?生成內容)非常熱,技術圈也受到了很大沖擊。目前來看,利用LLM?(Large Language Model,大語言模型)輔助開發還停留在非常早期的階段,主要應用是「輔助編碼」,即「用自然語言輸入需求,模型輸出代碼」。更近一步的探索也僅僅是在此基礎上的一層封裝(比如copilot X?、cursor)。
但即使在如此早期階段,也對開發者的心智產生極大震撼,「AI讓程序員失業」這樣的論調甚囂塵上。
LLM的爆發對前端意味著什么?本文嘗試預測一波2024年之后的前端開發模式,這個預測遵循如下原則:
- 尊重技術客觀發展規律。以當前已有技術為基礎預測,而不是將預測建立在某種虛無縹緲的高端技術,或者假想某些技術突破重大瓶頸。
- 尊重人性。程序員只是謀生的職業,新的開發模式即使再厲害,如果讓程序員賺不到錢,那也是很難推廣開的。
范式遷移的本質
為了預測未來,先看看我們是如何走到現在的。
在前端開發領域,我們經歷了從jQuery為代表的「面向過程編程」向前端框架為代表的「狀態驅動」模式的遷移。
當問到「該選Vue還是React開發?」,這樣的問題會引起很大爭議,但如果問到「該選jQuery還是框架開發?」,這樣的問題就不會有太多爭議。
為什么前端領域普遍接受了這種范式的遷移?在我看來,有兩個原因:
1、開發效率提高
這一點毋需多言,相信前端同學都有體會。
2、門檻提高
?「面向過程編程」是非常淺顯易懂的開發模式。君不見,曾經的前端靠一本「鋒利的jQuery」就能打天下。相比之下,「狀態驅動」就有一定學習門檻。
當一項有一定門檻的技術(這里指前端框架)變為行業事實上的標準時,行業門檻就提升了,這為從業者構筑了行業壁壘。
事實上,正是由于:
- web應用復雜度提高
- 前端框架的流行
才讓后端工程師工作職責中的view層,分化出前端工程師這一職業。
對于前端領域來說,只有同時平衡了「提效」與「提高門檻」的技術,才會被市場(這里的消費者指前端工程師)接受。
舉個反例,Angular全家桶的模式雖然提高了開發效率,但是同時,門檻提高太多了。
而且更糟的是,Angular?中的很多概念都是從「后端」遷移而來,作為一款前端框架,對后端更親和且門檻高,這對本身就是從后端view層中分化出的前端工程師來說,是比較排斥的。
再舉個反例 —— Vue?。有同學會說,Vue這么流行的前端框架,你說他是反例?
還是從「提效」與「提高門檻」的角度看,Vue?提效的同時,由于其模版語法、響應式更新等特性,他是降低了開發門檻的,這意味著使用Vue時:
- 同樣是開發業務,老前端與新前端差距不大
- 必要時后端經過簡單的學習,也能接手部分需求
重申一下,我并不是說Vue不好,相反,他是很優秀的前端框架。這里只是從人性的角度分析,并且這個分析很有可能是主觀、帶有偏見的。
再看個正面例子 —— React Hooks?。Hooks?對開發效率、組件復用性以及他對React未來發展的影響這里不贅述了。主要聊聊「提高門檻」:
- 一方面,什么時候封裝自定義Hook,如何封裝自定義Hook,如何規避Hook的坑,老前端與新前端有比較大的差異
- 更重要的是,后端改改JSX還行,要改基于Hooks的組件邏輯,是有一定難度的
既提效,又提高門檻,我認為這才是Hooks在前端領域火熱的原因。
同樣的原因,從人性的角度,我很看好Vue Composition API
所以,前端編程范式遷移的本質是:把握「提高效率」與「提高門檻」之間的平衡。
這個結論會成為后面預測未來開發模式的依據。
當范式無法再遷移時
當前端框架成為事實上的標準后很長一段時間,業界也在不斷探索新的開發范式。
有一種開發模式每過幾年都會被搬出來炒一遍,他就是「低代碼」。用我們上面的結論來分析下:在市場選擇的情況下,先拋開「低代碼是否能提高效率」不談,顯然他的目的是「降低門檻」。
從人性的角度出發,他就很難在程序員群體中自發傳播開。
那么,如果沒有新的范式出現,會發生什么事情?會內卷。
我們會發現,這幾年前端的發展軌跡,就是在重復一件事:
- 圍繞前端框架周邊,不斷探索各細分領域的最佳實踐
- 當探索出最佳實踐后,就把他集成到框架中
舉個例子,React Router?作為React技術棧中「路由」這一細分領域的一個開源庫,經過長期迭代,逐漸成為主流路由方案之一。
React Router?團隊基于React Router?開發出Remix?這一React框架。
這么做,在沒有新的范式出現前,也能基于當前范式(前端框架),達到上述2個目的:
- 提高效率:框架集成了最佳實踐,開發效率更高
- 提高門檻:除了學習React,還得學習新的上層框架
類似的,各種CSS?解決方案(比如tailwind css)也是同樣的道理:
- 提高效率:提高CSS編寫效率
- 提高門檻:新的概念、語法需要學習
那么,未來圍繞「提高效率」與「提高門檻」的平衡,前端開發模式會如何發展呢?
從考慮范式到考慮流程
首先,我認為,在有限的未來,不會出現新的更先進的范式能讓前端領域普遍認可并大規模遷移(就像從jQuery到前端框架的遷移)。
那么,為了提高效率,除了「改變范式」與「范式內 內卷」兩個選擇外,還有個選擇 —— 讓整個開發流程提效。
從需求文檔到最終代碼,存在4級抽象:
- PM用自然語言編寫的需求文檔
- 需求評審時,PM給開發描述需求后,開發腦海里形成的業務邏輯
- 開發根據業務邏輯劃分各個模塊或組件
- 開發實現各個模塊或組件的具體代碼
當前我們使用LLM?輔助編程時(比如以chatGPT為例),主要是用自然語言輸入模塊或組件業務邏輯,再讓模型輸出具體代碼。也就是借助模型自動完成從3到4級抽象的轉變。
比如說下圖我們讓chatGPT實現一個計時器:
這個計時器可能是我們需求中的某個模塊,在此chatGPT幫我們完成了從抽象3(實現一個計時器組件)到抽象4(計時器組件的代碼)。
如果僅僅到這一步,只能說這是個更高效的輔助工具,并不能達到「整個開發流程提效」的程度。為了達到這種程度,我們需要讓LLM幫我們完成從抽象1到4的整個過程。
LLM如何完成4級抽象轉換
接下來我們來看,基于當前已有的模型,如何完成抽象1到抽象4的自動轉換。
首先,來看抽象1(PM用自然語言編寫的需求文檔)。chatGPT當前已經掌握基礎的理解能力,所以他是能夠理解需求文檔的含義的。
下圖是我從網上找的某需求文檔中的登錄功能流程圖:
以當前主流的GPT-3.5?舉例,雖然GPT-3.5?不能理解圖片(不能理解需求文檔中的流程圖),但我們可以將流程圖用文字描述出來(最新的GPT-4已經擁有「理解圖片含義」的能力)。
上述登錄功能流程圖可以用文字概括為:
- 打開App后有3個選項,分別是“賬號密碼登錄”、“快捷登錄”、“第三方登錄”。
- 選擇“第三方登錄”,進入第三方,同意授權后登錄成功。
- 選擇“快捷登錄”,輸入手機號和驗證碼并選擇身份,點擊登錄后登錄成功。
- 選擇“賬號密碼登錄”,輸入手機號,如果已注冊,輸入密碼,點擊登錄后登錄成功。
- 選擇“賬號密碼登錄”,輸入手機號,如果未注冊,進入注冊頁,輸入手機號,如果手機號已注冊,回到“賬號密碼登錄”。
- 選擇“賬號密碼登錄”,輸入手機號,如果未注冊,進入注冊頁,輸入手機號,如果手機號未注冊,填寫手機號、驗證碼、密碼、姓名、選擇身份,點擊注冊,完畢。
抽象1到抽象2
如何完成從抽象1到抽象2(業務邏輯)的轉變呢?換句話說,如何用一種介于「自然語言與實際代碼」之間的規范描述業務邏輯?
這種規范應該擁有完備的數據結構(類似JSON?、XML),因為這樣會帶來很多好處:
- 相比于自然語言,用規范的數據結構表示的業務邏輯能夠傳達更準確的意圖。
- 業務需求的不斷增多,僅僅對應數據結構體積的增大,即使再復雜的業務,只需要分批將業務邏輯代表的數據結構投喂給模型,模型就能完全理解我們的業務。
- 數據結構可以保存在變量中,通過變量名就能指代業務邏輯,無需再用自然語言大段的向模型描述業務邏輯。
我們可以利用SCXML?(State Chart XML)格式。SCXML?是由W3C?定義的一種「表示狀態機」的XML格式,他能夠表示狀態之間的變化。
前端應用的本質其實就包括兩部分:
- 狀態的變化。
- 狀態到視圖的映射。
其中「狀態到視圖的映射」框架已經幫我們做了。所以,只要能表示「狀態的變化」,其實就能表示業務邏輯。
現在,我們讓chatGPT?將流程圖翻譯為SCXML格式:
得到如下結構(你不用細看,了解個大概就行):
至此,我們完成了抽象1到抽象2的轉變。
抽象2到抽象3
SCXML格式沒法直接在JS代碼中使用。為了用代碼實現邏輯,我們需要使用遵循SCXML規范的庫。xstate是JS中比較流行的狀態機開源庫。
所以接下來我們讓chatGPT將上述SCXML格式轉換為xstate語法:
得到結果(同樣,具體代碼你不用在意,了解我想表達的轉換意思就行):
這段代碼我們可以直接粘貼到xstate的可視化編輯器[1]中查看:
圖中初始狀態可以轉移到3個狀態(這些狀態都是chatGPT生成的),其中:
- QUICK_LOGIN —— 快捷登錄
- ACCOUNT_LOGIN —— 賬號密碼登錄
- THIRD_PARTY_LOGIN —— 第三方登錄
每個狀態接下來的變化邏輯都清晰可見。比如,當進入ACCOUNT_LOGIN狀態后,后續會根據是否登錄(UNREGISTERED、REGISTERED)進入不同邏輯:
也就是說,chatGPT理解了需求文檔想表達的業務邏輯后,將業務邏輯轉換成代碼表示。
讀者可將上述xstate代碼復制到可視化編輯器中看到效果。
抽象3到抽象4
接下來,我們只需要讓chatGPT?根據上述xstate狀態機生成組件代碼即可。
這時有同學會問:chatGPT?對話有token限制,沒法生成太多代碼怎么辦?
實際上,這可能并不是壞事。在我曾經供職的一家公司,前端團隊有條不成文的規矩 —— 如果一個組件超過200行,那你就應該拆分他。
同樣的,如果chatGPT?生成的組件超過了token限制,那么應該讓他拆分新的組件。
拆分組件的前提是 —— chatGPT?需要懂業務邏輯。顯然,他已經懂了xstate數據結構所代表的業務邏輯。
更妙的是,我們可以讓chatGPT?將「SCXML格式轉換而來的xstate數據結構」保存在一個變量中,在后續對話中,我們用一個變量名就能指代他背后所表示的業務邏輯(這里保存在變量m中)。
當我們要生成業務組件代碼時,讓chatGPT從模塊中導出m實現組件邏輯:
對于實際場景下比較復雜的需求,經過從抽象1到抽象3的轉換,我們會得到「代表業務邏輯的不同變量」,比如:
- signin變量代表登錄邏輯。
- login變量代表注冊邏輯。
- PopupAD變量代表彈窗廣告邏輯。
如果彈窗廣告的邏輯和是否登錄相關,那么要實現彈窗廣告組件代碼只需要告訴chatGPT:
根據signin?、PopupAD?實現彈窗廣告的react?組件,其中signin?變量由xxx?模塊導出,PopupAD?變量由yyy導出。
如果你司使用其他框架,只需將其中react換成其他框架名即可。當大家還在爭論哪個框架更優秀時,LLM已經悄悄幫開發者實現了「框架自由」。
新開發模式的優勢
讓我們從「提高效率」與「提高門檻」的角度分析這種新開發模式的優勢。
提高效率
首先,這種新模式能顯著提高開發效率。本質來說,他將前端工程師從「實現需求」的角色轉變為「review代碼」的角色。
極端的講,當需求評審會結束的那一刻,第一版前端代碼就生成了。
其次,他能解放部分測試同學的生產力(搶部分測試同學的活兒)。對于維護過屎山代碼的同學,肯定遇到過這樣的場景:明明只是改動一個小需求,測試問你改動影響的范圍,你自己都不清楚會有多大影響,為了穩妥起見只能讓測試覆蓋更大的回歸測試范圍。
在使用基于狀態機的開發模式后,任何改動會造成的影響在狀態圖中都清晰可見。同時,由于代碼邏輯的實現基于狀態機,可以據此自動生成端到端的測試用例,模型也能根據狀態機描述的邏輯自己補足其他單測。
提高門檻
接下來,我們從「提高門檻」的角度分析。
首先,能夠對模型生成的代碼進行查漏補缺本身就要求開發者有一定前端開發水平。
其次,這種開發模式引入了新的抽象層 —— 狀態機,這無疑會增加上手門檻。
但這都不是最重要的,最重要的是 —— 這套模式強迫前端開發需要更懂業務。
以前,拿到產品的需求文檔后,你可以在做的過程中遇到不懂的再問產品。使用新的開發模式后,你必須很懂業務,做到「在需求評審時就能指出需求文檔中不合理的地方」。
因為當需求評審結束后,你會將這份需求文檔投喂給模型直接生成業務代碼(中間會經歷「生成SCXML」、「生成xstate數據結構」、「保存xstate變量」、使用變量生成組件代碼)。
當大家技術水平旗鼓相當時,「懂業務」才是前端的核心競爭力。
綜上,這套開發模式在極大提高效率的同時提高了門檻,我認為在未來很有可能成為主流前端開發模式。
參考資料
[1]xstate的可視化編輯器:https://stately.ai/viz。