來源:何鎮汐
連結:http://www.cnblogs.com/xiadao521/p/Util-Introduction-1.html
這幾年技術更新節奏異常迅猛,.NET 進入了跨平臺時代,前端也被革命性的顛覆。
回顧
2015年,正當我還沉迷於JQuery + EasyUi的封裝時,突然意識到技術已經過時。
JQuery在面對更加複雜的UI需求時顯得力不從心,EasyUi雖然元件比較完善,但介面風格老舊,響應速度慢,且是收費商業產品,在一個商業產品上投入精力封裝並不划算,所以我果斷棄坑了。
然後開始封裝JQuery + Bootstrap,在一個SPA(單頁應用)專案裡暴露出很多問題,讓我認識到JQuery不適合做SPA,我開始尋找新的方案。
AngularJs(ng 1.x)是谷歌出品的JS框架,幾本書下肚以後,我開始琢磨著如何把AngularJs操作封裝起來,為了封裝成鏈式呼叫,甚至改了它的原始碼以支援服務定位器樣式。
正當我準備封裝基於AngularJs的UI元件時,發現它也過時了。由於UI封裝工作量巨大,而前端環境異常混亂,不再敢輕舉妄動,直到前端三大框架浮出水面。
2016年,.NET Core興起,為了方便學習交流,Alexinea(劉怡)發起了.NET Core學習小組,Kiler(謝煬)、Lemon(劉浩楊)和我做為第一批成員加入了小組。
微軟當時尚未提供.NET Core中文檔案,為了方便國內.NET Core的學習和推廣,.NET Core學習小組組織了一批.NET 愛好者進行翻譯,直到官方提供了中文檔案為止。
2017年,.NET Core學習小組決定釋出開源專案以推動.NET Core的發展,.NET Core學習小組也正式改名為.NET Core Community(.NET Core中國社群),簡稱NCC。
最初加入的專案有Lemon的AOP框架AspectCore,Savorboard(楊曉東)的分散式事務解決方案CAP框架,以及我的應用框架Util。隨後一些優秀的開源專案加入了NCC,包括爬蟲解決方案DotnetSpider,分散式微服務框架Surging等。
Util產生的背景
我長期混跡於小型軟體公司,小公司資源有限,人少事多,水平也參差不齊,如何降低團隊的學習成本,如何提高專案的開發進度,如何降低Bug率,是我的主要關註點。
Util應用框架是我在多年的專案實戰中積累起來以解決上述問題的利器,實踐證明,它在多個小型團隊和多個中小專案上起到關鍵作用,甚至包括一些瀕臨流產的專案。
中小專案的瓶頸在哪
對於中小專案,簡單CRUD(增刪改查)佔據大量篇幅,核心模組包含複雜業務邏輯,報表包含複雜查詢,另外還需要許可權控制、流程控制等,不管模組再多,大體不出這個範圍。
前端UI體驗變得越來越重要,工作量也越來越大。一個簡單CRUD,服務端API開發半小時,UI可能需要折騰一天。
如何打破瓶頸
如果能夠迅速拿下CRUD,並且能有效減輕前端開發任務,那麼就能將更多精力投入核心業務,從而提高專案交付能力。
對於服務端CRUD,透過封裝基類再配合程式碼生成就能很好解決,如何提升前端開發效率?
正確認識”前後分離”
一些人鼓吹“前後分離“原則,前端介面交給專業的前端人員,後端人員只負責提供API就好了,這似乎是提升前端開發效率的靈丹妙藥。
問題在於小公司資金預算有限,而專業前端人員薪資要求很高,以低價招聘的前端人員,往往只會HTML + CSS,JS耍得並不溜,最後還得服務端程式員上場。
另一方面,前端還有前臺和後臺之分,前臺是面向終端使用者的網站,比如入口網站,商城一類,前臺偏重展示,規律性不強,後臺是面向使用者或管理員的表單系統,偏重功能,規律性比較強。大多公司的前端人員主要開發前臺網站,而管理後臺還是服務端程式員開發,前端人員頂多幫助介面佈局,功能還是後端人員完成。
“前後分離”不一定是人員的分離,也不能降低工作量,主要是指前後端依賴關係的分離,如果前端技術或後端技術可隨意替換,而不是系結在一起,就認為分離成功,這提升了專案的可維護性。
Js框架的選擇
為了降低前端開發難度,選擇一個好的Js框架顯得特別重要。
對於一個複雜介面操作,JQuery同樣可以完成任務,但與現代主流的Js框架相比,JQuery操作Dom的方式更加複雜,效率低下,且難以維護。
現代前端三大Js框架是Angular(ng 2+),Vue和React。透過學習,發現Angular更符合我對開發效率的追求。
要提升開發效率,最關鍵的特性就是程式碼提示。不相信??請在記事本上用C#寫幾句試試。
Angular是谷歌開發的Js框架,預設採用Typescript(Ts)語言開發,Typescript語言是微軟開發的強型別指令碼陳述句,它是Js的超集,在VS或VSCode上具有程式碼提示。
你可能會說,Js不也有程式碼提示?這完全不一樣,Ts具有強型別的程式碼提示,你只能看見物件上明確定義的成員,提供了非常精確的提示,而Js的程式碼提示捲軸好幾米長,和當前物件無關的資訊也顯示出來,這嚴重降低了程式碼提示的作用。
除了程式碼提示,Ts還填平了Js固有的一些設計缺陷。
很多開發人員不選擇Angular的原因是需要多學一門指令碼語言,認為成本高,這其實是一種誤解。
Ts在語法上有點像Js + C# + Java的混合體,對於C#或Java程式員,上手成本非常低,開發起來讓你爽不停。
作為微軟系.NET 程式員的我們更應該大力支援。
宣告式程式設計
現在我們在開發服務端和前端指令碼時都有了程式碼提示,工作效率得到提升,還能更進一步嗎?
現代流行的前端框架都有元件或指令的概念,用來支援宣告式程式設計,它透過擴充套件Html自定義標簽或自定義屬性的方式來呼叫Js。
這種方式將Js隱藏在內部,將Js轉化成了Html,形成更好的封裝性。毫無疑問,使用Html編寫的頁面,比使用Js具有更強的表現力。
如果文字框需要非空驗證,只需要在標簽上加個屬性,就像下麵這樣,你並不需要呼叫任何Js就完成了驗證工作,這相當酷。
不過我發現很多團隊並不使用宣告式程式設計方式,更願意使用Js,原因在於Html是弱型別標簽,自定義屬性並沒有程式碼提示,這確實是個大問題。
TagHelper – 編寫Html的救命稻草
我在2012年學習Dwz這個前端框架時,接觸到宣告式程式設計的概念,也被Html無提示的問題所困擾,後面發現ASP.NET提供的HtmlHelper能夠封裝Html,提供強型別的程式碼提示,這正是我需要的特性。
2015年用HtmlHelper封裝了EasyUi,雖然只完成了一些基礎工作,但使用過的人都認為它大量提升了開發效率,它現在甚至仍然是一些公司的主打技術。
HtmlHelper也有缺陷,它看上去是C#程式碼,而不是標簽,比如HtmlHelper封裝的文字框長成這樣。
如果需要前端同學來幫助你調整介面,這就不太友好了。
另外HtmlHelper與Html混在一起也讓程式碼看上去不直觀。
微軟發現了這個問題,在ASP.NET Core推出了TagHelper,TagHelper與HtmlHelper類似,也是用來封裝Html的強型別工具,不過它用起來是個標簽,如果你不註意,根本看不出這是Html,還是TagHelper,這對前後端人員配合完成Html頁面具有重大意義。
現在TagHelper封裝的文字框長成這樣了。
TagHelper與Angular結合的艱難之路
使用Angular或Vue框架,你通常不會從0開始工作,尋找現成的UI元件庫是更明智的選擇,比如Angular可以選擇Angular Material或Ng-Zorro。
這些庫都提供了大量元件和屬性,如果直接使用Html編寫,沒有程式碼提示,你必須隨時開啟官網,四處翻上翻下以尋找你需要的屬性,哪怕你曾經用過它,如果你記得不是十分精確,從官網複製貼上會時刻伴隨著你。
現在好了,你知道TagHelper是救命稻草,可能已經迫不急待想要動手封裝了,不就是把Html拼接出來輸出到頁面,這能有多難?別急,小夥子,將Angular元件封裝成TagHelper可不是你想的這麼簡單。
如果你關註過ASP.NET Core Angular這個模板專案,你會發現這個模板使用的依然是Html,而不是TagHelper,這是為什麼?自家這麼好的技術,你都不推廣一下?
我憑藉之前封裝HtmlHelper所積累下來的經驗,將ASP.NET Core 2.0 Angular這個模板專案改造成支援TagHelper,這是使用Angular提供的JIT編譯特性做到的。
JIT就是即時編譯,會在執行時動態獲取Html頁面並編譯成內部Js,我在Github上也發現國外有些人在使用這種方式,不過都處於Demo級別。
我用TagHelper封裝了Angular Material元件庫,並將它應用在專案上。
很快爆發了嚴重的效能問題,這時候專案上的頁面也才上百個。
從啟動到看見登入頁面,需要半分鐘,F5掃清還需要這麼久,這個速度是無法接受的。
我觀察到系統在啟動時會請求所有頁面,原來我雖然使用了Angular模組,但沒有使用延遲載入,主模組直接取用了子模組,導致在啟動時載入全部頁面。
使用延遲載入緩解了這個問題,啟動能在三秒左右完成,進入子模組也需要幾秒,雖然能勉強使用,但效能和AOT編譯相去甚遠。
AOT編譯是Angular提供的預編譯,能在釋出階段把Html檔案直接編譯成Js,這樣在執行時就不再訪問Html頁面,對效能具有極大的提升。
使用了TagHelper以後,並沒有Html檔案,AOT編譯無法訪問服務端Url,所以沒辦法使用。
魚和熊掌都想兼得,如果能夠得到TagHelper的編譯時檢查和程式碼提示功能,又能得到AOT編譯的執行時效能,這該多好啊。
我當時寄希望於ASP.NET Core團隊,希望他們能提供一點支援,在Github提了Issue之後,ASP.NET Core團隊表示TagHelper與Angular這種Js框架水火不容,機制上的問題。
我後面仔細想想,確實如此,TagHelper主要為服務端MVC提供支援,而使用了Angular這樣的Js框架後,路由都走客戶端,透過AOT編譯後,服務端除了提供WEB API,真沒它啥事。
由於TagHelper提高了我團隊的開發效率,延遲載入能讓這個機制勉強使用,我也就堅持了下來。直到有一天靈機一動,用TagHelper生成出Html檔案不就好了嗎,和玄冰同學折騰了一天,終於解決了這個問題。現在,TagHelper充當了程式碼生成器的角色,服務端MVC相關的特性被全部拋棄。
小結
前面介紹了Util的一些背景和動機,同時也解釋了為何我花大把時間在UI封裝的原因。
未完待續,下一篇介紹Util包含的主要功能,以及讓你把TagHelper + Angular Material封裝的Demo執行起來。
Util應用框架的下載地址為:https://github.com/dotnetcore/Util
寫文需要動力,請大家多多支援,點下推薦,Github點下星星。
Util應用框架交流一群: 24791014
●編號150,輸入編號直達本文
●輸入m獲取文章目錄
Web開發
更多推薦《18個技術類公眾微信》
涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。