前言
近年來肝劲,隨著瀏覽器性能的提升與移動互聯(lián)網(wǎng)浪潮的洶涌而來迁客,Web前端開發(fā)進入了高歌猛進,日新月異的時代辞槐。這是最好的時代掷漱,我們永遠在前行,這也是最壞的時代榄檬,無數(shù)的前端開發(fā)框架卜范、技術體系爭妍斗艷,讓開發(fā)者們陷入困惑鹿榜,乃至于無所適從海雪。
Web前端開發(fā)可以追溯于1991年蒂姆·伯納斯-李公開提及HTML描述锦爵,而后1999年W3C發(fā)布HTML4標準,這個階段主要是BS架構奥裸,沒有所謂的前端開發(fā)概念险掀,網(wǎng)頁只不過是后端工程師的順手之作,服務端渲染是主要的數(shù)據(jù)傳遞方式湾宙。接下來的幾年間隨著互聯(lián)網(wǎng)的發(fā)展與REST等架構標準的提出迷郑,前后端分離與富客戶端的概念日漸為人認同,我們需要在語言與基礎的API上進行擴充创倔,這個階段出現(xiàn)了以jQuery為代表的一系列前端輔助工具嗡害。2009年以來,智能手機開發(fā)普及畦攘,移動端大浪潮勢不可擋霸妹,SPA單頁應用的設計理念也大行其道,相關聯(lián)的前端模塊化知押、組件化叹螟、響應式開發(fā)、混合式開發(fā)等等技術需求甚為迫切台盯。這個階段催生了Angular 1罢绽、Ionic等一系列優(yōu)秀的框架以及AMD、CMD静盅、UMD與RequireJS良价、SeaJS等模塊標準與加載工具,前端工程師也成為了專門的開發(fā)領域蒿叠,擁有獨立于后端的技術體系與架構模式明垢。
而近兩年間隨著Web應用復雜度的提升、團隊人員的擴充市咽、用戶對于頁面交互友好與性能優(yōu)化的需求痊银,我們需要更加優(yōu)秀靈活的開發(fā)框架來協(xié)助我們更好的完成前端開發(fā)。這個階段涌現(xiàn)出了很多關注點相對集中施绎、設計理念更為優(yōu)秀的框架溯革,譬如 React
、 VueJS
谷醉、 Angular2
等組件框架允許我們以聲明式編程來替代以DOM操作為核心的命令式編程致稀,加快了組件的開發(fā)速度,并且增強了組件的可復用性與可組合性孤紧。而遵循函數(shù)式編程的 Redux
與借鑒了響應式編程理念的 MobX
都是非常不錯的狀態(tài)管理輔助框架豺裆,輔助開發(fā)者將業(yè)務邏輯與視圖渲染剝離拒秘,更為合理地劃分項目結構号显,更好地貫徹單一職責原則與提升代碼的可維護性臭猜。在項目構建工具上,以 Grunt
押蚤、 Gulp
為代表的任務運行管理與以 Webpack
蔑歌、 Rollup
、 JSPM
為代表的項目打包工具各領風騷揽碘,幫助開發(fā)者更好的搭建前端構建流程次屠,自動化地進行預處理雳刺、異步加載本昏、Polyfill宿稀、壓縮等操作越庇。而以NPM/Yarn為代表的依賴管理工具一直以來保證了代碼發(fā)布與共享的便捷唯欣,為前端社區(qū)的繁榮奠定了重要基石萍聊。
紛擾
分久必合,合久必分啊预烙,無論是前端開發(fā)中各個模塊的分割還是所謂的前后端分離谴分,都不能形式化的單純按照語言或者模塊來劃分钞馁,還是需要兼顧功能,合理劃分绩鸣。
任何一個編程生態(tài)都會經(jīng)歷三個階段:
- 第一個是原始時期蓖康,由于需要在語言與基礎的API上進行擴充垒手,這個階段會催生大量的Tools蒜焊。
- 第二個階段,隨著做的東西的復雜化科贬,需要更多的組織泳梆,會引入大量的設計模式啊,架構模式的概念,這個階段會催生大量的Frameworks优妙。
- 第三個階段乘综,隨著需求的進一步復雜與團隊的擴充,就進入了工程化的階段鳞溉,各類分層MVC瘾带,MVP鼠哥,MVVM之類熟菲,可視化開發(fā),自動化測試朴恳,團隊協(xié)同系統(tǒng)抄罕。這個階段會出現(xiàn)大量的小而美的Library。
本文的主旨希望能夠盡可能地脫離工具的束縛于颖,回歸到前端工程化的本身呆贿,回歸到語言的本身,無論React森渐、AngularJS做入、VueJS,它們更多的意義是輔助開發(fā)同衣,為不同的項目選擇合適的工具竟块,而不是執(zhí)念于工具本身∧推耄總結而言浪秘,目前前端工具化已經(jīng)進入到了非常繁榮的時代,隨之而來很多前端開發(fā)者也甚為苦惱埠况,疲于學習耸携。工具的變革會非常迅速,很多優(yōu)秀的工具可能都只是歷史長河中的一朵浪花辕翰,而蘊藏其中的工程化思維則會恒久長存夺衍。無論你現(xiàn)在使用的是React還是Vue還是Angular 2或者其他優(yōu)秀的框架,都不應該妨礙我們?nèi)チ私鈬L試其他喜命。
工具化
我們學習的速度已經(jīng)跟不上新框架新概念涌現(xiàn)的速度刷后,用于學習上的成本遠大于實際開發(fā)項目的成本。我們不一定要去用最新最優(yōu)秀的工具渊抄,但是我們有了更多的選擇余地尝胆,相信這一點對于大部分非處女座人士而言都是喜訊。
工具化是有意義的护桦。工具的存在是為了幫助我們應對復雜度含衔,在技術選型的時候我們面臨的抽象問題就是應用的復雜度與所使用的工具復雜度的對比。工具的復雜度是可以理解為是我們?yōu)榱颂幚韱栴}內(nèi)在復雜度所做的投資。為什么叫投資贪染?那是因為如果投的太少缓呛,就起不到規(guī)模的效應,不會有合理的回報杭隙。這就像創(chuàng)業(yè)公司拿風投哟绊,投多少是很重要的問題。如果要解決的問題本身是非常復雜的痰憎,那么你用一個過于簡陋的工具應付它票髓,就會遇到工具太弱而使得生產(chǎn)力受影響的問題。反之铣耘,是如果所要解決的問題并不復雜洽沟,但你卻用了很復雜的框架,那么就相當于殺雞用牛刀蜗细,會遇到工具復雜度所帶來的副作用蜈项,不僅會失去工具本身所帶來優(yōu)勢吹截,還會增加各種問題弛秋,例如培訓成本驱入、上手成本,以及實際開發(fā)效率等吊骤。
所謂GUI應用程序架構缎岗,就是對于富客戶端的代碼組織/職責劃分∷縱覽這十年內(nèi)的架構模式變遷密强,大概可以分為MV與Unidirectional兩大類,而Clean Architecture則是以嚴格的層次劃分獨辟蹊徑蜗元。從MVC到MVP的變遷完成了對于View與Model的解耦合或渤,改進了職責分配與可測試性。而從MVP到MVVM奕扣,添加了View與ViewModel之間的數(shù)據(jù)綁定薪鹦,使得View完全的無狀態(tài)化。最后惯豆,整個從MV到Unidirectional的變遷即是采用了消息隊列式的數(shù)據(jù)流驅動的架構池磁,并且以Redux為代表的方案將原本MV*中碎片化的狀態(tài)管理變?yōu)榱私y(tǒng)一的狀態(tài)管理,保證了狀態(tài)的有序性與可回溯性楷兽。 具體到前端的衍化中地熄,在Angular 1興起的時代實際上就已經(jīng)開始了從直接操作Dom節(jié)點轉向以狀態(tài)/數(shù)據(jù)流為中心的變化,jQuery 代表著傳統(tǒng)的以 DOM 為中心的開發(fā)模式芯杀,但現(xiàn)在復雜頁面開發(fā)流行的是以 React 為代表的以數(shù)據(jù)/狀態(tài)為中心的開發(fā)模式端考。應用復雜后雅潭,直接操作 DOM 意味著手動維護狀態(tài),當狀態(tài)復雜后却特,變得不可控扶供。React 以狀態(tài)為中心,自動幫我們渲染出 DOM裂明,同時通過高效的 DOM Diff 算法椿浓,也能保證性能。
工具化的不足:抽象漏洞定理
抽象漏洞定理是Joel在2002年提出的闽晦,所有不證自明的抽象都是有漏洞的扳碍。抽象泄漏是指任何試圖減少或隱藏復雜性的抽象,其實并不能完全屏蔽細節(jié)尼荆,試圖被隱藏的復雜細節(jié)總是可能會泄漏出來左腔。抽象漏洞法則說明:任何時候一個可以提高效率的抽象工具唧垦,雖然節(jié)約了我們工作的時間捅儒,但是,節(jié)約不了我們的學習時間振亮。我們在上一章節(jié)討論過工具化的引入實際上以承受工具復雜度為代價消弭內(nèi)在復雜度巧还,而工具化濫用的結局即是工具復雜度與內(nèi)在復雜度的失衡。
談到這里我們就會明白坊秸,不同的項目具備不同的內(nèi)在復雜度麸祷,一刀切的方式評論工具的好壞與適用簡直耍流氓,而且我們不能忽略項目開發(fā)人員的素質褒搔、客戶或者產(chǎn)品經(jīng)理的素質對于項目內(nèi)在復雜度的影響阶牍。對于典型的小型活動頁,譬如某個微信H5宣傳頁星瘾,往往注重于交互動畫與加載速度走孽,邏輯復雜度相對較低,此時Vue這樣漸進式的復雜度較低的庫就大顯身手琳状。而對于復雜的Web應用磕瓷,特別是需要考慮多端適配的Web應用,盡量使用React這樣相對規(guī)范嚴格的庫念逞。
React困食?Vue?Angular 2翎承?
React硕盹,Vue,Angular 2都是非常優(yōu)秀的庫與框架叨咖,它們在不同的應用場景下各自具有其優(yōu)勢瘩例。Vue最大的優(yōu)勢在于其漸進式的思想與更為友好的學習曲線待讳,Angular 2最大的優(yōu)勢其兼容并包形成了完整的開箱即用的All-in-one框架,而這兩點優(yōu)勢在某些情況下反而也是其劣勢仰剿,也是部分人選用React的理由创淡。很多對于技術選型的爭論乃至于謾罵,不一定是工具的問題南吮,而是工具的使用者并不能正確認識自己或者換位思考他人所處的應用場景琳彩,最終吵的驢唇不對馬嘴。
小而美的視圖層
React 與 VueJS 都是所謂小而美的視圖層Library部凑,而不是Angular 2這樣兼容并包的Frameworks露乏。任何一個編程生態(tài)都會經(jīng)歷三個階段,第一個是原始時期涂邀,由于需要在語言與基礎的API上進行擴充瘟仿,這個階段會催生大量的Tools。第二個階段比勉,隨著做的東西的復雜化劳较,需要更多的組織,會引入大量的設計模式啊浩聋,架構模式的概念观蜗,這個階段會催生大量的Frameworks。第三個階段衣洁,隨著需求的進一步復雜與團隊的擴充墓捻,就進入了工程化的階段,各類分層MVC坊夫,MVP砖第,MVVM之類,可視化開發(fā)环凿,自動化測試梧兼,團隊協(xié)同系統(tǒng)。這個階段會出現(xiàn)大量的小而美的Library拷邢。
React 并沒有提供很多復雜的概念與繁瑣的API袱院,而是以最少化為目標,專注于提供清晰簡潔而抽象的視圖層解決方案瞭稼,同時對于復雜的應用場景提供了靈活的擴展方案忽洛,典型的譬如根據(jù)不同的應用需求引入MobX/Redux這樣的狀態(tài)管理工具。React在保證較好的擴展性环肘、對于進階研究學習所需要的基礎知識完備度以及整個應用分層可測試性方面更勝一籌欲虚。不過很多人對React的意見在于其陡峭的學習曲線與較高的上手門檻,特別是JSX以及大量的ES6語法的引入使得很多的傳統(tǒng)的習慣了jQuery語法的前端開發(fā)者感覺學習成本可能會大于開發(fā)成本悔雹。與之相比Vue則是典型的所謂漸進式庫复哆,即可以按需漸進地引入各種依賴欣喧,學習相關地語法知識。比較直觀的感受是我們可以在項目初期直接從CDN中下載Vue庫梯找,使用熟悉的腳本方式插入到HTML中唆阿,然后直接在script標簽中使用Vue來渲染數(shù)據(jù)。隨著時間的推移與項目復雜度的增加锈锤,我們可以逐步引入路由驯鳖、狀態(tài)管理、HTTP請求抽象以及可以在最后引入整體打包工具久免。這種漸進式的特點允許我們可以根據(jù)項目的復雜度而自由搭配不同的解決方案浅辙,譬如在典型的活動頁中,使用Vue能夠兼具開發(fā)速度與高性能的優(yōu)勢阎姥。不過這種自由也是有利有弊记舆,所謂磨刀不誤砍材工,React相對較嚴格的規(guī)范對團隊內(nèi)部的代碼樣式風格的統(tǒng)一呼巴、代碼質量保障等會有很好的加成泽腮。
一言蔽之,Vue會更容易被純粹的前端開發(fā)者的接受伊磺,畢竟從直接以HTML布局與jQuery進行數(shù)據(jù)操作切換到指令式的支持雙向數(shù)據(jù)綁定的Vue代價會更小一點盛正,特別是對現(xiàn)有代碼庫的改造需求更少删咱,重構代價更低屑埋。而React及其相對嚴格的規(guī)范可能會更容易被后端轉來的開發(fā)者接受,可能在初學的時候會被一大堆概念弄混痰滋,但是熟練之后這種嚴謹?shù)慕M件類與成員變量/方法的操作會更順手一點摘能。便如Dan Abramov所述,F(xiàn)acebook推出React的初衷是為了能夠在他們數(shù)以百計的跨平臺子產(chǎn)品持續(xù)的迭代中保證組件的一致性與可復用性敲街。
函數(shù)式思維:抽象與直觀
近年來隨著應用業(yè)務邏輯的日益復雜與并發(fā)編程的大規(guī)模應用团搞,函數(shù)式編程在前后端都大放異彩。軟件開發(fā)領域有一句名言:可變的狀態(tài)是萬惡之源多艇,函數(shù)式編程即是避免使用共享狀態(tài)而避免了面向對象編程中的一些常見痛處逻恐。函數(shù)式編程不可避免地會使得業(yè)務邏輯支離破碎,反而會降低整個代碼的可維護性與開發(fā)效率峻黍。與React相比复隆,Vue則是非常直觀的代碼架構,每個Vue組件都包含一個script標簽姆涩,這里我們可以顯式地聲明依賴挽拂,聲明操作數(shù)據(jù)的方法以及定義從其他組件繼承而來的屬性。而每個組件還包含了一個template標簽骨饿,等價于React中的render函數(shù)亏栈,可以直接以屬性方式綁定數(shù)據(jù)台腥。最后,每個組件還包含了style標簽而保證了可以直接隔離組件樣式绒北。我們可以先來看一個典型的Vue組件黎侈,非常直觀易懂,而兩相比較之下也有助于理解React的設計思想闷游。
在現(xiàn)代瀏覽器中蜓竹,對于JavaScript的計算速度遠快于對DOM進行操作,特別是在涉及到重繪與重渲染的情況下储藐。并且以JavaScript對象代替與平臺強相關的DOM俱济,也保證了多平臺的支持,譬如在ReactNative的協(xié)助下我們很方便地可以將一套代碼運行于iOS钙勃、Android等多平臺蛛碌。總結而言辖源,JSX本質上還是JavaScript蔚携,因此我們在保留了JavaScript函數(shù)本身在組合、語法檢查克饶、調試方面優(yōu)勢的同時又能得到類似于HTML這樣聲明式用法的便利與較好的可讀性酝蜒。
前后端分離與全棧:技術與人
前后端分離與全棧并不是什么新鮮的名詞,都曾引領一時風騷矾湃。Web前后端分離優(yōu)勢顯著亡脑,對于整個產(chǎn)品的開發(fā)速度與可信賴性有著很大的作用。全棧工程師對于程序員自身的提升有很大意義邀跃,對于項目的初期速度有一定增速霉咨。如果劃分合理的話能夠促進整個項目的全局開發(fā)速度與可信賴性,但是如果劃分不合理的話只會導致項目接口混亂拍屑,一團亂麻途戒。
我們常說的前后端分離會包含以下兩個層面:
- 將原本由服務端負責的數(shù)據(jù)渲染工作交由前端進行,并且規(guī)定前端與服務端之間只能通過標準化協(xié)議進行通信僵驰。
- 組織架構上的分離喷斋,由早期的服務端開發(fā)人員順手去寫個界面轉變?yōu)橥暾那岸藞F隊構建工程化的前端架構。
前后端分離本質上是前端與后端適用不同的技術選型與項目架構蒜茴,不過二者很多思想上也是可以融會貫通星爪,譬如無論是響應式編程還是函數(shù)式編程等等思想在前后端皆有體現(xiàn)。而全棧則無論從技術還是組織架構的劃分上似乎又回到了按照需求分割的狀態(tài)矮男。不過呢移必,我們必須要面對現(xiàn)實,很大程度的工程師并沒有能力做到全棧毡鉴,這一點不在于具體的代碼技術崔泵,而是對于前后端各自的理解秒赤,對于系統(tǒng)業(yè)務邏輯的理解。如果我們分配給一個完整的業(yè)務塊憎瘸,同時入篮,那么最終得到的是無數(shù)個碎片化相互獨立的系統(tǒng)。
相輔相成的客戶端渲染與服務端渲染
最初的網(wǎng)頁是數(shù)據(jù)幌甘、模板與樣式的混合潮售,即以經(jīng)典的APS.NET、PHP與JSP為例锅风,是由服務端的模板提供一系列的標簽完成從業(yè)務邏輯代碼到頁面的流動酥诽。所以,前端只是用來展示數(shù)據(jù)皱埠,所謂附庸之徒肮帐。而隨著Ajax技術的流行,將WebAPP也視作CS架構边器,抽象來說训枢,會認為CS是客戶端與服務器之間的雙向通信,而BS是客戶端與服務端之間的單向通信忘巧。換言之恒界,網(wǎng)頁端本身也變成了有狀態(tài)。從初始打開這個網(wǎng)頁到最終關閉砚嘴,網(wǎng)頁本身也有了一套自己的狀態(tài)十酣,而擁有這種變化的狀態(tài)的基礎就是AJAX,即從單向通信變成了雙向通信枣宫。
而近兩年來隨著React的流行服務端渲染的概念重回人們的視線婆誓。需要強調的是,我們現(xiàn)在稱之為服務端渲染的技術并非傳統(tǒng)的以JSP也颤、PHP為代表的服務端模板數(shù)據(jù)填充,更準確的服務端渲染作用的描述是對于客戶端應用的預啟動與預加載郁轻。我們千方百計將客戶端代碼拉回到服務端運行并不是為了替換現(xiàn)有的API服務器翅娶,并且在服務端運行過的代碼同樣需要在客戶端重新運行。
引入服務端渲染帶來的優(yōu)勢主要在于以下三個方面:
對瀏覽器兼容性的提升好唯,目前React竭沫、Angular、Vue等現(xiàn)代Web框架紛紛放棄了對于舊版本瀏覽器的支持骑篙,引入服務端渲染之后至少對于使用舊版本瀏覽器的用戶能夠提供更加友好的首屏展示蜕提,雖然后續(xù)功能依然不能使用。
對搜索引擎更加友好靶端,客戶端渲染意味著整體的渲染用腳本完成谎势,這一點對于爬蟲并不友好凛膏。雖然現(xiàn)代爬蟲往往也會通過內(nèi)置自動化瀏覽器等方式支持腳本執(zhí)行,但是這樣無形會加重很多爬蟲服務器的負載脏榆,因此Google這樣的大型搜索引擎在進行網(wǎng)頁索引的時候還是依賴于文檔本身猖毫。如果你希望提升在搜索引擎上的排行,讓你的網(wǎng)站更方便地被搜索到须喂,那么支持服務端渲染是個不錯的選擇吁断。
整體加載速度與用戶體驗優(yōu)化,在首屏渲染的時候坞生,服務端渲染的性能是遠快于客戶端渲染的仔役。不過在后續(xù)的頁面響應更新與子視圖渲染時,受限于網(wǎng)絡帶寬與重渲染的范疇是己,服務端渲染是會弱于客戶端渲染骂因。另外在服務端渲染的同時,我們也會在服務端抓取部分應用數(shù)據(jù)附加到文檔中赃泡,在目前HTTP/1.1仍為主流的情況下可以減少客戶端的請求連接數(shù)與時延寒波,讓用戶更快地接觸到所需要的應用數(shù)據(jù)。
總結而言升熊,服務端渲染與客戶端渲染是相輔相成的俄烁,在React等框架的協(xié)助下我們也可以很方便地為開發(fā)階段的純客戶端渲染應用添加服務端渲染支持。
項目中的全棧工程師:技術全棧级野,需求隔離页屠,合理分配
全棧工程師對于個人發(fā)展有很大的意義,對于實際的項目開發(fā)蓖柔,特別是中小創(chuàng)公司中以進度為第一指揮棒的項目而言更具有非常積極的意義辰企。但是全棧往往意味著一定的Tradeoff,步子太大况鸣,容易扯著蛋牢贸。任何技術架構和流程的調整,最好都不要去違背康威定律镐捧,即設計系統(tǒng)的組織潜索,其產(chǎn)生的設計等同于組織之內(nèi)、組織之間的溝通結構懂酱。有些全棧的結果就是強行按照功能來分配任務竹习,即最簡單的來說可能把登錄注冊這一塊從數(shù)據(jù)庫設計、服務端接口到前端界面全部分配給一個人或者一個小組完成列牺。然后這個具體的執(zhí)行者整陌,因為其總體負責從上到下的全部邏輯,在很多應該規(guī)范化的地方,特別是接口定義上就會為了求取速度而忽略了必要的規(guī)范泌辫。最終導致整個系統(tǒng)支離破碎成一個又一個的孤島随夸,不同功能塊之間表述相同意義的變量命名都能發(fā)生沖突,各種奇形怪狀的id甥郑、uuid逃魄、{resource}_id令人眼花繚亂。
現(xiàn)代經(jīng)濟發(fā)展的一個重要特征就是社會分工日益精細明確澜搅,想要成為無所不知的通才不過南柯一夢伍俘。在自己的小團隊中應該提倡職位輪替,一般某個項目周期完成后會調換部分前后端工程師的位置勉躺,一方面是為了避免繁雜的事務性開發(fā)讓大家過于疲憊癌瘾。另一方面也是希望每個人都了解對方的工作,這樣以后出Bug的時候就能換位思考饵溅,畢竟團隊內(nèi)部矛盾妨退,特別是各個小組之間的矛盾一直是項目管理中頭疼的問題。
工程化
所謂工程化蜕企,即是面向某個產(chǎn)品需求的技術架構與項目組織咬荷,工程化的根本目標即是以盡可能快的速度實現(xiàn)可信賴的產(chǎn)品。盡可能短的時間包括開發(fā)速度轻掩、部署速度與重構速度幸乒,而可信賴又在于產(chǎn)品的可測試性、可變性以及Bug的重現(xiàn)與定位唇牧。
- 開發(fā)速度:開發(fā)速度是最為直觀罕扎、明顯的工程化衡量指標,也是其他部門與程序員丐重、程序員之間的核心矛盾腔召。絕大部分優(yōu)秀的工程化方案首要解決的就是開發(fā)速度,我們在追尋局部速度最快的同時不能忽略整體最優(yōu)扮惦,初期單純的追求速度而帶來的技術負債會為以后階段造成不可彌補的損害臀蛛。
- 部署速度:程序員在日常工作中,最常對測試或者產(chǎn)品經(jīng)理說的一句話就是径缅,我本地改好了掺栅,還沒有推送到線上測試環(huán)境呢。在DevOps概念深入人心纳猪,各種CI工具流行的今天,自動化編譯與部署幫我們省去了很多的麻煩桃笙。但是部署速度仍然是不可忽視的重要衡量指標氏堤,特別是以NPM為代表的難以捉摸的包管理工具與不知道什么時候會抽個風的服務器都會對我們的編譯部署過程造成很大的威脅,往往項目依賴數(shù)目的增多、結構劃分的混亂也會加大部署速度的不可控性鼠锈。
- 重構速度:聽產(chǎn)品經(jīng)理說我們的需求又要變了闪檬,聽技術Leader說最近又出了新的技術棧,甩現(xiàn)在的十萬八千里购笆。
- 可測試性:現(xiàn)在很多團隊都會提倡測試驅動開發(fā)粗悯,這對于提升代碼質量有非常重要的意義。而工程方案的選項也會對代碼的可測試性造成很大的影響同欠,可能沒有無法測試的代碼样傍,但是我們要盡量減少代碼的測試代價,鼓勵程序員能夠更加積極地主動地寫測試代碼铺遂。
- 可變性:程序員說:這個需求沒法改吧栏纭!
- Bug的重現(xiàn)與定位:沒有不出Bug的程序襟锐,特別是在初期需求不明確的情況下撤逢,Bug的出現(xiàn)是必然而無法避免的,優(yōu)秀的工程化方案應該考慮如何能更快速地輔助程序員定位Bug粮坞。
無論是前后端分離蚊荣,還是后端流行的MicroService或者是前端的MicroFrontend,其核心都是犧牲局部開發(fā)速度換來更快地全局開發(fā)速度與系統(tǒng)的可信賴性的提高莫杈。而區(qū)分初級程序員與中級程序員的區(qū)別可能在于前者僅會實現(xiàn)互例,僅知其然而不知其所以然,他們唯一的衡量標準就是開發(fā)速度姓迅,即功能實現(xiàn)速度或者代碼量等等敲霍,不一而足。中級程序員則可以對自己負責范圍內(nèi)的代碼同時兼顧開發(fā)速度與代碼質量丁存,會在開發(fā)過程中通過不斷地Review來不斷地合并分割肩杈,從而在堅持SRP原則的基礎上達成盡可能少的代碼量。另一方面解寝,區(qū)分單純地Coder與TeamLeader之間的區(qū)別在于前者更注重局部最優(yōu)扩然,這個局部即可能指項目中的前后端中的某個具體模塊,也可能指時間維度上的最近一段的開發(fā)目標聋伦。而TeamLeader則更需要運籌帷幄夫偶,統(tǒng)籌全局。不僅僅要完成老板交付的任務觉增,還需要為產(chǎn)品上可能的修改迭代預留接口或者提前為可擴展打好基礎兵拢,磨刀不誤砍材工∮饨福總結而言说铃,當我們探究工程化的具體實現(xiàn)方案時,在技術架構上,我們會關注于:
- 功能的模塊化與界面的組件化
- 統(tǒng)一的開發(fā)規(guī)范與代碼樣式風格腻扇,能夠在遵循SRP單一職責原則的前提下以最少的代碼實現(xiàn)所需要的功能债热,即保證合理的關注點分離。
- 代碼的可測試性
- 方便共享的代碼庫與依賴管理工具
- 持續(xù)集成與部署
- 項目的線上質量保障
前端的工程化需求
當我們落地到前端時幼苛,在歷年的實踐中感受到以下幾個突出的問題:
- 前后端業(yè)務邏輯銜接:在前后端分離的情況下窒篱,前后端是各成體系與團隊,那么前后端的溝通也就成了項目開發(fā)中的主要矛盾之一舶沿。前端在開發(fā)的時候往往是根據(jù)界面來劃分模塊墙杯,命名變量,而后端是習慣根據(jù)抽象的業(yè)務邏輯來劃分模塊暑椰,根據(jù)數(shù)據(jù)庫定義來命名變量霍转。最簡單而是最常見的問題譬如二者可能對于同意義的變量命名不同,并且考慮到業(yè)務需求的經(jīng)常變更一汽,后臺接口也會發(fā)生頻繁變動避消。此時就需要前端能夠建立專門的接口層對上屏蔽這種變化,保證界面層的穩(wěn)定性召夹。
- 多業(yè)務系統(tǒng)的組件復用:當我們面臨新的開發(fā)需求岩喷,或者具有多個業(yè)務系統(tǒng)時,我們希望能夠盡量復用已有代碼监憎,不僅是為了提高開發(fā)效率纱意,還是為了能夠保證公司內(nèi)部應用風格的一致性。
- 多平臺適配與代碼復用:在移動化浪潮面前鲸阔,我們的應用不僅需要考慮到PC端的支持偷霉,還需要考慮微信小程序、微信內(nèi)H5褐筛、WAP类少、ReactNative、Weex渔扎、Cordova等等平臺內(nèi)的支持硫狞。這里我們希望能夠盡量的復用代碼來保證開發(fā)速度與重構速度,這里需要強調的是晃痴,移動端和PC端本身是不同的設計風格残吩,不建議過多的考慮所謂的響應式開發(fā)來復用界面組件,更多的應該是著眼于邏輯代碼的復用倘核,雖然這樣不可避免的會影響效率泣侮。魚與熊掌,不可兼得紧唱,這一點需要因地制宜旁瘫,也是不能一概而論祖凫。
質量保障
前端開發(fā)完成并不意味著萬事大吉琼蚯,我們目前所謂的Bug往往有如下三類:
- 開發(fā)人員的粗心大意造成的Bug:此類型Bug不可避免酬凳,但是可控性高,并且前端目前配置專門的輔助單元測試人員遭庶,此類型Bug最多在開發(fā)初期大規(guī)模出現(xiàn)宁仔,隨著項目的完善會逐步減少。
- 需求變動造成的Bug:此類型Bug不可避免峦睡,可控性一般翎苫,不過該類型Bug在正式環(huán)境下影響不大,最多影響程序員個人情緒榨了。
- 接口變動造成的Bug:此類型Bug不可避免煎谍,理論可控性較高。在上周修復的Bug中龙屉,此類型Bug所占比重最大呐粘,建議未來后端發(fā)布的時候也要根據(jù)版本劃分Release或者MileStone,同時在正式上線后設置一定的灰度替代期转捕,即至少保持一段時間的雙版本兼容性作岖。