前端開發的瓶頸與未來之路

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