Visual Studio Code為什麼能這麼牛X?

視學演算法發表於2020-04-06

點選上方視學演算法”,選擇“置頂或者星標

你的關注意義重大!

作者:李少俠 

連結:https://zhuanlan.zhihu.com/p/35303567

Visual Studio Code(VS Code)近年來獲得了爆炸式增長,成為廣大開發者工具庫中的必備神器。它作為一個開源專案,也吸引了無數第三方開發者和終端使用者,成為頂尖開源專案之一。它在功能上做到了夠用,體驗上做到了好用,更在擁有海量外掛的情況下做到了簡潔流暢,實屬難能可貴。

我是VS Code使用者,同時也為它開發外掛,外掛市場裡的眾多Java外掛基本都是我們團隊的作品,所以我在日常工作中觀察到不少VS Code在工程方面的亮點,下面就來逐一探討。

簡潔而聚焦的產品定位,貫穿始終

你知道VS Code的開發團隊人數只有二十出頭嗎?

難以相信吧,大家都覺得VS Code無所不能,如此強大的工具那麼幾個人怎麼做得出來。實際上功能豐富是個美好的錯覺,因為大部分針對特定程式語言和技術的功能都是第三方外掛提供的,VS Code的核心始終非常精簡,這很考驗產品團隊的拿捏能力:做多了,臃腫,人手也不夠;做少了,太弱,沒人用。

他們團隊選擇了專注於核心功能的開發,為使用者提供簡潔流暢的體驗,並將該思路貫穿在產品開發的每個環節。在我看來,這就是第一個亮點。

第一個亮點同時也是一個難點,因為“簡潔”說到底是產品的“形態”,更關鍵的其實是前置問題——產品的定位,它到底解決什麼問題。該問題如果從使用者的角度來看,可以轉換為以下幾個點——我們為什麼需要一個新的工具?它到底是程式碼編輯器(Editor)還是整合開發環境(IDE)?讓我們來看看專案負責人Erich Gamma 的說法:

Visual Studio Code為什麼能這麼牛X?

(視訊截圖 - Erich闡述了VS Code的定位:編輯器+程式碼理解+除錯)

這張截圖它闡述了VS Code的定位:編輯器+程式碼理解+除錯。這是一個非常節制而平衡的選擇,專注於開發者“最常用”的功能,同時在產品的形式上力求簡潔高效。從結果來看,這個定位是相當成功的。

在這個定位的指導下,這二十多位工程師搞出了VS Code。相對較小的功能集,使得開發者們能在程式碼質量上精益求精,終端使用者們也得到了一個效能優異的工具,這是VS Code從一眾編輯器中脫穎而出的重要原因。

正因為產品定位以及團隊職責上的高度節制,團隊成員才能把時間花在這類問題上,寫出經得起考驗的程式碼。

與此同時,較小的團隊也使得團隊成員做到了行為層面的整齊劃一,這點在社群互動上體現得尤為明顯,大家可以去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乾脆不信任任何人,把外掛們放到單獨的程式裡,任你折騰,主程式妥妥的。

Visual Studio Code為什麼能這麼牛X?

外掛與主程式隔離

VS Code團隊的這一決策不是沒有原因的,正如前面提到的,團隊裡很多人其實是Eclipse的舊部,自然對Eclipse的外掛模型有深入的思考。Eclipse的設計目標之一就是把元件化推向極致,所以很多核心功能都是用外掛的形式來實現的。遺憾的是,Eclipse的外掛執行在主程式中,任何外掛效能不佳或者不穩定,都直接影響到Eclipse,最終結果是大家抱怨Eclipse臃腫、慢、不穩定。VS Code基於程式做到了物理級別的隔離,成功解決了該問題。實際上程式級別的隔離也帶出了另一個話題,那就是介面與業務邏輯的隔離。

UI渲染與業務邏輯隔離,一致的使用者體驗

“不穩定”之後的問題是“難用”,具體來說就是混亂的介面和流程,究其原因就是外掛之間的介面語言的“不一致”,它導致學習曲線異常陡峭,並且在面臨問題時沒有統一的解決路徑。VS Code的做法是根本不給外掛們“發明”新介面的機會。

如上圖,外掛們被關在Extension Host程式裡,而UI則在主程式裡,所以外掛們天然沒法直接在使用者介面上做手腳。

VS Code統管所有使用者互動入口,制定互動的標準,所有使用者的操作被轉化為各種請求傳送給外掛,外掛能做的就是響應這些請求,專注於業務邏輯。但從始至終,外掛都不能“決定”或者“影響”介面元素如何被渲染(顏色、字型等,一概不行),至於彈對話方塊什麼的,就更是天方夜譚了。

VS Code對於使用者介面的把控可以說是謹慎到變態,做過外掛的人都懂的,感興趣的同學可以去深挖一下TreeView的歷史,會有更直觀的體會。乍一看,第三方開發者被卡得死死的,這樣不是限制了大家的創造力嗎?我想說這個做法跟這個團隊的背景密切相關,換一撥人很有可能會失敗。他們之所以能成功,是因為該團隊在開發工具領域深耕多年,他們把經驗轉換為觀點,最終落實到了VS Code的介面元素以及互動語言上,從結果來看,廣受歡迎。

介面和業務邏輯的徹底隔離,使得所有外掛有了一致的行為,使用者就得到了整齊劃一的體驗。不僅如此,這種介面和行為層面的一致性,最終轉化成了另一個“偉大”的功能——Remote Development,我們稍後討論。接下來我們要聊的是VS Code另一個創舉——Language Server Protocol。

LSP——基於文字的協議

前文提到了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團隊對當今技術趨勢的把握是相當精準的,他們決策充分考慮到了“簡單”,牢牢抓住了社群開發者的心。所以重要的事情說三遍:

在做設計的時候一定要傾向於簡單。

在做設計的時候一定要傾向於簡單。

在做設計的時候一定要傾向於簡單。

集大成的Remote Development

今年五月,VS Code釋出了Remote Development(VSCRD),有了它,我們可以在遠端環境(比如虛機、容器)裡開一個VS Code工作區,然後用本地的VS Code連上去工作,下圖說明了它的執行模式:

Visual Studio Code為什麼能這麼牛X?

VSCRD從本質上改善了遠端開發的體驗,與常用的遠端桌面共享相比,具體改進如下:

響應迅速:VSCRD所有的互動都在本地UI內完成,響應迅速;遠端桌面由於傳輸的是截圖畫面,資料往返延遲很大,卡頓是常態

沿用本地設定:VSCRD的UI執行在本地,遵從所有本地設定,所以你依然可以使用自己所習慣的快捷鍵、佈局、字型,避免了工作效率層面的開銷

資料傳輸開銷小:遠端桌面傳輸的是視訊資料,而VS Code傳輸是操作請求和響應,開銷與命令列相仿,卡頓的情況進一步改善

第三方外掛可用:在遠端工作區裡,不僅VS Code的原生功能可用,所有第三方外掛的功能依然可用;遠端桌面的話,你得自己一個個裝好

遠端檔案系統可用:遠端檔案系統被完整對映到本地,這個兩者差不多

那麼VSCRD做了什麼神奇的操作能夠實現以上效果呢?來看看它的架構圖:

Visual Studio Code為什麼能這麼牛X?

其實答案都在前文有所提及:

程式級別隔離的外掛模型

Extension Host(也就是圖中的VS Code Server)與主程式做到了物理級別的分離,那麼把Extension Host在遠端或者本地跑沒有本質的區別

UI渲染與外掛邏輯隔離,整齊劃一的外掛行為

所有的外掛的UI都由VS Code統一渲染,所以外掛裡面只有純業務邏輯,行為高度統一,跑在哪裡都沒區別

高效的協議LSP

VS Code的兩大協議LSP、DAP都非常精簡,天然適合網路延遲高的情況,用在遠端開發上再適合不過

VS Code團隊在架構上的決策無疑是非常有前瞻性的,與此同時,他們對細節的把握也是無可挑剔。正因為有了如此紮實的工程基礎,VSCRD這樣的功能才得以誕生,所以我認為這是集大成的作品。

還沒有嘗試過VSCRD的同學,這裡再安利一下,它在以下場景中非常有用:

開發環境配置起來很繁瑣,比如物聯網開發,需要自己安裝和配置各種工具和外掛。在VSCRD裡,一個遠端工作區的模板即可搞定,如需安裝額外的工具,也就是改改Dockerfile的事情,非常簡單。在這裡可以找到常用的程式語言和場景的模板。

本地機器太弱,某些開發搞不了,比如機器學習,海量資料及和計算需求需要非常好的機器。在VSCRD裡,可以直接操作遠端檔案系統,使用遠端計算資源。

最後

VS Code像一顆耀眼的星星,吸引著成千上萬開發者為其添磚加瓦。從VS Code的成功中,我們看到了好的設計和工程實踐能創造多少奇蹟。放眼軟體產業,各個層面的模式不斷被重新整理,讓人激動之餘,也要求從業者不斷提高技能水平。從個人學習的角度來看,瞭解這些模式誕生的前因後果,理解工程實踐中的決策過程是非常有利於提高工程能力的。

-  -------福利分割線 --------  -

福利:

為了答謝公眾號粉絲們一直以來對「IT平頭哥聯盟」的支援,在此2019年末之際,特地自費準備了幾本書籍送給大家,獎品資訊如下:
獎品:≺漫畫演算法 ≻ x 3
參與方式:關注「IT平頭哥聯盟」,在公眾號回覆“抽獎”,識別小程式參與抽獎,


Visual Studio Code為什麼能這麼牛X?希望大家在2020年能夠一路開掛、面試次次暢通、offer拿到手軟,同時也一如既往的支援“IT平頭哥聯盟”! 

❤️ 看完兩件事

如果你覺得這篇內容對你有所幫助,我想邀請你幫我兩個小忙:

  1. 點個「在看」,讓更多的人也能看到這篇內容(喜歡不點在看,都是耍流氓 -_-)

  2. 關注公眾號「視學演算法」,一起進步,一起成長!

- END -

如果看到這裡,說明你喜歡這篇文章,請轉發、點贊掃描下方二維碼或者微信搜尋「perfect_iscas」,新增好友後即可獲得10套程式設計師全棧課程+1000套PPT和簡歷模板向我私聊「進群」二字即可進入高質量交流群。

掃描二維碼進群↓

Visual Studio Code為什麼能這麼牛X?

Visual Studio Code為什麼能這麼牛X?

Visual Studio Code為什麼能這麼牛X?

在看 Visual Studio Code為什麼能這麼牛X?

相關文章