本文轉載自公衆号“讀芯術”(ID:AI_Discovery)。
今天是2018年夏天。我的(de)老闆阿德裏安(Adrian)請我與加拿大(dà)一家大(dà)公司的(de)首席技術官詹姆斯(James)一起進行Skype通(tōng)話(huà)。
在相互了(le)解的(de)同時(shí),我發現詹姆斯是一個(gè)有雄心壯志的(de)聰明(míng)人(rén)。他(tā)的(de)願景是将大(dà)規模的(de)桌面WPF應用(yòng)程序遷移到雲中的(de)Web。
我喜歡他(tā)的(de)友好态度,可(kě)以說出他(tā)渴望與我們合作。他(tā)已經在印度擁有開發合作夥伴,但是他(tā)們缺乏構建Web應用(yòng)程序的(de)經驗。
我和(hé)Adrian在這(zhè)種情況下(xià)遵循标準方法。我們還(hái)有幾個(gè)電話(huà),然後我們開始發現階段,在此階段我們試圖把握全局并找到非功能性需求。這(zhè)些是我們應重點關注的(de)要點:
一個(gè)大(dà)型應用(yòng)程序-超過220頁,其中大(dà)多(duō)數是維護屏幕,其中大(dà)約20%是高(gāo)度定制的(de)。
顯示大(dà)量數據,尤其是在具有各種功能的(de)網格中:分(fēn)組,列凍結,行擴展,自定義列,即可(kě)爲其命名。
模塊化(huà)架構,允許多(duō)個(gè)團隊同時(shí)處理(lǐ)項目。
多(duō)年項目。新功能将随著(zhe)時(shí)間的(de)推移而增加。
不需要離線支持。
爲新團隊成員(yuán)快(kuài)速入門,特别是對(duì)使用(yòng)舊(jiù)桌面應用(yòng)程序的(de).NET開發人(rén)員(yuán)而言。
作爲一名架構師,我的(de)任務是創建一個(gè)技術提案,其中包含架構細節,方法,路線圖,指南(nán),最重要的(de)是将要使用(yòng)的(de)技術棧。
James多(duō)次提到他(tā)想要一種面向未來(lái)的(de)技術,他(tā)不贊成Angular,因爲在AngularJS被棄用(yòng)之後,它的(de)聲譽很差。
我已經使用(yòng)Angular和(hé)React成功地實現了(le)一些中小型項目,因此我對(duì)其中的(de)任何一個(gè)都沒有真正的(de)興趣。我覺得(de)任何一個(gè)都能勝任。
對(duì)于這(zhè)個(gè)項目,我選擇React with Redux…兩年後我會後悔的(de)。
我們指定了(le)一個(gè)由三名開發人(rén)員(yuán)組成的(de)團隊來(lái)進行概念驗證,兩個(gè)月(yuè)後,它成功了(le)。超級響應的(de)用(yòng)戶界面,超快(kuài)的(de)構建時(shí)間和(hé)高(gāo)開發速度。每個(gè)人(rén)都很開心。
障礙1:.NET開發人(rén)員(yuán)加入團隊
經過概念驗證後,是時(shí)候讓客戶外包團隊的(de)開發人(rén)員(yuán)加入了(le)。我們還(hái)沒有開始知識共享會議(yì),CTO給我發送了(le)一封電子郵件,說:“嘿,拉茲萬。我們真的(de)必須明(míng)天與我的(de)外包團隊見面。”
我們開會,技術負責人(rén)向我提出問題和(hé)解決方案:
“依賴注入在哪裏?“不需要一個(gè)是什(shén)麽意思?”這(zhè)是一個(gè):InversifyJS!
“功能組件?不不不。我們不喜歡他(tā)們。讓我們使用(yòng)類組件!”
“爲什(shén)麽這(zhè)些函數隻是四處徘徊,爲什(shén)麽不将它們封裝在服務類中以使其靜态化(huà)?”
“ API的(de)重試策略在哪裏?讓我們使用(yòng)PollyJS實現一個(gè)。”
“當類名是PascalCase時(shí),爲什(shén)麽文件名會變成破折号?它應反映類名,因此從現在開始,我們将其命名爲SomePageComponent.tsx。”
而且,最讓我煩惱的(de)是:“如何使用(yòng)Visual Studio而不是Visual Studio Code運行它?”
對(duì)我來(lái)說很清楚他(tā)們想在React中使用(yòng).NET準則和(hé)設計模式。我已經多(duō)次看到這(zhè)種情況發生-開發人(rén)員(yuán)很難适應新技術的(de)工作方式。因此,我不害怕就爲何這(zhè)些是React的(de)異常模式展開辯論。
但是在這(zhè)種情況下(xià),CTO支持他(tā)的(de)團隊,這(zhè)很正常。在與團隊合作多(duō)年的(de)時(shí)候,他(tā)認識我隻有兩個(gè)月(yuè)。我必須做(zuò)出讓步,并同意他(tā)們的(de)建議(yì)。
我剛剛意識到React不是Java或.NET開發人(rén)員(yuán)友好的(de)。由于類似的(de)設計模式,在這(zhè)種情況下(xià),Angular會是更好的(de)選擇。
障礙2:永遠(yuǎn)隻有React
React是一個(gè)沒有觀點的(de)庫,這(zhè)意味著(zhe)它對(duì)如何實現跨領域關注沒有意見。因此,您和(hé)您的(de)團隊有責任就如何使用(yòng)它,尤其是要使用(yòng)的(de)其他(tā)庫提出意見。當然,您将使用(yòng)第三方庫,因爲您不想重新發明(míng)輪子。在React中,有很多(duō)選項可(kě)供選擇。
對(duì)于概念驗證,我已經對(duì)如何處理(lǐ)大(dà)多(duō)數跨領域問題有意見。現在,他(tā)們必須與新的(de)團隊成員(yuán)一起重新驗證。這(zhè)是討(tǎo)論的(de)基本主題列表:
應該使用(yòng)哪個(gè)路由器?
除了(le)Redux,異步動作還(hái)應該使用(yòng)什(shén)麽?Trunk?Saga
我們應該使用(yòng)Axios還(hái)是訪存浏覽器API?
Redux-Forms,Formiq還(hái)是Final-Form?
樣式組件,makeStyle,SASS還(hái)是純CSS?
國際化(huà)庫?
因此,我們又花了(le)三個(gè)星期來(lái)做(zuò)出這(zhè)些決定。我可(kě)以感覺到您對(duì)我尖叫:“快(kuài)點,夥計!不可(kě)能花三個(gè)星期的(de)時(shí)間來(lái)挑選那些庫!”
好吧……歡迎來(lái)到企業項目。有很多(duō)決定。對(duì)于每一項,您都必須創建決策标準,進行研究,通(tōng)過創建概念證明(míng)來(lái)驗證發現,提出發現,在決策日志中記錄所有内容以及使庫保持最新。這(zhè)花費了(le)瘋狂的(de)時(shí)間,而且甚至沒有樂(yuè)趣。
而且,我什(shén)至沒有考慮每個(gè)開發人(rén)員(yuán)花費在學習(xí)所有這(zhè)些第三方庫上的(de)時(shí)間。我從未見過兩個(gè)具有相同依賴項,項目結構和(hé)準則的(de)React項目。這(zhè)意味著(zhe)知識無法在項目之間轉移,就像在Angular或Vue中一樣。
在實施功能用(yòng)戶故事方面未取得(de)任何進展的(de)三周後,CTO開始擔心。
障礙3:React Hooks受歡迎
九個(gè)月(yuè)後,我們創建了(le)50多(duō)個(gè)頁面。開發人(rén)員(yuán)注意到功能組件與類組件一樣好,并開始使用(yòng)它們。因此,現在該項目不再遵循原始的(de)編碼準則。對(duì)于每個(gè)開發人(rén)員(yuán)來(lái)說,這(zhè)更像是個(gè)人(rén)選擇。對(duì)我來(lái)說,那沒關系。
React Hooks已發布并廣受歡迎。球隊有百感交集。有人(rén)認爲類會使人(rén)和(hé)機器混淆,有些開發者對(duì)此感到不滿,而另一些人(rén)則熱(rè)衷于新的(de)編碼模式。
我們正在使用(yòng)的(de)所有第三方庫都增加了(le)對(duì)Hooks的(de)支持,整個(gè)React世界似乎都朝著(zhe)這(zhè)個(gè)方向發展。那我們該怎麽辦呢(ne)?我們是否應該偏離原始的(de)編碼準則,并添加實現組件的(de)第三種方法?無法退回并将現有頁面和(hé)組件遷移到Hooks!
該團隊贊成使用(yòng)Redux Hooks,因爲不需要使用(yòng)Redux connect()并将轉儲組件與容器分(fēn)開。這(zhè)是有道理(lǐ)的(de),我們同意從現在開始,新頁面和(hé)新組件将使用(yòng)Hooks。我們将保留舊(jiù)的(de)。
這(zhè)就是我們最終得(de)到三種處理(lǐ)方式的(de)方式。不再有一緻性。
更糟的(de)是,一些開發人(rén)員(yuán)開始提出不再使用(yòng)Redux而是使用(yòng)useState的(de)想法。這(zhè)意味著(zhe)我們将破壞擁有一個(gè)單一全球狀态的(de)想法。
懸念仍然是實驗性功能。我擔心它發布後會發生什(shén)麽。
障礙4:開發放緩
當我們進行持續集成的(de)設置時(shí),構建大(dà)約花了(le)三分(fēn)鐘(zhōng),包括npm安裝。但是現在,一年後,大(dà)約需要15分(fēn)鐘(zhōng)。
我們還(hái)必須配置Node.js以将RAM擴展到4GB,因爲2GB不夠了(le)。這(zhè)不是大(dà)問題。令人(rén)擔憂的(de)是,開發人(rén)員(yuán)已開始抱怨構建時(shí)間太長(cháng),在45-60分(fēn)鐘(zhōng)的(de)開發後熱(rè)加載就停止工作,并且重新啓動要花5分(fēn)鐘(zhōng)以上的(de)時(shí)間-特别是對(duì)于那些使用(yòng)Windows機器(顯然是Linux系統的(de)用(yòng)戶)對(duì)于Node.js來(lái)說要快(kuài)得(de)多(duō))。有時(shí),他(tā)們不得(de)不完全删除node_modules并再次下(xià)載依賴項,因爲否則它将無法正常工作。
當node_modules中有1200多(duō)個(gè)依賴項,總大(dà)小爲600MB時(shí),您會期望什(shén)麽?
對(duì)于企業應用(yòng)程序,一切都與成本有關。假設開發人(rén)員(yuán)每天必須以每小時(shí)$ 40的(de)速度重新啓動六次。六次/天x五分(fēn)鐘(zhōng)x 240天/年x $ 40 /小時(shí)x八個(gè)開發人(rén)員(yuán)= $ 38,400 /年對(duì)于企業而言,這(zhè)并不是一筆大(dà)數目,但是對(duì)于項目發起人(rén)來(lái)說,這(zhè)是一筆不錯的(de)年度獎金。畢竟,它等于全新的(de)Tesla Model 3。
障礙5:Redux-Saga快(kuài)死了(le)
大(dà)多(duō)數開發人(rén)員(yuán)不同意我的(de)觀點,但是我認爲大(dà)部分(fēn)業務邏輯都在Redux異步操作内部。在大(dà)多(duō)數情況下(xià),它是唯一可(kě)以進行驗證,API調用(yòng),錯誤處理(lǐ),觸發redux突變或觸發通(tōng)知烤面包機的(de)地方。如果不将這(zhè)些視爲前端應用(yòng)程序上的(de)業務邏輯,那又是什(shén)麽?
我們使用(yòng)Redux-Saga,這(zhè)是一個(gè)糟糕的(de)決定,因爲它增加了(le)不必要的(de)複雜(zá)性。Thunk足夠好了(le)。
在企業應用(yòng)程序中,您必須不時(shí)地升級并重新驗證依賴關系。這(zhè)是一個(gè)好習(xí)慣,因爲您希望安全更新,性能改進和(hé)較小的(de)增量API更改,同時(shí)希望不進行重大(dà)更改。看來(lái)Redux-Saga已落伍。上一次更新是一年多(duō)以前的(de),而沒有任何人(rén)修複它們,GitHub問題的(de)數量仍在增加。
開發人(rén)員(yuán)喜歡React的(de)原因有三個(gè):簡單性,靈活性和(hé)生态系統。React的(de)團隊喜歡嘗試新的(de)想法,但這(zhè)正在破壞生态系統!他(tā)們應該勇敢承擔責任!
實際上,React大(dà)多(duō)是向後兼容的(de),但是React周圍的(de)生态系統卻不是。開發人(rén)員(yuán)和(hé)第三方庫将始終使用(yòng)最新的(de)功能和(hé)體系結構模式,而舊(jiù)的(de)實驗将被淘汰。對(duì)于中小型項目,這(zhè)應該不成問題,因爲您可(kě)以更輕松地進行調整。但是對(duì)于大(dà)型的(de)多(duō)年項目,這(zhè)些實驗可(kě)能會破壞交易。
已經是2020年9月(yuè),我決定将React-Saga納入技術指導委員(yuán)會的(de)風險評估結果中。
因爲30%的(de)業務邏輯都在saga中,所以我将其标記爲高(gāo)風險。那是當我們開始項目時(shí),首席技術官發脾氣,并責怪我做(zuò)出了(le)錯誤的(de)決定。
這(zhè)隻是産品經理(lǐ)需要的(de)火花。他(tā)以此爲契機開始提出如下(xià)問題:
“爲什(shén)麽我們必須花很多(duō)時(shí)間來(lái)升級庫?”
“爲什(shén)麽發展放緩?”
“爲什(shén)麽應用(yòng)程序變得(de)有bug和(hé)不穩定?”
事情升級到管理(lǐ)層。我花了(le)很多(duō)時(shí)間尋找證據來(lái)證明(míng)我們當時(shí)做(zuò)出了(le)最好的(de)決定,而不是我想度過周末的(de)方式。
幾次回顧會議(yì)之後,我們再次駛過平靜的(de)水(shuǐ)面。畢竟,該項目即将完成。即将進入維護模式。
結論
我愛(ài)React。我将其用(yòng)于我的(de)所有個(gè)人(rén)項目,并希望将其推薦用(yòng)于新的(de)工作計劃。但是,在經曆了(le)令人(rén)不愉快(kuài)的(de)經曆之後,我将不鼓勵将其用(yòng)于企業應用(yòng)程序。再沒有。
順便說一下(xià),我并不孤單。
原文鏈接:
https://medium.com/better-programming/i-almost-got-fired-for-choosing-react-in-our-enterprise-app-846ea840841c