本文邀請cheeqi來回答,讓他手把手教你如何開發一個爆款VS Code插件!
vscode 插件的形態和一個 npm 包非常相似,需要在項目的根目錄添加 package.json,并且在其中增加一些 vscode 獨家的設置。其中最主要的設置是 Activation Events(插件的激活時機) 和 contribution points (插件的能力)。接下來我們主要看看這兩個配置具體是什么意思。
聲明插件的激活時機 Activation Events
我將 vscode 的生命周期簡單描述為下圖。下面會做進一步解釋。
[ vscode 插件生命周期(轉載請注明作者 cheeqi) ]
activate() 函數 & deactivate() 函數
可以看到生命周期中最終要的兩個節點就是activate函數和deactivate函數。這兩個函數需要在插件 npm 模塊的入口文件 export 出去給 vscode 主動調用。
其中,activate 會在 vscode 認為合適的時機調用,并且在插件的運行周期內只調用一次。因此在 activate 函數中開始啟動插件的邏輯,是一個非常合適的時機。
deactivate 函數會在插件卸載之前調用,如果你的卸載邏輯中存在異步操作,那么只需要在deactivate 函數中 retuen 一個 promise 對象,vscode 會在 promise resolve 時才正式將插件卸載掉。
onXxxx Activation Events
可以看到在activate函數之前,還有onLanguage等事件的描述,實際上這些就是聲明在插件 package.json 文件中的 Activation Events。聲明這些 Activation Events 后,vscode 就會在適當的時機回調插件中的 activate函數。vscode之所以這么設計,是為了節省資源開銷,只在必要的時候才激活你的插件。當然,如果你的插件非常重要,不希望在某個事件之后才被激活,你可以聲明Activation Events為*這樣 vscode 就會在啟動的時候就開始回調 activate函數。
插件的具體邏輯
插件中的具體邏輯 vscode 沒有做任何限制,你可以通過調用vscdoe提供的各種 api 對其進行擴充。不過需要注意的是,出于性能和移植性考慮,vscode不允許開發者直接操作dom。
關于vscode 的 api 可以參考
https://code.visualstudio.com/api/references/vscode-api 這是微軟根據 vscode 的 d.ts 文件生成的文檔
舉個例子
接下來我們來看幾個插件的 Activation Events 聲明
超越鼓勵師 申明了 onCommand:ycy.showReminderView 和 * ,其實我們都知道只聲明后一個就足夠了
vuter 申明了 onLanguage:vue 所以他會在用戶打開 vue 語言文件時被激活
vscode-icons 是一個純主題插件,聲明的是 *
GitLens 需要覆蓋所有的文件,并且在vscode啟動時就需要激活,他的聲明是 *
關于 Activation Events 的說明可以參考官方文檔 https://code.visualstudio.com/api/references/activation-events
聲明插件的貢獻點 contribution points
需要在 package.json 中聲明的另一個重要字段就是 contribution points。 contribution points描述了當前插件支持哪些能力,以及對應能力的配置。
由于 vscode 禁止直接操作dom,往 UI 中插入功能的正確方式是聲明貢獻點。下圖列出了 vscode 支持的所有貢獻點。
[ 目前 vscode 支持的貢獻點 ]
舉個例子
接下來我們來看幾個插件的 contribution points 聲明
超越鼓勵師 支持通過 commands 觸發楊超越的提醒,同時可以配置提醒出現的時機,因此包括 commands / configuration
vuter 主要為 vue 文件提供語言支持,可以看到他提供的 contribution points 比較廣,包括 commands / breakpoints / languages / grammars / configuration
vscode-icons 已支持主題為主,他提供了 iconThemes / commands / configuration
GitLens 是對vscode git 功能的增強,所以他的插入點集中在 UI 上的能力 configuration / commands / menus /resourceLabelFormatters / viewsContainers / views
關于 contribution points 的更多說明可以參考 https://code.visualstudio.com/api/references/contribution-points
編程語言支持
那么,要怎么給 vscode 增加一門新的編程語言支持呢?
就像之前說的,vscode 主要支持兩類編程語言支持: 聲明類語言特性主要描述了代碼高亮、代碼片段等輕量級需要實時給出響應的語言特性支持;而程序類語言特性只要提供更加高級的跳到定義、查找引用、hover提示等對實時性要求不高,而且需要大量計算的語言能力。因此前者更加適合在 IDE 的主線程進行處理,而后者可以考慮拆分到其他線程甚至服務中進行計算。
聲明類語言特性(基本支持)
下面主要以語法高亮為例子介紹聲明式語言支持。
[ 從手寫 paser 到 TextMate ]
在最初,微軟的工程師們為web開發中常見的開發語言都手寫了 paser。這類 paser 執行效率很高,但對開發者的能力要求也比較高,不太適合未來的插件擴展。從 vscode 1.8 版本開始,微軟引入了 TextMate 的高亮語法,并逐步將原有的手寫 paser 切換到這種語法上。
[ TextMate 官網 ]
TextMate 本身是 mac 下的一個文本編輯器,vscode 借用了他對語言高亮文本的定義方式。TextMate語法的本質是用一個 json 文件來描述語言中的 token 和結構,當然為了方便,也可以改用 YAML 并編譯成json。
順便一提,而 TextMate 語法使用的是 oniguruma 庫來解析正則表達式,oniguruma 中支持一些 js 引擎目前還不支持的正則特性,因此在 vscode 中使用了一個 oniguruma 的 c++ 模塊來加速正則表達式解析速度。
另外,為了方便開發者編寫語法高亮插件,vscode還提供了一個 yomen 模板用于生成插件基本目錄結構,以及一個名為 inspectTMScopes 的調試器查看詞法分析的結果。
[ vscode 提供的 yomen 模板 ]
[ inspectTMScopes ]
除了語法高亮外,vscode還支持這些特性:注釋切換、括號定義、自動閉合、Auto surrounding、代碼折疊、word Pattern、縮進規則等,詳見
https://code.visualstudio.com/api/language-extensions/language-configuration-guide