<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          VS Code 插件開發(fā)入門教程

          共 14906字,需瀏覽 30分鐘

           ·

          2021-03-13 06:15


          原本鏈接:https://hellogithub2014.github.io/2019/06/09/vscode-plugin-development/

          之前一直以為開發(fā)VS code插件是一件很難的事情,后來工作上需要搞一個(gè)效率小工具,就試著找了些資料來入門,發(fā)現(xiàn)其實(shí)就入門和開發(fā)一些簡(jiǎn)單功能的插件來說難度還是很低的。因?yàn)関scode本身是基于electron開發(fā)的,所以總體來說開發(fā)插件就是在寫node代碼,額外再加一些編輯器api,插件發(fā)布的過程和npm包的發(fā)布很類似。

          vscode官方提供的腳手架還幫忙加上了調(diào)試配置,調(diào)試非常方便。下面就來說下具體步驟,在學(xué)習(xí)的過程中參考了一些博客,放在了最后面。

          環(huán)境準(zhǔn)備

          這個(gè)很簡(jiǎn)單,我就直接拷貝過來了。

          • nodejs: 建議使用 LTS 版本
          • npm: 建議最新版本
          • yeoman : npm install -g yo
          • generator-code : npm install -g generator-code

          另外小TIPS,我們平時(shí)直接安裝的插件所在目錄是~/.vscode/extensions,有興趣的可以看看這些插件是怎么實(shí)現(xiàn)的。

          腳手架

          安裝的yo可以直接生成一個(gè)Hello World版本的插件目錄。執(zhí)行

          yo code

          即會(huì)提示一些問題,按照個(gè)人喜好填寫即可,最后會(huì)生成樣板代碼:

          .
          ├── CHANGELOG.md                 插件變更記錄
          ├── README.md
          ├── extension.js                 插件入口main文件
          ├── jsconfig.json                編輯器關(guān)于js的配置
          ├── package.json                 全局配置
          ├── test                         測(cè)試代碼文件夾
          │   ├── extension.test.js
          │   └── index.js
          ├── vsc-extension-quickstart.md  新手介紹
          └── yarn.lock

          其中的quickstart.md是新手引導(dǎo),里面包含了對(duì)文件的作用解析、如何運(yùn)行插件、測(cè)試插等等,推薦去看一看,我們?cè)谙旅嬉矔?huì)介紹一些。除此之外在package.json里也包含了很多非常重要的信息:

          {
            "name""hello-world", // 插件名
            "displayName""hello-world",
            "description""hello world", // 插件描述
            "version""0.0.1",
            "engines": {
              "vscode""^1.35.0" // 運(yùn)行插件需要vscode最低版本
            },
            "categories": ["Other"],
            "activationEvents": ["onCommand:extension.helloWorld"], // 如何激活插件:在命令面板(Command+Shift+P吊起)輸入helloWorld. 注意command名需要在contributes.commands中有配置
            "main""./extension.js", // 插件入口
            "contributes": {
              "commands": [
                // 此數(shù)組表示插件支持的所有命令
                {
                  "command""extension.helloWorld", // 命令對(duì)應(yīng)的Command,需要和代碼里保持一致
                  "title""Hello World" // 命令的顯示名稱
                }
              ]
            },
            "scripts": {
              // 正常的npm script
              "postinstall""node ./node_modules/vscode/bin/install",
              "test""node ./node_modules/vscode/bin/test"
            },
            "devDependencies": {
              // 依賴包
              "typescript""^3.3.1",
              "vscode""^1.1.28",
              "eslint""^5.13.0",
              "@types/node""^10.12.21",
              "@types/mocha""^2.2.42"
            }
          }

          啟動(dòng)、調(diào)試插件

          啟動(dòng)運(yùn)行

          腳手架生成的其實(shí)就是一個(gè)node應(yīng)用,直接按F5即可運(yùn)行。對(duì)配置感興趣的也可以查看根目錄下的.vscode/launch.json

          跑起來以后默認(rèn)會(huì)新開一個(gè)vscode窗口,然后會(huì)發(fā)現(xiàn)什么都沒有發(fā)生,這是由插件的啟動(dòng)方式?jīng)Q定的,配置于package.json里的activationEvents項(xiàng)。常用的有:

          • onLanguage   在打開特定語言類型的文件后激活
          • onCommand    在執(zhí)行特定命令后激活

          由于我們的插件是配置的onCommand啟動(dòng),并且指定的命令名是Hello World,所以我們?cè)谛麻_的vscode窗口中按下快捷鍵Command+Shift+P后再找到Hello World,選中并執(zhí)行即可。



          最后順利的話,編輯器右下角會(huì)彈出Hello World!。



          如果細(xì)心的話,還會(huì)在源窗口的控制臺(tái)的調(diào)試控制臺(tái)tab 中看到如下輸出:

          Congratulations, your extension "hello-world" is now active!

          這個(gè)就是由插件的真正代碼部分輸出的了。我們接下來看看extension.js的內(nèi)容:

          // vscode編輯器api入口
          const vscode = require('vscode');

          /**
           * 此生命周期方法在插件激活時(shí)執(zhí)行
           * @param {vscode.ExtensionContext} context
           */

          function activate(context{
            // console的各種方法都是輸出在`調(diào)試控制臺(tái)`tab下
            console.log('Congratulations, your extension "hello-world" is now active!');

            // registerCommand用于注冊(cè)命令并提供具體邏輯,命令名需要和package.json里寫的一致。
            // 回調(diào)函數(shù)在命令被觸發(fā)時(shí)執(zhí)行。
            let disposable = vscode.commands.registerCommand('extension.helloWorld'function({
              // 在編輯器右下角展示一個(gè)message box
              vscode.window.showInformationMessage('Hello World!');
            });

            // 將registerCommand的返回值放入subscriptions可以自動(dòng)執(zhí)行內(nèi)存回收邏輯。
            context.subscriptions.push(disposable);
          }
          exports.activate = activate;

          // 當(dāng)插件被設(shè)置為無效時(shí)執(zhí)行此生命周期鉤子
          function deactivate({}

          module.exports = {
            activate,
            deactivate,
          };

          以上就是此插件的完整邏輯了,配置注釋是很簡(jiǎn)單的。可以看到主要就是兩個(gè)生命周期函數(shù),另外搭配一些編輯器api就完成了。

          調(diào)試

          腳手架已經(jīng)貼心的幫我們加了調(diào)試配置,我們只用添加斷點(diǎn)即可:



          Command 配置

          上面提到了生成一個(gè)command只需要 2 步,先是利用vscode.commands.registerCommand注冊(cè)一個(gè),然后再到package.json里的contributes.commands中配置即可。圍繞command還可以做一些其他事情,最常見的就是配置右鍵菜單和快捷鍵。

          右鍵菜單

          表示右鍵的菜單里出現(xiàn)指定command,配置方法:

          "contributes":{
            "menus": {
              "editor/context": [
                {
                  "when""editorHasSelection && resourceFilename =~ /.js|.vue|.ts/", // 出現(xiàn)時(shí)機(jī),當(dāng)編輯器中有選中文本同時(shí)文件名后綴是js/vue/ts
                  "command""extension.starling_textSearch", // 需要在`contributes.commands`存在此命令
                  "group""6_Starling" // 命令所在的組,右鍵菜單可以分組,組與組之間存在分隔線
                },
              ]
            }
          }



          快捷鍵

          有了快捷鍵后,就不用每次在命令面板里查找并運(yùn)行命令了,同樣是在package.json中配置:

          "contributes": {
            "keybindings": [
              {
                "command""extension.starling_textSearch",
                "key""ctrl+f11", // 在Windows上的快捷鍵
                "mac""cmd+f11", // 在mac上的快捷鍵
                "when""editorTextFocus" // 出現(xiàn)時(shí)機(jī), 當(dāng)編輯器焦點(diǎn)在某個(gè)文本中
              }
            ],
          }

          發(fā)布

          主要參考的是官方文檔

          首先需要安裝vsce工具:

          npm install -g vsce

          本地打包將插件打包成.vsix文件。

          vsce package

          會(huì)在項(xiàng)目根目錄生成hello-world-0.0.1.vsix,然后在編輯器的插件面板選擇從VSIX安裝即可:



          發(fā)布到插件市場(chǎng)

          • 需要獲取一個(gè)token,參考官方文檔
          • 利用token創(chuàng)建一個(gè)publisher,這是在插件市場(chǎng)的用戶
          vsce create-publisher (publisher name)
          • 本地登錄此用戶
          vsce login (publisher name)
          • 發(fā)布插件
          vsce publish

          順利的話在控制臺(tái)會(huì)提示發(fā)布成功,然后過幾分鐘就可以在插件市場(chǎng)搜到自己的插件啦!??

          版本升級(jí)

          當(dāng)插件內(nèi)容發(fā)生變更時(shí),重新發(fā)布時(shí)最好更新版本號(hào),vsce可以遵循語義化版本指定升級(jí)大(major)/小(minor)/補(bǔ)丁(patch)版本,也可以直接指定版本號(hào)。例如只升級(jí)小版本:

          vsce publish minor

          如果插件代碼在gitlab上,因?yàn)閭}庫在內(nèi)網(wǎng),需要事先將README里的圖片替換為公網(wǎng)cdn上的路徑。

          snippets

          snippets是代碼片段,可以理解為代碼快捷鍵,在輸入很少量觸發(fā)代碼后即可聯(lián)想出一大坨關(guān)聯(lián)代碼,非常方便。對(duì)于js、ts、vue都可以在插件市場(chǎng)找到非常多的snippets插件。

          開發(fā)snippets只用兩步:

          • 編寫snippets映射文件,它是一個(gè)json,例如javascript.json:
          {
            "this$t": {
              "prefix""tt'", // 觸發(fā)代碼
              "body": [
                // 聯(lián)想出來的關(guān)聯(lián)代碼
                "this.\\$t('${1:key}')" // ${1: key} 是占位符,聯(lián)想出來后會(huì)自動(dòng)聚焦在這里
              ],
              "description""this.$t" // snippets描述,當(dāng)有多個(gè)匹配的代碼片段時(shí),可以用來識(shí)別
            }
          }
          • 在package.json中配置
          "contributes": {
            "snippets": [
              {
                "language""javascript", // 代碼片段起作用的語言類型
                "path""./src/snippets/javascript.json" // 對(duì)應(yīng)的映射文件
              }
            ]
          }

          最后就可以在編輯器看到效果了:



          • 更多細(xì)節(jié)參考snippets-syntax

          插件默認(rèn)配置

          很多插件是需要一些額外配置才能工作的,設(shè)置默認(rèn)配置同樣在package.json里:

          "contributes": {
            "configuration": { // 默認(rèn)配置
              "type""object",
              "title""",
              "required": [
                "sid"
              ],
              "properties": {
                "includes": {
                  "type""Array",
                  "default": [
                    "json"
                  ],
                  "description""文件類型過濾器"
                }
              }
            },
          }

          默認(rèn)配置是json schema格式,在覆蓋默認(rèn)配置時(shí)如果校驗(yàn)出錯(cuò)會(huì)有提示。

          插件中使用getConfiguration來讀取配置:

          function getConfig() {
            const config = vscode.workspace.getConfiguration();
            const includes: string[] | undefined = config.get('includes'); // 獲取指定配置項(xiàng)

            return {
              includes: includes || [],
            };
          }

          監(jiān)聽配置項(xiàng)修改

          在用戶安裝了插件后,可能會(huì)修改配置,如何實(shí)時(shí)監(jiān)聽配置項(xiàng)的修改呢?vscode提供了onDidChangeConfiguration事件監(jiān)聽。

          vscode.workspace.onDidChangeConfiguration(function(event{
            const configList = ['includes'];
            // affectsConfiguration: 判斷是否變更了指定配置項(xiàng)
            const affected = configList.some(item => event.affectsConfiguration(item));
            if (affected) {
              // do some thing ...
            }
          });

          常見編輯器 api

          所有vscode相關(guān)api都可以在官網(wǎng)文檔查找,vscode內(nèi)部也集成了.d.ts文件,編輯器內(nèi)直接跳轉(zhuǎn)定義即可。這里只列舉一些常見的api.

          • messgae

          用于展示提示性消息,出現(xiàn)在編輯器右下角,而不是頂部或右上角。

          和console類似,提供了普通消息、警告消息、錯(cuò)誤消息。

          vscode.window.showInformationMessage('普通消息');
          vscode.window.showWarningMessage('警告消息');
          vscode.window.showErrorMessage('錯(cuò)誤消息');

          消息也支持交互按鈕,當(dāng)選中按鈕時(shí)返回的是按鈕本身:

          vscode.window.showErrorMessage(`與starling的遠(yuǎn)程交互依賴vscode-starling.sid配置項(xiàng)`'打開配置項(xiàng)').then(selection => {
            if (selection === '打開配置項(xiàng)') {
              vscode.commands.executeCommand('workbench.action.openSettings');
            }
          });



          input box

          在編輯器頂部展示一個(gè)input輸入框,使用vscode.window.showInputBox,會(huì)返回一個(gè)Promise:

          const text: string | undefined = await vscode.window.showInputBox({
            '最后一步,輸入文案'
          })



          quick pick

          用于從一組選項(xiàng)中選擇一個(gè),類似于select組件。使用vscode.window.showQuickPick,同樣返回一個(gè)Promise,resolve時(shí)得到被選中的選項(xiàng)或undefined:

          const lang: string | undefined = await vscode.window.showQuickPick(['en''zh''ja'], {
            placeHolder'第一步:選擇語言',
          });



          每個(gè)選項(xiàng)也可以是對(duì)象類型:

          const option: Object | undefined = await vscode.window.showQuickPick([{ id1name'a' }, { id2name'b' }, { id3name'c' }], {
            placeHolder'select an option',
          });

          output channel

          在利用Control + ~打開控制臺(tái)后,會(huì)出現(xiàn) 4 個(gè)tab,從左到右依次是問題、輸出、調(diào)試控制臺(tái)、終端。output channel就是用于控制輸出 tab的內(nèi)容,可以往其中追加文本、追加行、清空,可以將其看成一個(gè)簡(jiǎn)單的文件。output channel適用于一次展示大量信息.

          使用vscode.window.createOutputChannel創(chuàng)建output channel實(shí)例,然后就可以操作各種api了。

          const opc = vscode.window.createOutputChannel('textSearch'); // 可以有多個(gè)OutputChannel共存,使用參數(shù)名區(qū)分

          opc.clear(); // 清空
          opc.appendLine('水電費(fèi)'); // 追加一行
          opc.show(); // 打開控制臺(tái)并切換到OutputChannel tab

          一個(gè)例子:



          file selector

          有些時(shí)候需要操作本地文件系統(tǒng),例如選擇某個(gè)文件、將文件保存到指定位置等。

          • 保存文件到指定位置使用showSaveDialog,它會(huì)打開文件選擇器彈窗,選擇了保存路徑后點(diǎn)擊確定會(huì)返回選中的路徑,如果點(diǎn)擊取消會(huì)返回undefined。
          // 讓用戶手動(dòng)選擇文件的的存儲(chǔ)路徑
          const uri = await vscode.window.showSaveDialog({
            filters: {
              zip: ['zip'], // 文件類型過濾
            },
          });
          if (!uri) {
            return false;
          }

          writeFile(uri.fsPath); // 寫入文件
          • 文件選擇showOpenDialog同樣會(huì)打開文件選擇器彈窗,不過這次是用于選擇文件,如果有選擇文件會(huì)返回選中的文件路徑,反之返回undefined。
          // showOpenDialog返回的是文件路徑數(shù)組
          const uris = await window.showOpenDialog({
            canSelectFoldersfalse// 是否可以選擇文件夾
            canSelectMany: false// 是否可以選擇多個(gè)文件
            filters: {
              json: ['json'], // 文件類型過濾
            },
          });

          if (!uris || !uris.length) {
            return;
          }

          handleFiles(uris);



          hover

          有時(shí)候需要在hover到文本上時(shí)展示一些提示信息,例如eslint插件在hover到不合規(guī)的代碼上時(shí)會(huì)展示具體違反了哪些規(guī)則:



          處理hover需要注冊(cè)一個(gè)hover處理器,vscode會(huì)在hover到文本上時(shí)自動(dòng)調(diào)用處理器,同時(shí)傳遞hover相關(guān)的信息。例如一個(gè)展示光標(biāo)所在的單詞hover處理器:

          /**
           * document: 打開的文本
           * position:hover的位置
           * token: 用于取消hover處理器作用
           */

          async function hover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken{
            const line = document.lineAt(position).text; // 光標(biāo)所在的行
            // getWordRangeAtPosition獲取光標(biāo)所在單詞的行列號(hào)范圍;getText獲取指定范圍的文本
            const positionWord = document.getText(document.getWordRangeAtPosition(position));

            console.log('光標(biāo)所在位置的單詞是:', positionWord);
          }

          // registerHoverProvider的第一個(gè)參數(shù)數(shù)組表明此處理器的作用范圍
          const hoverDisposable = vscode.languages.registerHoverProvider(['javascript''vue'], {
            provideHover: hover,
          });

          context.subscriptions.push(hoverDisposable);

          selection

          與hover類似,有時(shí)候需要處理選中的文本,獲取它是通過vscode.TextEditor實(shí)例上的屬性,有兩個(gè)相關(guān)屬性

          • selections:所有被選中的文本信息
          • selection:第一個(gè)被選中的文本信息, 等同于selections[0]

          獲取TextEditor的一個(gè)方法是通過注冊(cè)textEditorCommand,會(huì)在回調(diào)函數(shù)里提供TextEditor實(shí)例,例如展示選中文本:

          let command = vscode.commands.registerTextEditorCommand('extension.selection'function(textEditor, edit{
            const text = textEditor.document.getText(textEditor.selection);
            console.log('選中的文本是:', text);
          });

          context.subscriptions.push(command);

          FileSystemWatcher

          用于監(jiān)聽文件是否發(fā)生了變化,可以監(jiān)聽到新建、更新、刪除這 3 種事件,也可以選擇忽略其中某個(gè)類型事件。創(chuàng)建watcher是利用vscode.workspace.createFileSystemWatcher:

          function createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher;

          例如監(jiān)聽所有js文件的變動(dòng):

          const watcher = vscode.workspace.createFileSystemWatcher('*.js'falsefalsefalse);
          watcher.onDidChange(e => { // 文件發(fā)生更新
            console.log('js changed,' e.fsPath);
          });
          watcher.onDidCreate(e => { // 新建了js文件
            console.log('js created,' e.fsPath);
          });
          watcher.onDidDelete(e => { // 刪除了js文件
            console.log('js deleted,' e.fsPath);
          });

          參考文章

          • https://code.visualstudio.com/api
          • VSCode插件開發(fā)全攻略:https://www.cnblogs.com/liuxianan/p/vscode-plugin-overview.html
          • VSCode插件開發(fā)急速入門:https://juejin.im/entry/6844903640826642440



          最后


          • 歡迎加我微信(winty230),拉你進(jìn)技術(shù)群,長期交流學(xué)習(xí)...

          • 歡迎關(guān)注「前端Q」,認(rèn)真學(xué)前端,做個(gè)專業(yè)的技術(shù)人...

          點(diǎn)個(gè)在看支持我吧
          瀏覽 57
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美操逼亚洲操逼 | 日日夜夜影音先锋 | 女人18片毛片60分钟播放在线 | 精品免费视频 | 尹人大香蕉网 |