Visual Studio Code(VS Code)近年來獲得了爆炸性成長,成為廣大開發者工具庫中的必備神器。它作為一個開源項目,也吸引了無數第三方開發者和終端用戶,成為頂尖開源專案之一。它在功能上做到了夠用,體驗上做到了好用,更在擁有海量插件的情況下做到了簡潔流暢,實屬難能可貴。
相關推薦:《vscode基礎教學》
#我是VS Code用戶,同時也為它開發插件,外掛市場裡的眾多Java外掛程式基本上都是我們團隊的作品,所以我在日常工作中觀察到不少VS Code在工程方面的亮點,以下就來逐一探討。
你知道VS Code的開發團隊人數不多嗎?難以相信吧,大家都覺得VS Code無所不能,如此強大的工具那麼幾個人怎麼做到。實際上功能豐富是個美好的錯覺,因為大部分針對特定程式語言和技術的功能都是第三方插件提供的,VS Code的核心始終非常精簡,這很考驗產品團隊的拿捏能力:做多了,臃腫,人手也不夠;做少了,太弱,沒人用。他們團隊選擇了專注於核心功能的開發,為使用者提供簡潔流暢的體驗,並將該想法貫穿產品開發的每個環節。在我看來,這就是第一個亮點。
第一個亮點同時也是一個難點,因為“簡潔”說到底是產品的“形態”,更關鍵的其實是前置問題——產品的定位,它到底解決什麼問題。該問題如果從使用者的角度來看,可以轉換為以下幾個點——我們為什麼需要一個新的工具?它到底是程式碼編輯器(Editor)還是整合開發環境(IDE)?讓我們來看看專案負責人怎麼說:
https://link.zhihu.com/?target=https://www.youtube.com/watch?v=Vs3AGfeuNKU
視訊截圖 - Erich闡述了VS Code的定位:編輯器 程式碼理解 調試
無法觀看影片的同學請看這張截圖,它闡述了VS Code的定位:編輯器 程式碼理解 調試。這是一個非常節製而平衡的選擇,專注於開發者「最常用」的功能,同時在產品的形式上力求簡潔高效。從結果來看,這個定位是相當成功的。
在這個定位的指導下,這些個位工程師搞出了VS Code。相對較小的功能集,使得開發者們能在程式碼品質上精益求精,最終用戶們也得到了一個性能優異的工具,這是VS Code從一眾編輯器中脫穎而出的重要原因。關於精益求精,大家可以參考這篇文章,它記錄了VS Code重新實作Text Buffer的過程,同時也分享了思路歷程。正因為產品定位以及團隊職責上的高度節制,團隊成員才能把時間花在這類問題上,寫出經得起考驗的程式碼。
同時,較小的團隊也使得團隊成員做到了行為層面的整齊劃一,這點在社區互動上體現得尤為明顯,大家可以去GitHub上看他們的Issues,超出產品定位範疇的請求和回饋基本上都被婉拒或轉交到第三方插件項目,可以說是很專注了。
看到這裡,似乎一切都好,但問題來了,碼農千千萬,你用Node我用Go,你搞前端我弄後台,VS Code如何滿這些五花八門的需求呢?機智的你已經搶答了——海量插件。那接下來我們來深究一下VS Code是如何經營一個龐大的插件生態的。
透過外掛程式來擴充功能的做法已經是司空見慣了,但如何保證插件和原生功能一樣優秀呢?歷史告訴我們:不能保證。大家可以參考Eclipse,插件模型可以說是做得非常徹底了,功能層面也是無所不能,但存在幾個煩人的問題:不穩定、難用、慢,所以不少用戶轉投IntelliJ的懷抱。可謂成也插件,敗也插件。問題的本質在於資訊不對稱,它導致不同團隊寫出來的程式碼,無論是思路還是質量,都不一致。最終,用戶得到了一個又亂又卡的產品。所以要讓插件在穩定性、速度和體驗的層面都做到和原生功能統一,只能是一個美好的願望。
來看看其他IDE是怎麼做的,Visual Studio自己搞定所有功能,並且做到優秀,讓別人無事可做,這也成就了其「宇宙第一IDE」的美名;IntelliJ與之相仿,開箱即用,插件可有可無。這麼看起來,自己搞定所有的事情是個好辦法,但大家是否知道,Visual Studio背後有龐大的工程團隊,顯然,這不是VS Code這幾號人能搞定的。他們選擇了讓大家來做插件,那要怎麼解決Eclipse所遇到的問題呢?
這裡分享一個小知識-Eclipse核心部分的開發者就是早期的VS Code團隊。嗯,所以他們沒有兩次踏入同一條河流。與Eclipse不同,VS Code選擇了把插件關進盒子裡。
這樣做首先解決的問題就是穩定性,這個問題對於VS Code來說尤其重要。都知道VS Code基於Electron,實質上是個node.js環境,單線程,任何程式碼崩了都是災難性後果。所以VS Code乾脆不信任任何人,把插件放到單獨的進程裡,任你折騰,主程式妥妥的。
外掛程式與主流程隔離
VS Code團隊的這項決策不是沒有原因的,正如前面提到的,團隊裡很多人其實是Eclipse的舊部,自然對Eclipse的插件模型有深入的思考。 Eclipse的設計目標之一就是把元件化推向極致,所以很多核心功能都是用插件的形式來實現的。可惜的是,Eclipse的插件運作在主流程中,任何外掛效能不佳或不穩定,都直接影響Eclipse,最終結果是大家抱怨Eclipse臃腫、慢、不穩定。 VS Code基於進程做到了物理層級的隔離,成功解決了這個問題。實際上進程層級的隔離也帶出了另一個話題,那就是介面與業務邏輯的隔離。
“不穩定”之後的問題是“難用”,具體來說就是混亂的介面和流程,究其原因就是插件之間的介面語言的“不一致”,它導致學習曲線異常陡峭,並且在面臨問題時沒有統一的解決路徑。 VS Code的做法是根本不給外掛程式「發明」新介面的機會。
如上圖,插件們被關在Extension Host進程裡,而UI則在主進程裡,所以插件們天然沒辦法直接在使用者介面上做手腳。 VS Code統管所有使用者互動入口,制定互動的標準,所有使用者的操作轉化為各種請求傳送給插件,插件能做的就是回應這些請求,專注於業務邏輯。但從始至終,插件都不能「決定」或「影響」介面元素如何被渲染(顏色、字體等,一概不行),至於彈奏對話框什麼的,就更是天方夜譚了。
VS Code對於使用者介面的把控可以說是謹慎到變態,做過插件的人都懂的,有興趣的同學可以去深挖一下TreeView的歷史,會有更直觀的體會。乍一看,第三方開發者被卡得死死的,這樣不是限制了大家的創造力嗎?我想說這個做法跟這個團隊的背景密切相關,換一撥人很有可能會失敗。他們之所以能成功,是因為團隊在開發工具領域深耕多年,他們把經驗轉換為觀點,最終落實到了VS Code的介面元素以及互動語言上,從結果來看,廣受歡迎。
介面和業務邏輯的徹底隔離,使得所有外掛程式有了一致的行為,使用者就得到了整齊劃一的體驗。不僅如此,這種介面和行為層面的一致性,最終轉化成了另一個「偉大」的功能——Remote Development,我們稍後討論。接下來我們要聊的是VS Code另一個創舉-Language Server Protocol。
前文提到了VS Code定位中的兩個特色:程式碼理解和調試,絕大部分都由第三方插件來實現,中間的橋樑就是兩大協定-Language Server Protocol(LSP)和Debug Adapter Protocol(DAP)。兩者從設計的角度來看高度相似,我們著重看最火的LSP。首先,為什麼需要LSP?
全端開發早已成為這個時代的主流,軟體從業者們也越來越不被某個特定的語言或技術所局限,這也對我們手中的金剛鑽提出了新的挑戰。舉個栗子,我用TypeScript和node.js做前端,同時用Java寫後台,偶爾也用Python做一些數據分析,那麼我很有可能需要若干工具的組合,這樣做的問題就在於需要在工具間頻繁切換,無論從系統資源消耗和使用者體驗的角度來看,都是低效率的。
那麼有沒有一種工具能在同一個工作區裡把三個語言都搞定呢?沒錯,就是VS Code——支援多語言的開發環境,而多語言支援的基礎就是Language Server Protocol(LSP)。該協議在短短幾年內取得了空前的成功,到目前為止,已經有來自微軟等大廠以及社區的一百個實現,基本上覆蓋了所有主流程式語言。同時,它也被其他開發工具所採納,例如Atom、Vim、Sublime、Emacs、Visual Studio和Eclipse(點擊這裡查看完整清單),從另一個角度證明了它的優秀。更難能可貴的是,該協定也做到了輕量且快速,可以說是VS Code的殺手級特性了,同時也是微軟最重要的IP之一。 。 。哇塞,又強大又輕巧,怎麼看都是個騙局啊,那我們就來看看它到底怎麼做到的。
先劃重點:1、節制的設計 2、合理的抽象 2、周全的細節。
先來說說設計(Design),大而全是很常見的問題。如果讓我來設計這麼一個用來支援所有程式語言的東西,第一個反應很可能是搞個涵蓋所有語言特性的超集。微軟就有過這樣的嘗試,像是Roslyn——語言中立的編譯器,C#和VB.NET的編譯器都是基於它所做的。大家都知道C#在語言特性層面是非常豐富的,Roslyn能撐起C#就足以說明它的強大。那麼問題來了,為啥它沒有在社區廣泛應用呢?我想根本原因是「強大」所帶來的副作用:複雜、主觀(Opinionated)。光是語法樹就已經很複雜了,其他各種特性以及他們之間的關係更是讓人望而卻步,這樣一個龐然大物,普通開發者是不會輕易去碰的。
相較之下,LSP顯然把小巧當作設計目標之一,它選擇做最小子集,貫徹了團隊一貫節制的作風。它關心的是使用者在編輯程式碼時最常處理的實體(例如檔案、目錄)和狀態(遊標位置)。它根本沒有試圖去理解語言的特性,編譯也不是它所關心的問題,所以自然不會涉及語法樹一類的複雜概念。它也不是一步到位的,而是隨著VS Code功能的迭代而逐步發展出來的。所以它自誕生至今依然保持著小巧的身材,易懂,實現門檻也很低,迅速在社區得到了廣泛的支持,各種語言的Language Server(LS)遍地開花。
小歸小,功能可不能少,所以抽象就非常關鍵了。 LSP最重要的概念是動作和位置,LSP的大部分請求都是在表達」在指定位置執行規定動作「。舉個栗子,使用者把滑鼠停留在某個類別名稱上方,查看相關的定義和文件。這時VS Code會傳送一個'textDocument/hover'請求給LS,這個請求裡最關鍵的資訊就是目前的文件和遊標的位置。 LS收到請求之後,經過一系列內部計算(識別出遊標位置所對應的符號,並找出相關文件),找出相關的信息,然後發回給VS Code顯示給用戶看。這樣一來一回的交互,在LSP裡被抽象化為請求(Request)和回覆(Response),LSP同時也規定了它們的規格(Schema)。在開發者看來,概念非常少,互動形式也很簡單,實作起來非常輕鬆。
看到這裡,大家應該對LSP有了更進一步的理解,它本質上是膠水,把VS Code和各種語言的LS黏在一起。但它不是普通的膠水,而是非常有品味的膠水,這品味就體現在細節上。
首先這是一個基於文字的協議,文字降低了理解和調試的難度。參考HTTP和REST的成功,很難想像如果這是一個二進位協定會是什麼局面,甚至同樣是文字協定的SOAP也早已作古,足以說明「簡單」在打造開發者生態裡的重要性。
其次這是一個基於JSON的協議,JSON可以說是最易讀的結構化資料格式了,大家看看各個程式碼倉庫裡的配置未見都是啥格式就知道這是個多麼正確的決定了,現在還有人在新專案裡用XML嗎?又一次——「簡單」。
再次,這是一個基於JSONRPC的協議,由於JSON的流行,各大語言都對它有極好的支持,所以開發者根本不需要處理序列化、反序列化一類的問題,這是實現層面的「簡單」。
從這些細節可以看出,VS Code團隊對當今技術趨勢的把握是相當精準的,他們決策充分考慮到了“簡單”,牢牢抓住了社區開發者的心。所以重要的事情說三遍:
在做設計的時候一定要傾向於簡單。
在做設計的時候一定要傾向於簡單。
在做設計的時候一定要傾向於簡單。
今年五月,VS Code發布了Remote Development(VSCRD),有了它,我們可以在遠端環境(例如虛機、容器)裡開一個VS Code工作區,然後用本地的VS Code連接上去工作,下圖說明了它的運作模式:
VSCRD本質上改善了遠端開發的體驗,與常用的遠端桌面共享相比,具體改進如下:
那麼VSCRD做了什麼神奇的操作能夠實現以上效果呢?來看看它的架構圖:
其實答案都在前文有所提及:
VS Code團隊在架構上的決策無疑是非常有前瞻性的,同時,他們對細節的掌握也無可挑剔。正因為有瞭如此紮實的工程基礎,VSCRD這樣的功能才得以誕生,所以我認為這是集大成的作品。
還沒有嘗試過VSCRD的同學,這裡再安麗一下,它在以下場景中非常有用:
VS Code像一顆耀眼的星星,吸引成千上萬開發者為其添磚加瓦。從VS Code的成功中,我們看到了好的設計和工程實踐能創造多少奇蹟。放眼軟體產業,各層面的模式不斷被刷新,讓人興奮之餘,也要求從業人員不斷提陞技能水準。從個人學習的角度來看,了解這些模式誕生的前因後果,理解工程實務中的決策過程是非常有利於提升工程能力的。
附送彩蛋一枚,大家留意一下《Design Patterns》這本書的作者名單。對,就是他,不謝。
更多程式相關知識,請造訪:程式設計教學! !
以上是VSCode工程方面的亮點有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!