是時候開發你自己的vscode擴充套件外掛了

wangzy2019發表於2019-05-16

Visual Studio Code(以下簡稱vscode)是現在非常流行的一款編輯器,相信很多人都在用或者用過,至少也是聽說過。不同於WebStorm這樣的IDE大而全但稍顯笨重,vscode算是比較小巧快速的了,雖然還比不上Sublime Text,但是畢竟自帶了除錯,GIT管理,簡單的程式碼提示等功能,體積大一點也是可以理解的,反正前端開發是比較推薦使用vscode作為首選編輯器的。
vscode的大部分功能都是通過擴充套件外掛來實現的,安裝這些擴充套件可以給我們提供豐富的功能,但是要注意外掛裝的越多越吃效能,這點需要大家按照自己的需求和電腦配置去取捨,不是裝得越多就越好。
大部分使用vscode的人都或多或少的使用過如eslint(程式碼檢查),Prettier(格式化程式碼),GitLens(git增強)等必備擴充套件,講究一點的人還會選擇安裝一些程式碼主題和圖示主題。但是我相信很多人只是安裝使用,並沒有自己開發過擴充套件外掛,今天我就跟大家一起動手開發一個vscode擴充套件。

需求說明

這裡例子是一個工作中真實的需求,由於公司的一個專案中會大量複製貼上一些文案,在一些英文句子中如果出現了中文標點,寫文案的人就會扯皮,說是前端自己寫錯了(明明都是複製貼上的),即使找出證據是寫文案的錯,也會說我們為什麼開發的時候沒檢查出來改掉。秉著前端永不背鍋的態度,我決定開發一個擴充套件來處理這個問題,功能大概就是,檢測檔案中'' "" ``之間的字串,純英文字串(不出現中文字元)出現了中文標點就標記出來,成品效果如下。

演示

原始碼

git地址github.com/hoc2019/vsc…,感興趣的可以star一波,我會把註釋寫的儘量詳細。vscode商店中搜sneak mark也可以找到,目前該擴充套件基本功能已經完成,後續還會不斷更新完善。

擴充套件

準備工作

node環境,如果要釋出的話要有一個git倉庫和微軟賬號,編輯器肯定是用vscode,方便除錯。因為vscode是基於Electron開發,所以外掛也是用Javascript來寫(官方更推薦用Typescript),對前端非常友好。
有人可能會擔心太難,其實大可不必,本來我也覺得開發一個擴充套件很難,但是前段時間vscode出現的楊超越鼓勵師坤坤鼓勵師這樣的粉絲向擴充套件,讓我覺得擴充套件開發應該是一個挺隨意的事(順便一提,坤坤鼓勵師說明配的那是個什麼圖和文字,而且搜尋關鍵詞竟然有雞你太美,作者怕是個黑粉)。

建立專案

建立專案最簡單的方法肯定是使用腳手架,微軟官方推出了基於yeoman的腳手架vscode-generator-code,使用非常簡單。(注:yeoman是一個包含了大量腳手架的腳手架倉庫)

// 全域性安裝yeoman和vscode-generator-code
npm install -g yo generator-code

// 建立專案
yo code
複製程式碼

執行建立命令後,會像使用vue-cli那樣有一些配置選項,我這邊選擇的意思是用ts開發一個新擴充套件,副檔名為sneak mark,擴充套件id為sneak-mark。

yo

專案已經建立完成,用vscode開啟。此時已經是一個簡單的擴充套件,在vscode中按F5(也可以在側邊欄切換到除錯皮膚啟動)會啟動一個新的vscode執行除錯你的程式碼(標題欄會顯示為擴充套件開發主機),開啟命令面版(windows下快捷鍵是ctrl+alt+p)輸入hello world會找一條命令,選中後彈出hello world的提示。

v

專案配置

相關配置是在package.json中,一開始設定的副檔名,擴充套件id之類的在package.json中都可以修改。我們這裡只說明兩個重要的配置,還有一些基礎的和沒用到的配置可以檢視官方專案配置文件。專案配置裡面有一項是擴充套件配置,由於內容比較多而且重要,有單獨的頁面。如果英文看起來比較吃力,可以先看一下這篇VSCode外掛開發全攻略(三)package.json詳解(這篇教程裡面也有比較全面細緻的各項說明)。

{   
    //啟動設定為隨vscode開啟載入
    "activationEvents": [
        "*"
    ],
    //擴充套件配置項,最重要的配置點,官方有單獨的說明頁
    "contributes": {
        //vscode首選項設定裡面的相關內容,這裡允許使用者設定標記的顏色
        "configuration": {
            "type": "object",
            "title": "Sneak mark",
            "properties": {
                "sneakMark.markColor": {
                    "type": "string",
                    "default": "#FF000055",
                    "description": "標記顏色"
                }
            }
        }
    }
}

複製程式碼

這樣配置之後我們的擴充套件就會隨vscode開啟載入,不過為了使用者的體驗,官方不推薦這種載入方式,這樣的擴充套件裝多了,就是vscode開啟變慢的罪魁禍首。我們應該根據擴充套件的功能選擇最優的載入時機,比如我們這個外掛還可以設定為隨著開啟某種格式的檔案載入,比如js和json檔案。

{
    "activationEvents": [
        "onLanguage:javascript",
        "onLanguage:json"
    ]
}
複製程式碼

但是為了以後能檢查指定格式檔案的功能,這裡就先使用隨vscode開啟載入。
首選項設定的效果如下,我們可以拿到使用者設定的顏色值,作為標記的樣式。

設定

功能實現

微軟官方提供了很多擴充套件的示例,基本上你想做的功能,都有類似的示例(示例列表示例程式碼)。
首先實現異常中文標點的標記高亮,用到的功能示例為decorator-sample,流程就是設定一個裝飾集,裝飾集是一個位置物件陣列,vscode的會對裝飾集中的位置進行額外樣式設定。

import * as vscode from 'vscode';
//擴充套件載入後執行的函式
export function activate(context: vscode.ExtensionContext) {
    //匹配被'',"",``符號包裹的文字
    const textRegEx = /(['"`])[\s\S]*?\1/g;
    //匹配需要標識出的標點符號,計劃後期可新增配置
    const charCodeRegEx = /(,|。|‘|’|“|”|?|!)/g;
    //獲取配置中異常中文標點的樣式
    let sneakDecorationType = getSneakDecorationType();
    //編輯中頁面
    let activeEditor = vscode.window.activeTextEditor;
    //更新資料和樣式
    function updateDecorations() {
        //獲取編輯中頁面的文字資訊
        const text = activeEditor.document.getText();
        //裝飾集(這裡就是需要被修改樣式的異常中文標點)
        const sneakCharCodes: vscode.DecorationOptions[] = [];
        let match;
        //迴圈每一個被''""``包裹的異常字串
        while ((match = textRegEx.exec(text))) {
            const initialText = match[0];
            //字串中是否包含中文
            const hasChinese = isChineseChar(initialText);
            //字串中是否含有異常中文標點
            const hasChineseMark = isChineseMark(initialText);
            //若果存在中文或沒有中文標點則跳過後續步驟執行下一次迴圈
            if (hasChinese || !hasChineseMark) {
                continue;
            }
            let charCodeMatch;
            //迴圈異常字串中的每一個字元
            while ((charCodeMatch = charCodeRegEx.exec(initialText))) {
                //異常中文標點實際開始位置為異常字串的位置+異常中文標點在異常字串的位置
                const startIndex = match.index + charCodeMatch.index;
                const startPos = activeEditor.document.positionAt(startIndex);
                const endPos = activeEditor.document.positionAt(startIndex + 1);
                //異常中文標點的範圍
                const decoration = {
                    range: new vscode.Range(startPos, endPos)
                };
                //將異常中文標點的位置新增進裝飾集
                sneakCharCodes.push(decoration);
            }
        }
        //啟用中的編輯頁面應用樣式集
        activeEditor.setDecorations(sneakDecorationType, sneakCharCodes);
    }
    //啟動時存在開啟的編輯頁面自動觸發樣式更新
    if (activeEditor) {
        updateDecorations();
    }
}
複製程式碼

activate這個函式只會在擴充套件載入時執行一次,如果存在開啟的編輯頁面就會標記出異常中文標點,但是後面再開啟別的編輯頁面或者頁面中的內容有修改變化是不會更新的,所以要加兩個監聽事件來觸發。

//防止程式碼敲的太快,防抖一下
function triggerUpdateDecorations() {
        if (timeout) {
            clearTimeout(timeout);
            timeout = undefined;
        }
        timeout = setTimeout(updateDecorations, 500);
    }
//切換編輯頁面事件,會觸發樣式更新
vscode.window.onDidChangeActiveTextEditor(
    editor => {
        activeEditor = editor;
        if (editor) {
            triggerUpdateDecorations();
        }
    },
    null,
    context.subscriptions
);
//編輯頁面中的內容變化,會觸發樣式更新
vscode.workspace.onDidChangeTextDocument(
    event => {
        if (activeEditor && event.document === activeEditor.document) {
            triggerUpdateDecorations();
        }
    },
    null,
    context.subscriptions
);
複製程式碼

功能已基本實現完畢,這裡只是部分程式碼和主要功能,完整程式碼前面給出的github倉庫可以看到,基本每一行程式碼都加了註釋,就是為了方便大家理解學習。

釋出更新

釋出的話有幾種形式,可以直接拷貝資料夾給別人,也可以打包成VSIX讓別人離線安裝,當然最方便的方式還是釋出到vscode擴充套件市場,不過需要先有一個微軟賬號然後建立令牌token。具體的步驟可以參考VSCode外掛開發全攻略(十)打包、釋出、升級這篇教程。
這裡假設已經有了令牌,接下來的步驟是:

  1. 全域性安裝釋出工具
npm i vsce -g
複製程式碼
  1. 建立釋出賬號
vsce create-publisher name
複製程式碼

這裡會需要你設定釋出者的賬號,之後會提示你輸入姓名,郵箱。總得來說和npm包釋出很像,不過沒有登入密碼,而是要填入令牌token。

  1. 釋出和更新
vsce publish
複製程式碼

注意每次釋出package.json中的版本號要有變化。

寫在最後

大功告成,你已經有了自己的vscode擴充套件了,接下來就是去vscode市場欣賞自己的成果,是不是也不是很複雜,而且還很有成就感。 希望大家喜歡我的文章,多多指正交流。

全部文章列表

相關文章