2015 前端生態發展回顧
引用蘇寧前端架構師的一個總結作為開篇
程式設計技術及生態發展的三個階段
- 最初的時候人們忙著補全各種API,代表著他們擁有的東西還很匱乏,需要在語言跟基礎設施上繼續完善
- 然後就開始各種模式,標誌他們做的東西逐漸變大變複雜,需要更好的組織了
- 然後就是各類分層MVC,MVP,MVVM之類,視覺化開發,自動化測試,團隊協同系統等等,說明重視生產效率了,也就是所謂工程化
處在2015年這個時間段來看,前端生態已經進入了第三階段。看上去好像已經走的挺遠了,實則不然。如果再用人類歷史上的三次工業革命來類比,前端發展其實不過剛剛邁入了蒸汽機時代,開始逐步用工具來替代過往相當一部分的人肉作業,但是離電氣時代的自動化流水線作業還有很長一段路要走。回顧一下2015年前端的生態發展,我大致整理了幾個我覺得比較有歷史意義的事件。
按時間順序:
- 年初React Native的釋出,引領React正式走上歷史舞臺。
- 3月angular2.0第一個預覽版釋出
- 5月 http/2.0標準正式釋出,同月 iojs 與 nodejs合併。
- 6月 ES6 和 WebAssembly 落地
- 7月 迄今為止React生態圈影響最大的Flux實現redux釋出1.0版本
- 8月 Facebook公開了在React上應用GraphQL的relay框架的技術預覽版
- 9月 React Native for Andriod 釋出
- 11月伊始,es標準委員會宣佈將歷時3年研究的Object.observe從草案中移除,儘管它原本已經是stage2,幾乎已經是ES7的事實標準。雙十一剛一結束,阿里手淘團隊釋出了名為 無線電商動態化解決方案 的 Weex,也有人給了它一個更具象的名字,vue native。
- 12月,趕在2015的尾巴,aurelia和angular2先後釋出beta版。
css方面,postcss & cssnext先後高調走到臺前。
觀念的變化
由於近幾年前端的野蠻生長以及前端應用的多元化和複雜化,整個技術形態已經跟幾年前純做頁面的時代完全迥異了。主要觀念的變化總結來看在於一點,現在的前端開發面向的是web app而不是web page。今天的前端開發模式跟傳統的GUI軟體(如C++、.NET開發的windows客戶端)已經很接近了,而且由於現在前端領域為了解決日益複雜的web業務需求及體量,越來越多的借鑑了傳統客戶端的開發經驗,導致兩者變得越來越趨同。再加上前端一些獨特的特性(免安裝、增量安裝等),工程上的複雜度有過之而無不及。前端如今已經脫離了茹毛飲血、刀耕火種的原始社會,開始步入了工業時代。
框架 & 類庫的變化
今年最火的框架/類庫毫無疑問當屬React了。React從2014年年中開始廣泛受到開發者關注,但是真正開始在社群獨領風騷還得歸功於2015年初React Native的釋出。React Native的釋出使得js統一三端(前端、後端、移動端)開發成為可能(現在這個時間點看可能還是過於理想,但是整體方向還是對的),這一針強心劑吸引了大量開發者的眼球。筆者對此最大的感受就是,我在社群發表一篇react的入門教程級別的軟文便可獲得廣泛關注及轉發,相應的寫angular原始碼剖析的準乾貨大部分情況則是門可羅雀
我們挑幾個主流的框架來講講這一層的變化。
React & Redux
React基本簡介可以參考這篇文章React簡介,這裡不再贅述。這裡挑幾個核心特徵簡單來講:
-
virtual dom
這個可以說是F家工程師超強工程能力的最佳體現了(Relay也算一個),從本質來看它是通過用js object來模擬了一個dom tree,然後將這層virtual dom插在react元件跟真實dom之間,配合強勁的dom diff演算法實現它一直標榜的高效能。 -
jsx
同樣為了配合react中的元件化開發模式,F家發明了一套新的語法jsx。乍看之下它像是html in js,這也是初接觸的開發者最難以接受的,典型的違背前端推崇多年的表現與業務分離的原則啊。其實這裡要換個角度來看jsx,它並不是html in js,準確來說它是一個用來構建react元件樹的AST。這樣來想你就能理解react中這一看似怪異的設計了。 -
immutable object
不可變物件是函數語言程式設計中的重要概念,react的介入使得這一理念在前端社群中流行起來。從目前各種類庫的實現來看,不可變物件在大型應用中擁有傳統可變物件不具備的優勢。尤其在這個記憶體不值錢的年代。從目前immutable object的良好走勢來看,將來有可能被es納入規範之中。目前可以通過facebook的immutable.js來實現。
Redux則是目前react配套的Flux模式的各種實現(其實現在兩者的關係越來越模糊了)中最火的一個,在此基礎上它引入了函數語言程式設計、單一資料來源、不可變資料、中介軟體等概念。一定程度來講,redux是今年react生態甚至整個前端生態中影響最大的一個框架,它給整個前端技術棧引入了很多新成員,儘管這些概念可能在其他領域已經有了廣泛的應用。雖然它們是否會在大規模的應用實踐中被廣大開發者認可還需要再檢驗,但至少給我們帶來了一些新的思路。其中的單一資料來源、不可變資料、中介軟體等思路目前來看還是非常有價值的,尤其是單一資料來源跟不可變資料,很有可能在將來成為大型應用架構中的標配(目前來看至少在應用中構建Store層在當前的前端架構中是勢在必行的)。單一資料來源就好比在前端構建了一個集中式資料庫,所有的資料存取操作物件都是它,不單如此它裡面還實現了觸發器,當有insert/update操作時它會對相應元件作rerender動作,這個在各元件之間有資料同步需求的場景下就非常有用了。
至於我對函數語言程式設計的看法,後面單獨闡述。
在我看來,react的優勢並不在元件化,元件化的實現方案多種多樣。react的優勢在於virtual dom及一個幾乎構成閉環的強大生態,這歸功於F家工程師強大的工程能力跟架構能力。virtual dom將應用表現層從瀏覽器這個基於dom的上下文中抽離出來,通過原生js物件模型的方式使得react具備在任何環境支撐上層表現的能力。上層的渲染引擎可以是canvas、native、服務端甚至是桌面端,只要相應的端提供基於react元件的渲染能力,即可達到一套程式碼、或者只要很少的改動就能移植到任一終端環境的效果,這個就非常誇張了。react從0.14版本之後便將react-dom抽出來變成一個獨立的庫,可見react的野心並不侷限於瀏覽器,相反從這點來看,react反而是受到了dom的掣肘。
Angular2 & Vue.js
ng2跟ng1相比是一個完全革命性版本而不是升級版,它是一個為了迎合未來的標準及理念來設計的全新框架,而這些新的理念又無法通過改進ng1.x的方式來實施,所以angular團隊做了這麼一個看似激進的決策,可以理解成重構已經無法滿足需求只能重寫了。ng2也採用純元件化的開發思路,任何單元對於它來說都是元件。同時,ng2裡面也引入了一些全新的概念(對於前端而言)來提升框架的效能及設計,例如基於worker的資料檢測機制能大幅度提升渲染效能(對應實現是zone.js),基於響應式程式設計的新的程式設計模型能更大的改善編碼體驗(對應實現RxJS)。趕在2015年的尾巴,ng2正式釋出beta版,對於angular的這次自我革命是否能成功,還有待後續檢驗。另外原angular團隊中出來的一個成員開發了一個類ng2的框架aurelia,有相當的開發者認為它更配稱為ng2,值得關注。
由於阿里在背後的技術實踐及支援,Vue.js今年也開始得到越來越多的關注。vue相對於angular1.x的優勢在於輕量、易用、更優異的效能及面向元件化的設計,目前發展態勢也非常好,是移動端開發的一個重要技術選型之一。
標準 & 語言的變化
現在回顧起來,2015年真的是很有意義的一年:這一年是Web的25歲生日,也是js的20歲生日。同時又是ES6標準落地的一年。ES6是迄今為止ECMAScript標準最大的變革(如果不算上胎死腹中的ES4的話),帶來了一系列令開發者興奮的新特性。從目前es的進化速度來看,es後面應該會變成一個個的feature釋出而不是像以前那樣大版本號的方式,所以現在官方也在推薦 ES+年份 這種叫法而不是 ES +版本。
ES2015(ES6) & ES2016(ES7) & TypeScript
6月中ES2015規範正式釋出,從ES2015帶來的這些革命性的新語法來看,JS從此具備了用於開發大型應用的語言的基本要素:原生的mudule支援、原生的class關鍵字、更簡潔的api及語法糖,更穩定的資料型別。而這些new features中,有幾個我認為是會影響整個前端發展程式的:
-
Module & Module Loader
ES2015中加入的原生模組機制支援可謂是意義最重大的feature了,且不說目前市面上五花八門的module/loader庫,各種不同實現機制互不相容也就罷了(其實這也是非常大的問題),關鍵是那些模組定義/裝載 語法都醜到爆炸,但是這也是無奈之舉,在沒有語言級別的支援下,js只能做到這一步,正所謂巧婦難為無米之炊。ES2016中的Module機制借鑑自CommonJS,同時又提供了更優雅的關鍵字及語法(當然也存在一些問題)。遺憾的是同樣有重大價值的Module Loader在2014年底從ES2015草案中移除了,我猜測可能是對於瀏覽器而言Module Loader的支援遭遇了一些技術上的難點,從而暫時性的捨棄了這一feature。但是一個原生支援的模組載入器是非常有意義的,相信它不久後還是會迴歸到ES規範中(目前由WHATWG組織在單獨維護)。 -
Class
準確來說class關鍵字只是一個js裡建構函式的語法糖而已,跟直接function寫法無本質區別。只不過有了Class的原生支援後,js的物件導向機制有了更多的可能性,比如衍生的extends關鍵字(雖然也只是語法糖)。 -
Promise & Reflect API
Promise的誕生其實已經有幾十年了,它被納入ES規範最大意義在於,它將市面上各種非同步實現庫的最佳實踐都標準化了。至於Reflect API,它讓js歷史上第一次具備了超程式設計能力,這一特性足以讓開發者們腦洞大開。
關於ES2016的最重磅的訊息莫過於11月初es標準委員會宣佈將Object.observe從ES2016草案中移除了,儘管它已經是stage2幾乎已經是事實標準。官方給出的解釋是,這3年的時間前端世界變化實在太大,社群已經有了一些更優秀簡潔的實現了(polymer的observe-js),而且React帶來的immutable object在社群的流行使得基於可變資料的Object.observe的處境變的尷尬,O.o再繼續下去的意義不大了。
除此之外,ES2016的相關草案也已經確定了一大部分其他new features。這裡提兩個我比較感興趣的new feature:
-
async/await
寫過C#的同學應該對這兩個關鍵字很熟悉了,async/await是為了更優雅的非同步程式設計做的一個關鍵字級別的封裝,術語叫協程。ES2016中 async/await 實際是對Promise的上層封裝,幾乎同步的寫法寫非同步比Promise更優雅更簡單,非常值得期待。 -
decorator
字面意思是裝飾器,其實等同於Java裡面的註解。註解機制對於大型應用的開發的作用想必不用我過多贅述了。用過的同學都說好。
目前ES2015/ES2016都有了比較優秀的轉譯器支援(沒錯我說的是babel),但是也不是all features supported,嘗新的過程中需要注意。
至於Typescript,你可以將它理解成加入了靜態型別的js的超集。不過我對於這種轉譯型語言一直不感冒(包括快死掉的CoffeeScript),有興趣同學自己去了解下吧。。
WebAssembly
WebAssembly選擇了跟ES2015在同一天釋出,其專案領頭人是大名鼎鼎的js之父Brendan Eich。WebAssembly旨在解決js作為解釋性語言的先天效能缺陷,試圖通過在瀏覽器底層加入編譯機制從而提高js效能。這個事情跟當時V8做的類似(有興趣的同學可以去了解下JIT),V8也因此一躍成為世界上跑的最快的js引擎。但是由於js是弱型別的動態語言,V8很快就觸碰到了效能優化的天花板,因為很多場景下還是免不了recompile的過程。WebAssembly提供工具將各種語言轉換成特定的位元組碼,瀏覽器直接面向位元組碼編譯程式。其實在此之前,firefox已經搞過asm.js做類似的事情,只不過WebAssembly的方案更激進。有人認為WebAssembly可能是2016年最大的黑馬,如果wa能發展起來,若干年後我們看js編寫的應用會像現在看組合語言寫出的大型程式的感覺。WebAssembly專案目前由蘋果、谷歌、微軟、Mozila四大瀏覽器廠商共同推進,還是非常值得期待的(寫不下去了我決定回去翻開我那本落灰的編譯原理。。)。
Web Components
webcomponents規範起草於2013年,w3c標準委員會意圖提供一種瀏覽器級別的元件化解決方案,通過瀏覽器的原生支援定義一種標準化的元件開發方式。webcomponents提出之際引發了整個前端圈的躁動,大家似乎在跨框架的元件化方案上看到了曙光。但是前端這圈子發展實在太特麼快了,在當前這個時間點,webcomponents也遭遇到了跟Object.observe相似的尷尬處境。我們先來看看webcomponents的幾個核心特性:
- Shadow DOM
- Custom Element
- Template Element
- HTML Imports
其中1、4現在都能很容易的通過自動化的工程手段解決了(shadow dom對應的是scoped css),而自定義標籤這種事情不論是React還是Angular這類元件框架都能輕鬆解決,那麼我用你webcomponents的理由呢?
另外webcomponents將目標對準的是HTML體系下的元件化,這一點跟React比就相對狹隘了(但是這並不表明React把戰線拉的那麼長就不會有問題)。
不過原生支援的跨框架的元件還是有存在的意義的,比如基礎元件庫,只是在當前來看web components發展還是有點營養不良。期待2016年能有實質上的突破吧。
架構的變化
2015年出現的新的技術及思路,影響最大的就是技術選型及架構了。我們可以從下面幾點來看看它對前端架構上都有哪些影響。
元件化
React的風靡使得元件化的開發模式越來越被廣大開發者關注。首先要肯定的是,元件化是一個非常值得去做的事情,它在工程上會大大提升專案的可維護性及擴充性,同時會帶來一些程式碼可複用的附加效果。但這裡要強調的一點是,元件化的指導策略一定是分治(分而治之)而不是複用,分治的目的是為了使得元件之間解耦跟正交,從而提高可維護性及多人協同開發效率。如果以複用為指導原則那麼元件最後一定會發展到一個配置繁雜程式碼臃腫的狀態。如果以元件的形態劃分,可以分為兩個型別:基礎控制元件和業務元件。基礎控制元件不應包含業務邏輯不然達不到拿來即用的效果,因此它也會表現出可複用的價值,但是根本還是為了提高業務元件的可維護性。至於業務元件,可複用的價值就很低了。
-
元件化指的是什麼
元件化這個詞,在UI這一層通常指“標籤化”,也就是把大塊的業務介面,拆分成若干小塊,然後進行組裝。
狹義的元件化一般是指標籤化,也就是以自定義標籤(自定義屬性)為核心的機制。這也是我們通常認識的元件。
廣義的元件化包括對資料邏輯層業務梳理,形成不同層級的能力封裝。它不一定是一個自定義語義標籤:它可以是一個包含邏輯(js)、樣式(css)、模版(html)的功能完備的結構單元,也就是我們常“口口相傳”的模組(從術語準確性的角度來看模組這個描述並不合適,應該稱之為元件);它也可以是一個單純的js,比如http元件這種純邏輯單元。嚴格從概念上來講,css跟html是不具備單獨/組合成一個元件的,它們不具備描述邏輯的能力(非圖靈完備)。從這個層面來看,全元件化是沒有任何問題及疑義的。 -
是否需要全元件化
我們通常說的元件指的是狹義上的元件,而且往往我們理解的全元件化也是建立在狹義的元件基礎上的,
代表框架是React。React+Flux體系下,它提倡儘可能將頁面作細粒度的元件拆分,元件的資料全部由父級元件通過props傳遞而來。這本身是一件非常有價值的事情,能有效的確保應用狀態的穩定及可預測性,但是應用一旦複雜龐大起來,元件樹變得“枝繁葉茂”導致葉子節點層級過深,當出現資料問題時,我們必須一層層的回溯來定位bug。而且元件樹過於龐大也會增加元件之間的通訊負擔。從狹義的元件來看,我對全元件化是存懷疑態度的,工程上的成本太高是最大的問題,而且大部分開發者很難拿捏合適的元件粒度,容易出現過細/過粗的拆分。很多場景其實並不適合實現成狹義上的元件,它以零散的模板的方式存在更合適。
但是如果從廣義的元件來看,全元件的意義是很大的,我們需要通過拆分頁面邏輯區塊的方式實現程式的解耦,從而提升應用的可維護性。
綜合來看,我覺得工程上更具可行的全元件化方案應該是:細粒度的基礎元件庫 + 粗粒度的模板/元件。
工程化
工程化是近年前端提到最多的問題之一,而且個人認為是當前前端發展階段最有價值的問題,也是前端開發通往工業化時代的必經之路。這裡不贅述,有興趣的同學看我前陣子整理的一篇文章前端工程化知識點回顧
應用架構層 MVVM & Flux
MVVM想必大部分前端都耳熟能詳了,代表框架是angular、vue、avalon。angular在1.2版本之後加入了controllerAs語法,使得controller可以變成一個真正意義上的VM,angular整個架構也才真正能稱之為嚴格的MVVM(之前只能說是帶有雙向繫結的MVC/MVP)。
Flux是facebook隨React一併推出的新的(準確來說其實是改進的,並非原創)架構模型,核心概念是單向資料流。Flux實質上就是一個演進版的中介者模式,不同的是它同時包裝了action、store、dispatcher、view等概念。關於Flux對應用分層、資料在不同層之間只能單向流轉的方式我是很贊成的。應用的分層在業務稍複雜的應用中都是很有必要的,它更利於應用的伸縮及擴充,副作用是會帶來一定的複雜度(在我看來這點複雜度根本就可以忽略不計)。
今年被黑的最多的前端主流框架莫過於angular了。老實講前端圈真的挺善變的,去年各種大會都在分享angular黑jquery,今年就變成了都在分享react黑angular了。黑的點大致有三:
- angular的部分實現太low
- 太多Java身上帶來的臭毛病(並沒有在黑Java)
- mvvm自身的缺陷
第一點第二點我並無異議。angular的髒值檢測機制相對於其他mvvm框架的雙向繫結實現方式確實不太優雅,同樣有硬傷的還有失敗的模組語法及過多過於複雜的概念。但是對於第三點,我有不同的看法。
大多數人黑mvvm會以Facebook那張經典的flux vs mvc的圖為論據,對於雙向繫結造成的資料流紊亂及應用狀態的不確定導致問題定位困難的觀點我是認同的,這一點我也有切身體會,但是單純的這一點就足以否定mvvm麼?就說flux比mvvm高明?
MVVM在富表格型(自造的詞
業務資料層 Relay & falcor
這一層對大部分前端來說可能是比較新的概念,其實我們可以這樣理解:在一個完整的應用中,業務資料層指的就是資料來源,在angular體系中可以等同於ngResource模組(準確來說應該是$http)。
Relay是f家推出的在react上應用GraphQL的框架,它的大致思路是:前端通過在應用中定義一系列的schema來宣告需要的介面資料結構,後端配合GraphQL引擎返回相應的資料。整個事情對於前端來說意義簡直是跨時代的,工業化典範!不僅能極大提升前後端協同的開發效率,還能增加前端對於應用完整的掌控力。但是目前來看問題就是實施過於複雜,而且還得後端服務支援,工程成本太高,這一點上Meteor顯然做的更好。
falcor則是Netflix出品的一個資料拉取庫,核心理念是單一資料來源,跟Redux的單store概念一致。用法跟Realy類似,也需要前端定義資料schema。
另外還有一個新的W3C標準api:fetch,它的級別等同於XMLHttpRequest,旨在提供比ajax更優雅的資源獲取方式,目前幾個主流瀏覽器支援的都還不錯,也有官方維護的polyfill,幾乎可以確定是未來的主流資料請求api。
業務資料層是前端應用中比較新的概念,它的多元化主要會影響到應用的架構設計,這裡不細講後面再來說。
新的程式設計正規化
函數語言程式設計(FP)
函數語言程式設計(functional programming)是近年比較火爆的一個程式設計正規化,FP基於lambda演算,與以圖靈機為基礎的指令式程式設計(Java、C++)有著明顯的差異。lambda演算更關注輸入輸出,更符合自然行為場景,所以看上去更適合事件驅動的web體系,這點我也認同。但問題是,太多開發者看到redux那麼火爆就急著學redux用js去玩函式式,我覺得這個有待商榷。js作為一個以基於函式(scheme,父親)跟基於物件(Self,母親)的程式語言為藍本設計然後語法又靠近Java(隔壁老王)的“混血”語言,你非得用它去寫函式式,是不是過於一廂情願?尤其是在現在瀏覽器還不支援尾呼叫優化的情況下,你讓那激增的呼叫棧可如何是好
函式式響應型程式設計(FRP)
函式式響應型程式設計(functional reactive programming)不是一個新概念,但也不過是近兩年才引入到前端領域的,代表類庫就是ng2在用的rxjs。FRP關注的是事件及對應的資料流,你可以把它看作是一個基於事件匯流排(event bus)的觀察者模式,它主要適用於以GUI為核心的互動軟體中。但FRP最大的困難之處在於,如果你想使用這樣的程式設計正規化,那麼你的整個系統必須以reactive為中心來規劃。目前微軟維護的ReactiveX專案已經有各種語言的實現版本,有興趣的同學可以去了解下。
工具鏈的變化
去年最主流的前端構建工具還是grunt&gulp,2015年隨著react的崛起和web標準的快速推進,一切又有了新的變化。
webpack & browserify & jspm
webpack跟browserify本質上都是module bundler,差異點在於webpack提供更強大的loader機制讓其更變得更加靈活。當然,webpack的流行自然還是離不開背後的react跟facebook(可見有個強大的乾爹多麼重要)。但是從現在HTTP/2標準的應用及實施進展來看,webpack/browserify這種基於bundle的打包工具也面臨著被歷史車輪碾過的危機,相對的基於module loader的jspm反而更具前景(雖然現在使用前兩者的開發者都多於jspm)。
PostCSS & cssnext
PostCSS作為新一代的css處理器大有取Sass/Less而代之的趨勢,Bootstrap v5也有著基於PostCSS去開發的計劃。但從本質來講它又不算一個處理器,它更像是一個外掛平臺,能通過配置各種外掛從而實現前處理器跟後處理器的效果。
cssnext官方口號是“使用來自未來的語法開發css,就在今天!”,但是cssnext又不是css4,它是一個能讓開發者現在就享受最新的css語法(包括自定義屬性、css變數等)的轉換工具。這一塊筆者還沒有過具體實踐,暫不多言。
寫在最後
從前端的發展現狀來看,未來理想的前端技術架構應該是每一層都是可組裝的,框架這種重型組合的適用場景會越來越侷限。原因在於各部件不可拆卸會增加架構的升級代價同時會限制應用的靈活性。舉個例子,我有一套面向pc端的後臺管控平臺的架構,view層採用angular開發,哪天我要遷移到移動端來,angular效能不行啊,我換成vue就好了。哪天覺得ajax的寫法太挫,把http層替換成fetch就好了。又有一天後端的GranphQL平臺搭好了,我把ngResource換成relay就OK了。
這種理想的方式當然是完全正確的方向,但是目前來看它對 開發者/架構師 的要求還是太高,工業級別上一套帶有約束性的框架還是有相當的需求的(特別是當團隊開發者的水平良莠不齊時。當然我覺得更正確的方式是流程上有一套完整的自動化方案用於確保團隊提交的程式碼質量,只是目前基於動態分析的程式碼質量檢測工具還沒有出現,而且估計很長一段時間內都不會有)。雖然美好但是組合的方式也不是沒有問題,各種五花八門的搭配容易造成社群的分化跟內耗,一定程度上不利於整個生態圈的發展。
近年前端生態的野蠻發展影響最大的應該就是新產品的技術選型了,亂花迷人眼,我們很難設計出一套適應大部分場景、而且短時間內不會被淘汰的架構。前端的變化太快通常會導致一些技術決策的反覆,今天的最佳實踐很可能明天就被視為反模式。難道最合適的態度是各種保留各種觀望,以不變應萬變?在這一點上即使如我這般在技術上一向激進的人都有點畏手畏腳了。那句話怎麼說的來著?從來沒有哪個圈子像今天的前端一樣混亂又欣欣向榮了。有人說2015年或許是大前端時代的元年,目前看來,如果不是2015,那麼它也一定會是2016年。
最後引用計子winter的一句話作為結語吧:
前端一直是一個變化很快的職能,它太年輕,年輕意味著可能性和機會,也意味著不成熟和痛苦。我經常擔心的事情就是,很可能走到最後,我們會發現,我們做了很多,卻還是一無所獲。所幸至今回顧,每年還是總有點不同,也算給行業貢獻了些經驗值吧。
相關文章
- 2017 前端技術發展回顧前端
- 【直播回顧】參與ArkUI,共建OpenHarmony繁榮生態UI
- 【譯】2018 年前端開發回顧前端
- 10月回顧 | Apache SeaTunnel社群動態與進展一覽Apache
- 雲端計算“黃金十年”發展回顧
- 2021年前端回顧前端
- 2021年JavaScript業界發展回顧 - risingstarsJavaScript
- 前端工作兩年多的回顧前端
- 開源生態發展合作倡議
- 圓滿落幕!回顧 eBPF 技術的發展與挑戰eBPF
- 一張圖回顧Android七年發展程式–資訊圖Android
- Rust 1.0釋出一週年,發展回顧與總結Rust
- 谷歌回顧資料中心7年發展:能效大幅提高谷歌
- [譯] 2018 前端全面回顧前端
- 精讀《2021 前端新秀回顧》前端
- 回顧兩年前整理的前端規範前端
- 2015年商用無人機市場回顧無人機
- 直播回顧|TGIP-CN 036:Apache Pulsar 最新技術進展與動態Apache
- 以太坊學習筆記————4、以太坊發展歷史回顧筆記
- 回顧2013年中國數字營銷行業發展行業
- RedHat 產品總監回顧容器與 PaaS 的發展歷程Redhat
- 回顧與前瞻:百度權重API介面的發展之路API
- Voodoo發行主管回顧超休閒遊戲發展強勁的一年Odoo遊戲
- 國產作業系統生態發展趨勢作業系統
- 國內外大模型生態發展報告!大模型
- 回顧中國網路安全發展史,喜迎建黨101週年
- 空中WiFi發展十週年回顧 航空公司名利雙收WiFi
- 工信部:2014年彩電行業發展回顧及展望行業
- 一文回顧騰訊數字生態大會·微搭低程式碼專場
- 視訊回顧|Pulsar Summit Asia 2021,案例、運維、生態乾貨不斷MIT運維
- 《Days Gone》開發商Bend Studio回顧29年遊戲作品發展歷程Go遊戲
- 回顧2014展望2015-BattleHeartBAT
- 前端面試題 回顧與複習(更新中)前端面試題
- 前端面試回顧(1)---javascript的物件導向前端面試JavaScript物件
- 而立之年——回顧我的前端轉行之路前端
- 前端基礎重點回顧2: HTTP協議前端HTTP協議
- 回顧蘋果十年發展歷程 因為提前拿到iPhone8蘋果iPhone
- 回顧2011年9種程式語言的發展趨勢