一.擴展能力
VS Code插件不適合做UI定製,比如Atom的tool-bar 在VS Code很難實現:

提供了豐富的擴展能力模型,但不允許插件直接訪問底層UI DOM(也就是說插件難以改變IDE外觀,UI定製受限),這是出於方便底層持續優化考慮:
With VS Code, we』re continually trying to optimize use of the underlying web technologies to deliver an always available, highly responsive editor and we will continue to tune our use of the DOM as these technologies and our product evolve.
UI DOM這一層可能會隨著優化頻繁變動,VS Code不希望這些優化項受限於插件依賴,所以乾脆把UI定製能力限制起來
除UI定製之外的,IDE相關的功能型特性都是支持擴展的,如基礎的語法高亮/API提示、引用跳轉(轉到定義)/文件搜索、主題定製,高級的debug協議等等
P.S.實際上,非要擴展UI,也是有辦法的(逃出插件運行環境,但要費不少力氣),具體見access electron API from vscode extension,後續筆記會詳細介紹
二.運行環境
為了性能與兼容性,插件在獨立的進程(稱為extension host process)中運行,並且不允許直接訪問DOM,所以提供了一套內置的UI組件,比如智能提示(IntelliSense)
所以插件崩潰或無響應不影響IDE正常運行,例如:
一個插件的死循環並不影響IDE的正常使用和其它插件的載入/激活,但在進程列表能夠看到Code Helper的CPU佔用接近100%,進程級沙箱保證了插件機制的穩定性
三.核心理念穩定性:插件隔離
插件可能會影響啟動性能和IDE自身的穩定性,所以通過進程隔離來解決這個問題,插件運行在獨立的進程中,不影響IDE及其啟動時間
這樣做是從用戶角度考慮的,希望用戶對IDE擁有完全的控制力,無論插件在做什麼,都不影響IDE基本功能的正常使用
P.S.extension host process是個特殊的Node進程,能夠訪問VS Code擴展API,VS Code也對這種進程提供了debug支持
性能:插件激活
插件都是懶載入的(as late as possible),只在特定場景才載入/激活,所有在此之前也不耗費內存等資源
實現上是插件註冊特定激活事件(activation events),由IDE來觸發執行,比如markdown插件只在用戶代開md文件時才需要激活
激活方式
插件有6種激活方式:
除外都是條件激活,只在特定場景或滿足特定條件時才載入/激活插件
插件清單文件
清單文件用來描述插件的meta信息,直接把作為清單文件,並增加了一些特有欄位,比如觸發插件載入的激活事件()、插件想要增強的擴展點()
IDE在啟動過程中掃一遍插件清單文件,UI相關的就擴展UI,UI無關的就把擴展點與插件功能關聯起來
另外,由於插件的執行環境是Node進程,所以npm package都是可用的,依賴模塊同樣聲明在里。注意,用戶安裝插件時不會自動,所以需要在發布插件前把依賴模塊打包進去,具體見Installation and Packaging
P.S.擴展點類似於AOP里的Join point(連接點),即「允許在這裡擴展/增強」,比如新增一個自定義命令,就是對擴展點的增強
manifest
P.S.完整的見Extension Manifest File – package.json
只觸發一次,根據聲明的來觸發,觸發條件可以是打開特定語言的文件,或者執行特定命令。激活之後,直到IDE被關閉/崩潰才會觸發,所以一般用法是:
activate: 插件被激活,初始化功能模塊單例(只執行一次)
deactivate: IDE即將關閉,清理現場,但不宜做太耗時的操作,因為據說最多只等待10s
擴展點
即支持的擴展類型,都聲明在下,包括:
是唯一的UI擴展官方途徑,支持擴展的菜單具體如下:
P.S.都是些不起眼的位置,大刀闊斧的UI定製是不支持的,比如想在左端側邊欄(Activity Bar)加個Icon都是做不到的
標題欄上的菜單擴展支持自定義icon,但定義方式比較奇怪,例如:
給定義,關聯到,然後展示對應的
擴展API
環境隔離讓嚴格限制插件可用API變得容易很多,插件只能訪問IDE提供的擴展性API,不能胡亂搞事情(比如修改UI DOM和樣式,官方支持的主題定製項除外)
API設計原則
插件API遵循一些原則:
基於Promise:非同步操作都用Promise來描述
取消token:傳入作為額外參數來檢查取消狀態,以及接收取消通知
可釋放式資源管理:持有的資源都需要手動釋放,例如事件監聽,命令,UI交互等
事件API:調用訂閱方法()傳入listener(接收參數)返回Disposable
嚴格空檢查:通過TypeScript嚴格區分和
P.S.關於「可釋放式」(Disposable)的更多信息,請查看Dispose pattern
API概覽
API按命名空間組織,全局命名空間如下:
比如可以通過實現Haste的全局模塊引用跳轉支持
另外,一些API以命令形式提供(即上面提到的「IDE自身的」命令),例如、、等等
基於協議的擴展
插件進程與IDE之間通過特定協議來通信,實現上是以JSON形式的stdin/stdout來通信
這種模式更強大的一點是:插件可以用任意語言來實現,只要遵守這套約定的通信協議即可
四.語言相關擴展
通過配置文件來支持語法高亮、代碼片段和智能括弧匹配,更複雜的通過擴展API或language server來做
配置型擴展
語法高亮:基礎支持區分字元串、注釋、關鍵字等語法角色,高級支持變數、函數引用等語義區分
代碼片段:snippets快捷輸入,基礎支持簡單佔位符,高級支持嵌套佔位符
智能括弧匹配:高級支持自動補充成對出現的東西,比如括弧、引號、跨行注釋等
注意,語言擴展VS Code支持標準Text Mate Grammar(格式),比如Monaco Editor的非主流Monarch-style友好很多,具體見Colorization Clarification
編程型擴展
簡單配置搞不定的,都通過擴展API(寫插件)來實現,有2種方式:
實現language server protocol與IDE通信,完全獨立
註冊Provider提供自定義能力,類似於hook的方式
使用上,第一種麻煩但更強大靈活,第二種方便直接但沒那麼靈活。支持的擴展能力如下:
hover提示:基礎支持類型、文檔等信息,高級支持方法簽名語法高亮
補全提示:高級支持在補全提示項旁邊展示額外信息
檢查報錯:基礎支持保存時對打開的文件內容檢查報錯,高級支持對打開的文件目錄里的任意資源檢查報錯
方法簽名:基礎支持在方法簽名中包含參數說明文檔
跳轉到定義:基礎支持存在多處定義時都展示出來
引用查找:基礎支持返回所有引用處的具體位置
選中查找高亮:基礎支持返回當前文檔的所有相同引用
方法/變數聲明目錄:基礎支持返迴文檔中聲明的所有標識符,及其定義位置
快速修復:對Warning和Error給出建議做法,快捷修復。基礎支持糾錯動作,高級支持修改源碼,比如重複代碼提出函數
上下文操作選項:允許根據用戶處代碼上下文,提供額外的信息與可操作選項。基礎支持展示,高級可以添加自定義命令
重命名:基礎不支持按引用重命名,高級支持工作空間下跨文件重命名
代碼格式化:基礎不支持代碼格式化,高級支持全文/選中/輸入中格式化
五.開發步驟環境要求
VS Code
Yeoman與Yo Code – Extension Generator:一步搞定
步驟
通過腳手架生成項目模版:
命令交互選擇插件類型:
建議TypeScript,其它都是字面意思,其中Extension Pack(插件包)比較有意思,即插件組裝成的插件,類似於React Native的Nuclide
輸入插件名稱等meta信息,就得到一個插件項目,然後用VS Code單獨打開該項目(工作空間不能有其它項目目錄),F5啟動debug進入插件調試
插件入口文件是,項目結構規範可以參照VS Code內置插件:
六.打包發布
提供了CLI工具,vsce:
打包
進入插件目錄,打包成文件:
會得到一個本地包(包括依賴),然後不想公開的話,自己想辦法傳播安裝,因為不像npm registry,可以手動部署一份,在內網環境放私有插件,Visual Studio Marketplace(VS Code插件市場)沒有這麼開放的心態:
If you want to share your extension with others privately, you can send them your packaged extension .vsix file.
(見Sharing Privately with Others)
沒有辦法部署一套Visual Studio Marketplace,所以只能想辦法手動解決插件更新問題,比如自動下載/提示安裝
發布
要發布到插件市場的話,需要做幾件事情:
註冊Visual Studio Team Services賬號
進入Security頁面創建個Personal Access Token
命令新增publisher
命令登錄
命令發布
具體見Publishing Extensions
參考資料
Extending Visual Studio Code
聯繫ayqy
喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!
本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!
請您繼續閱讀更多來自 ayqy 的精彩文章: