前端開發的瓶頸到底在哪裏,前端技術是否已經走到一個十字路口,全棧化的系統架構是否能改變目前的窘境?本文將根據做者自身的開發經歷談談當下前端開發中遇到的一些問題和想法。前端
近兩年我一直在思考的一個問題:java
若是前端不用考慮性能問題、不用考慮終端兼容性、不用考慮歷史遺留問題,甚至不用考慮具體技術實現...node
若是咱們假設本身有豐富的技術儲備,同時不用考慮上面的問題,那麼前端究竟 能 作出什麼樣有價值的東西?程序員
咱們把時間拉到 5 年前...web
若是你「那時」仍是前端開發的話。上面的問題確定是你不得不面臨的典型問題。甚至是當時前端開發的意義所在。typescript
可是隨着時間的推移,前端技術的更新迭代,以及互聯網的發展。你會發現這些曾經的問題彷佛已經再也不是問題,或者說在能預見的將來 可能 再也不是問題。npm
頁面加載性能可能再也不是問題,技術上有了 HTTP2,基建上有了 5G,硬盤也愈來愈快。編程
兼容性問題慢慢淡出你們的視角,Chrome 一家獨大,微軟也不得不向它靠攏。後端
不少前端開發已經具有了後端(或者說多端)的技術能力,技術儲備也可能不是問題,固然前提是你能招到人。瀏覽器
到底什麼是前端開發,前端與後端的界限在哪裏?我在三年前對它的定義是:
前端爲 界面、交互展現負責; 後端爲 數據、業務邏輯負責;
不過如今看來彷佛已通過時了,我愈來愈以爲不該該有這樣一個清晰的界限把先後端分割開來,尤爲是技術層面(除了職能層面的界限有利於協做之外)。這就比如說:若是你不能打破規則,那就必將被規則束縛。
我一直認爲程序員應該對新的技術、工具、理念有比日常人更快的適應能力。舉個簡單的例子,我之前寫代碼一般使用 tab 縮進,後來你們都建議使用空格,剛開始嘗試換成空格確定是拒絕的,由於讓人改變習慣是一件很難的事情。可是當你真正爲了改變作出實踐的時候,每每就會發現一條新大路。一樣還有加不加分號的問題。
如今回過頭來再看,前端在整個系統層面擔任的角色至少應該是整個視圖 View 層面的。視圖層面的技術更接近軟件系統的上層,更感性。感性的東西就是說一個顏色,我以爲好看,他以爲很差看,徹底屬於我的情感訴求。因此前端更注重與UI、交互 以及整個產品層面須要解決的問題。優秀的前端必然要具有敏銳的產品洞察能力。
固然這還只是前端最基礎的職責所在。同時前端作爲最接近產品的技術角色,技術纔是前端真正的硬實力。
大約在去年一年的時間,個人崗位從前端轉向了後端 Java 程序員的角色。雖然只作了一年的 Java 程序員,可是對我自身的技術提高而言是最多的一年。你們可能廣泛的認爲後端轉前端比較容易,前端轉後端會有門檻,實際上根據我本身的體驗來說並不是如此。
Java 這門語言是商業化、成熟度特別高的語言。不管是語言自己,仍是周邊框架、工具都有一套很是成熟且井井有條的系統化抽象。若是你有兩、三年的編程經驗,忽然讓你上轉寫 Java 是很是容易的一件事情,尤爲是寫 Java web。Spring 框架已經爲程序員屏蔽了不少複雜問題,並且已經事實上成爲了各大互聯網公司的主流框架選型。
我特地按我本身的學習線路繪製了一張 Java 版的程序員學習線路,僅供參考:
咱們能夠清楚的看出來 Java 構建的整個體系最大的特色:它是漸進式的,一步一步地給開發者創建正向的引導。
當我處在在應用層階段的時候,我須要關心的只是一些概念,方法,具有基礎了之後就能夠藉助 Spring 框架入門,入門後就能夠研究源碼,你會發現 Spring 的本質核心類 DispatchServlet,今後 Servlet 就出如今了你的視野。我之前上學時理解不了 java 中 Servlet 的概念,後來參加了工做又學些了 Python,再次看到 Java 中的 Servlet 的時候瞬間就明白了它就是 Python 中的 uwsgi,就是一種接口,將編程語言和服務器網關連接起來的一種規範。
而後你就能夠順利進入下一環節,服務器/通訊。這裏你會發現整個網絡編程的核心 Socket,一樣之前上學的時候沒理解 Socket 的概念,繼續學習後你就會明白 Socket 其實就是操做系統提供給編程語言的一種能力,有了它就能夠創建服務器與客戶端之間的通訊。在這一環節中你會學習到網絡層 TCP/IP 協議,明白了 TCP/UDP 的區別,while (true) { socket.listen() }
創建 Socket 監聽會有性能問題,此時你便進入下一個抽象層次,操做系統和計算機原理。
爲了解決「while true」監聽鏈接的性能問題,你會去學習多線程技術,瞭解併發的概念。你可能總會聽到別人討論併發和並行的區別。繼續學習後,慢慢的你就會明白:併發多用來解決網絡IO(硬盤)的效率問題,而並行則是爲了更好的利用多/核處理器(CPU)的問題。這時你會發現這個階段涉及到了不少的計算機硬件知識。內存分配、CPU計算、IO 複用等等。
像 Spring 這種框架才能真正意義上被稱作 框架,由於它不只僅解決了軟件開發的問題,更重要的是 AOP/IoC 這類概念能夠徹底改變編程的一些理念。使用 Spring 開發 web 應用,聯合 Java 構建出來的生態,整個開發流程就像呼吸同樣天然。
Java 構建出來的軟件開發體系就像是把程序員放進了一個一個的井井有條的小櫃子裏面,進去了之後你根本不須要關注外界是怎麼樣的,作好本身那部分工做就能夠了。若是你對外界有興趣能夠一點點的順藤摸瓜,跳出你原來的小櫃子。即保證精力專一的同時又創建起一套有秩序的提高曲線。這一點是別的語言體系沒有的。
實際上我在轉 Java 以前對 Java 有着不小的誤解,甚至轉 Java 自己也不是我本身的想法。但當你真正轉型成 Java 程序員後。看懂了數以百萬行記的代碼倉庫、維護過每秒好幾十萬的 QPS 項目、見識過百行的 SQL 的時候,你纔會對 Java 和軟件開發產生一種敬畏之心,纔會對技術纔有了更深層次的理解。
這時候再回過頭來看前端,看 JavaScript,纔會發現它們之間的區別與特色。不少以前爭論的東西也就有告終論。
我相信從事前端工做稍微長一點(5年以上)的人近兩年都會有一種感受:前端彷佛沒什麼東西能夠玩出花樣了。這是由於不少東西都已經成爲了前端事實上的主流,之前前端沒有的基建慢慢的被完善。語言、框架、可視化、跨端、遊戲、工具/自動化/工程化 這些領域都在發展。
語言方面 TypeScript 必然是主流,不管你願意與否,你都將不得不使用它來寫前端。框架方面 React 已是事實上的主流了,不必再作選擇題。打包工具 Webpack 也是一家獨大,雖然被不少人詬病,可是社區生態起來了,想改變就很難。跨端應用 Electron 也不用想了,VSCode 能作好你作很差那就不是選型的問題了。2D 遊戲/繪圖方面 PixiJS 6 已經在設計中了,3D 我我的認爲就先別玩了。
這些看似成熟的體系實際上仍是有不少能夠挖掘的東西。若是你不深刻研究,或許會認爲過兩年這些技術就穩定了前端就能夠作到大一統的狀態。這個想法可能就過於天真了,我舉例解釋下它們各自的瓶頸:
React(並不特指 React)雖然如今看起來是主流,可是它自己有不少問題是沒解決的,甚至能夠說是無解的。React 的本質只是一個 UI Library,並非框架 Framework。框架要解決的問題是系統層面的不是某個抽象層面的。用 React 寫過幾個項目之後你就會認識到用 React 去寫大型項目是很是麻煩的事情,React 自己並不解決 SPA 應用中數據流的問題,甚至沒解決狀態管理的問題(或者說狀態管理原本就是個僞命題?)。一個很簡單的父子組件之間狀態共享的問題一直沒有成熟的解決方案,hooks 這種方案更像是拆了東牆補西牆。
並且如今 React 社區瀰漫着一種崇尚函數式編程的邪氣,hooks 更像是一塊遮羞布。多數人用 hooks 的緣由僅僅是不想使用 Class,由於 Class 很臃腫,function 更簡單。固然這個邏輯是沒問題的。函數確實簡單,可是若是你把一個函數裏面寫上幾百行的代碼,各類 hooks 用到飛起的時候,你纔會回過頭來反思如何組織代碼。若是 Class 能以一種更好/更易於理解的方式去抽象那爲何不用呢?
前端框架如此,基於 Node.JS 的後端框架也好不到哪兒去,難道你真的想用 Express/Koa.js 去寫大型的後端應用?這種量級的框架連 web 開發最簡單的三層模型( 模型、視圖、控制器)支持都不完整。固然你可能會說小型框架原本就只關注某一方面嘛,視圖和模型層的東西能夠用其它三方庫解決。是的,確實能夠這樣,不過你不以爲 Node.JS 的第三方庫有點太多了嗎。正如 NestJS 在文檔中提到的一個問題同樣「不少 JavaScript 類庫都沒有高效地解決一個問題 架構。」React/Vue/Express/Koa 這些都是相對獨立的點,沒有一個東西能把他們鏈接起來造成一個面,造成一種框架級別的體系。這就是架構的問題。
這裏多說一點,結合上面 Java 構建出來的生態,對比 Node.JS 的話。我借用本身打過的比喻:若是你低頭看到的是 Node.JS,那麼你擡頭未必能看見 Java。假如你從事前端開發 2,3 年遇到瓶頸,想轉學 Node.JS,你會學習 Exporess/Koa 這類框架,可是很快你就會發現一個嚴重的問題:沒辦法深刻下去了。由於當你用 Express 寫完一個頁面後就面臨着各類技術上的盲點,會讓你無所適從。
我也嘗試繪製一張我對 JavaScript/Node.JS 或者說大前端體系理解的一張圖:
JavaScript 體系看似先後端通吃,客戶端、 服務端甚至桌面端皆有。可是最大的問題在於:沒有一個東西能給他們創建起關係並發展成爲一種體系。
插播一條娛樂看點,前兩天寫 Ruby on rails 框架的做者 DHH 發推並配圖:
大意以下:
如今的年輕人在 web 開發的時候是這樣的嘛?底層邏輯、純手寫鏈接池 + 純手工 SQL、配置文件都放在了一塊兒。天哪!(截圖中使用的式TJ大神寫的 Express 框架)
而後 TJ 大神也回覆了:
大意以下:
只有菜鳥玩家才能寫出乾淨、簡潔、高性能(黑 Ruby 性能)、見名知意的 SQL,而不是去寫一個有15層的抽象。
二者的推特對話挺有意思,你們娛樂一下。
TypeScript 也主流,可是持續關注 TS 到如今,我發現 TS 也遇到了瓶頸,這個瓶頸不只來自於 TS 的設計目標與理念,更多的仍是社區及 TC39。TS 的設計初衷是 JavaScript 的超集,因爲自己要編譯成 JS,這一點本質上限制了 TypeScript 的方向,設計者對於添加一個新特性會很是謹慎,一者怕與 TC39 ES proposal 衝突,兩者要考編譯到不一樣版本 JavaScript 的兼容性問題。以致於如今 TS 新的語言特性只會跟進 TC 39 發佈的最新 ES proposal。可是我我的對於 TC 39 的效率及將來持懷疑態度,decorator 的提案一直還處於 Stage 2 的階段,像這種其它語言都成爲標配好幾年的事情,如今 JavaScript 社區還在草案(stage-2)階段。
普及下 ECMA 的標準的流程:
- stage-1:前期設想
- stage-2:正式提案(裝飾器所在的階段)
- stage-3:實現候選
- Stage-4:完成測試
- 各個瀏覽器 JS 引擎實現;TypeScript 實現
在這個問題上我認爲其實也很好解決,開個腦洞:若是微軟想借助編程語言一統瀏覽器和客戶端是沒有什麼不可能的。併入 TC39 組織,開發真正屬於 TypeScript 的原生引擎,奉天子以令不臣的方式也何嘗不可。
近幾年 Microsoft 對於開源的投入是肉眼可見的,微軟要發力我相信不少東西都會有翻天覆地的變化。
Webpack/Babel 就更不用說了,主流中的主流。可是也是問題最嚴重的一個。Webpack/Babel 的流行偏偏從反面證實了前端的基礎設施有多麼的爛。如今國外網友老每天叫喊着 Webpack/Babel is eval 也是挺值得深思的。咱們引入了一個新工具來解決問題,卻又在不經意之間產生了新問題。
前端構建工具問題的本質仍是在於 Node.JS 的包管理工具的設計。這一點在 Node.JS 的做者 Ryan Dahl 關於 Deno 演講《10 Things I Regret About Node.js》中也有過「官方」的認可。我相信任何一個實現過構建工具的人都被 Node gyp 戰勝過。node-sass, fsevent 的痛沒必要細說。更不用說萬年被黑的 node_modules 了,你根本不知道一個簡單的 npm install 命令會致使安裝成千上萬個 npm 包被安裝到你的機器上。
固然每種編程語言對應的包管理工具都要解決依賴問題,並且這是一個廣泛的問題,腳本/解釋型編程語言尤其突出,Python/Ruby/PHP 都有這些相似的問題。或許 Go/Rust 這種把源代碼編譯打包成單個可執行文件的方式纔是好的解決方式。
從前人們老是抱怨 JavaScript 這門語言,黑它、諷刺它。可是我看到的是它在一點點變好。不只是語言層面逐步完善,工具鏈生態日趨成熟,使用它的也人愈來愈多。你們對它的關注程度也在提升,整個 JavaScript 開發者的水平也在向更高更強的方向發展。生存環境只會淘汰那些老舊再也不進化的事物,能適應變化的纔會永存。
JavaScript 這門語言有兩個其它 任何 編程語言都不具有的優勢:
當下的前端開發情況不禁得讓我我想起蘇東坡《晁錯論》中的一段話:
天下之患,最不可爲者,名爲治平無事,而其實有不測之憂...
最大的問題在於,有些事物,從表面上看着平淡無奇,但實際上底層暗流涌動,彷佛每一時刻都有着鉅變的可能性。這也是前端開發最有趣也最有潛力的地方。
做爲一名新時代的前端開發者,就是要在這看似風平浪靜的表面之下,找到一些真正的突破點,興許只是一個簡單的想法,順應時勢而後造就出不斐的成就也說不定呢。
不管是前端仍是後端、國內仍是國外,技術纔是真正的核心競爭力,只有技術革新才能提升生產力,而對於咱們程序員來說,編程則是惟一能提高硬實力的方法。只要你心中充滿了熱情,堅持下去總會走出一條本身的路子。
分享一段小經歷
我在 2018 年有幸參加了 TypeScirpt 的推廣大會,TypeScript 的做者 Anders Hejlsberg 親自主講。一位將近 60 歲的程序員在講臺上口若懸河的講技術方案,TS 的設計理念。你真的很難想像這樣一位處於「知天命」階段的老頭子(實際上很年輕)講的東西。
QA 環節有個年輕小夥問到 Anders「在中國作程序員很累、很難應該怎麼堅持下去(相似這樣的描述,細節記不清楚了)」的問題。
Anders 幾乎絕不猶豫的說出了「Passion」這個單詞。我瞬間就被打動了。由於在此以前我對於「激情」這個詞的認識還停留在成功人士的演講說辭層面,當 Anders 親口說出 Passion 一詞的時候,讓人感受真的是一字千金。
直到如今 Anders 還作爲 TypeScript 的核心貢獻者爲它提交代碼,處處奔走爲 TypeScript 宣傳。
咱們再回到前端,那麼將來的前端到底會發展成什麼樣?長期而言充滿了未知數,誰也無法預測,可是短時間來說我比較關注幾個東西:
若是你仔細研究一番,上面的這些新鮮東西,都是起源於前端,但又不把視野侷限在前端。或許這就是前端將來的發展方向吧。