怎么進行vscode插件開發?本篇文章帶大家一起開發一個vscode百度翻譯插件,希望對大家有所幫助!
每次給元素取className的時候總是時不時的要去百度翻譯下,大大的減慢了開發速度,這款簡易版的vscode百度翻譯插件,直接寫中文選中輕松一鍵轉換為英文,也可選中英文進行翻譯。【推薦學習:《vscode》】
一、項目搭建
項目搭建可直接采用官方腳手架。
安裝腳手架
npm?install?-g?yo?generator-code
項目生成
yo?code
新生成的項目結構如圖:
項目運行
直接按F5即可運行,運行成功后會彈出一個新的vscode窗口,窗口標題會注明擴展開發主機。
二、準備工作
由于該插件采用的是百度翻譯的api,所有首先需要使用百度賬號登錄vscode,注冊成為開發者,獲得APPID以及APPKEY。
接入方式
通過調用通用翻譯API,傳入待翻譯的內容,并指定要翻譯的源語言(支持源語言語種自動檢測)和目標語言種類,就可以得到相應的翻譯結果。
請求api如下:
/* ????q:請求翻譯的字段,utf-8編碼 ????from:翻譯源語言,可以設置為auto,自動檢測 ????to:翻譯目標語言 ????appid:APP?ID ????salt:隨機數 ????sign:appid+q+salt+密鑰的MD5值 */ https://fanyi-api.baidu.com/api/trans/vip/translate?q=&from=&to=&appid=&salt=&sign=
具體文檔可查看vscode
三、項目開發
主要的開發文件就是清單文件package.JSon以及入口文件extension.js
package.json
配置如下:
{ //?插件名,必須用全小寫無空格的字母組成? "name":?"vscode-translate-plugin", //?插件市場所顯示的插件名稱。 "displayName":?"vscode-translate-plugin", //?插件描述 "description":?"vscode?百度翻譯插件", //?插件版本 "version":?"0.0.1", //?插件圖標,最小128x128像素 "icon":?"img/icon.png", //?插件最低支持的vscode版本支持 "engines":?{ "vscode":?"^1.50.0" }, //?插件應用市場分類,可選值:?[Programming?Languages,?Snippets,?Linters,?Themes,?Debuggers,?Formatters,?Keymaps,?SCM?Providers,?Other,?Extension?Packs,?Language?Packs] "categories":?[ "Other" ], //?激活事件數組 "activationEvents":?[ "onCommand:vscode-translate-plugin.helloWorld" ], //?插件入口 "main":?"./extension.js", //?描述插件的發布內容 "contributes":?{ "commands":?[ ????????????????????????{ ????????????????????????????"command":?"vscode-translate-plugin.helloWorld", ????????????????????????????"title":?"Hello?World" ????????????????????????} ??????????????????] ?????????}, "scripts":?{ "lint":?"eslint?.", "pretest":?"npm?run?lint", "test":?"node?./test/runTest.js" }, "devDependencies":?{ "@types/vscode":?"^1.50.0", "@types/glob":?"^7.1.3", "@types/mocha":?"^8.0.0", "@types/node":?"^12.11.7", "eslint":?"^7.9.0", "glob":?"^7.1.6", "mocha":?"^8.1.3", "typescript":?"^4.0.2", "vscode-test":?"^1.4.0" } }
主要是配置activationEvents和contributes這兩個配置項
1、activationEvents
插件在VS Code中默認是沒有激活的,那要怎么激活呢?可以通過activationEvents進行配置,目前有以下幾種激活時機。
- onLanguage:${language}? 特定語言文件打開時激活
- onCommand:${command} ?調用命令時激活事件
- onDebug ?調試會話啟動前激活
- workspaceContains:${toplevelfilename} ?文件夾打開后,且文件夾中至少包含一個符合glob模式的文件時觸發。
- onFileSystem:${scheme} ?從協議(scheme)打開的文件或文件夾打開時觸發。通常是file-協議,也可以用自定義的文件供應器函數替換掉,比如ftp、ssh
- onView:${viewId} ?指定的視圖id展開時觸發
- onUri ?插件的系統級URI打開時觸發
- *? 當VS Code啟動時觸發
該翻譯插件在這里配置了三個命令:
"activationEvents":?[ ???????//?將英文翻譯成中文命令 ??????"onCommand:extension.translateToZh", ???????//?將中文翻譯成英文命令 ??????"onCommand:extension.translateToEn", ???????//?將中文替換成相應中文的命令 ??????"onCommand:extension.replaceWithEn" ??],
2、contributes
主要有以下配置
- configuration?JSON格式的鍵值對,VS Code為用戶提供了良好的設置支持,該配置項中配置的內容會暴露給用戶,用戶可以從“用戶設置”和“工作區設置”中修改你暴露的選項。
- commands? 設置命令標題和命令體
- menus ?為編輯器或者文件管理器設置命令的菜單項,菜單項至少包含選中時調用的命令和何時顯示這個菜單項。也可以為該菜單項設置顯示的位置。
- keybindings? 快捷鍵綁定
- languages? 配置一門語言,引入一門新的語言或者加強VS Code已有的語言支持。
- debuggers? 配置VS Code的調試器
- breakpoints ?通常調試器插件會有contributes.breakpoints入口,插件可以在這里面設置哪些語言可以設置斷點。
- grammars ?為一門語言配置TextMate語法。
- themes ?為VS Code添加TextMate主題。
- snippets ?為語言添加代碼片段。
- jsonValidation? 為json文件添加校驗器。
- views ?為VS Code 添加視圖。
- problemMatchers ?配置問題定位器的模式。
- problemPatterns ?配置可以在問題定位器中可以使用的問題模式的名稱。
- taskDefinitions ?配置和定義一個Object結構,定義系統中唯一的配置任務。
- colors? 這些色彩可用于狀態欄的編輯器裝飾器。
該翻譯插件的配置如下:
"contributes":?{ ????//?命令 ????"commands":?[ ????????{ ????????????"command":?"extension.translateToZh", ????????????"title":?"translateToZh" ???? }, ????????{ ????????????"command":?"extension.translateToEn", ????????????"title":?"translateToEn" ????????}, ????????{ ????????????"command":?"extension.replaceWithEn", ????????????"title":?"replaceWithEn" ????????} ?????], ????//?快捷鍵綁定 ????"keybindings":[ ????????{ ???????????//?命令 ???????????"command":?"extension.translateToZh", ???????????//?windows快捷鍵綁定 ????????????"key":?"ctrl+shift+t", ???????????//?mac快捷鍵綁定 ????????????"mac":?"cmd+shift+t", ????????????"when":?"editorTextFocus" ????????}, ????????{ ????????????"command":?"extension.translateToEn", ????????????"key":?"ctrl+shift+e", ????????????"mac":?"cmd+shift+e", ????????????"when":?"editorTextFocus" ????????}, ????????{ ????????????"command":?"extension.replaceWithEn", ????????????"key":?"ctrl+shift+r", ????????????"mac":?"cmd+shift+r", ????????????"when":?"editorTextFocus" ????????} ????], ????//?菜單 ????"menus":?{ ????????//?編輯器上下文菜單,即點擊鼠標右鍵出來的菜單 ????????"editor/context":?[ ????????????{ ???????????? //?編輯器聚焦時 ????????????????"when":?"editorFocus", ????????????????//?點擊菜單項觸發的命令 ????????????????"command":"extension.translateToZh", ????????????????//?分組排序,navigation組始終在最上方 ????????????????"group":?"navigation" ????????????}, ????????????{ ????????????????"when":?"editorFocus", ????????????????"command":"extension.translateToEn", ????????????????"group":?"navigation" ????????????}, ????????????{ ????????????????"when":?"editorFocus", ????????????????"command":"extension.replaceWithEn", ????????????????"group":?"navigation" ????????????} ????????] ????}, ????//?插件配置項 ????"configuration":?{ ????????"type":?"object", ????????"title":?"translate?configuration", ????????"properties":?{ ???????? //?百度翻譯請求api ????????????"translate.url":?{ ????????????????"type":?"string", ????????????????"default":?"****", ????????????????"description":?"百度翻譯API" ????????????}, ????????????//?百度翻譯appId ????????????"translate.appId":?{ ????????????????"type":?"string", ????????????????"default":?"****", ????????????????"description":?"百度翻譯appId" ????????????}, ????????????//?百度翻譯appKey ????????????"translate.appKey":?{ ????????????????"type":?"string", ????????????????"default":?"****", ????????????????"description":?"百度翻譯appKey" ????????????} ????????} ??????} ??},
extension.js
該文件為插件的入口文件,一般包括兩個函數activate和deactivate。其中activate函數是插件激活時也就是在注冊的activationEvents發生的時候就會執行。deactivate中放的是插件關閉的代碼。
我們需要在插件激活的時候注冊activationEvents里配置的命令,并且實現該命令的觸發函數,然后給插件訂閱該命令。
完整代碼如下
const?vscode?=?require('vscode'); const?request?=?require('request') const?crypto?=?require('crypto') const?randomstring?=?require('randomstring') //?md5函數 function?getMD5(content)?{ ????if?(!content)?{ ???? return?content ????} ????let?md5?=?crypto.createHash('md5') ????md5.update(content) ????let?d?=?md5.digest('hex') ????return?d.toLowerCase() } //?翻譯函數 function?translate(targetType)?{ ????return?new?Promise((resolve,?reject)?=>?{ ????????//?打開的vscode窗口對象 ????????const?editor?=?vscode.window.activeTextEditor ????????//?若沒有打開的窗口,則返回 ????????if?(!editor)?{ ????????????console.log('no?open?text?editor') ????????????return ????????} ????????//?選中的文本位置 ????????let?selection?=?editor.selection ????????//?獲取選中的文本 ????????let?text?=?editor.document.getText(selection) ????????//?沒有選中的文本,則返回 ????????if?(!text)?{ ????????????console.log('no?choosed?text') ????????????return ????????} ????????//?隨機數 ????????let?salt?=?(new?Date()).getTime()?+?randomstring.generate() ????????//?獲取package.json里的配置項 ????????const?config?=?vscode.workspace.getConfiguration() ????????//?請求百度翻譯api,翻譯選中的文本 ????????request.post({ ????????????url:?config.get("translate.url"), ????????????formData:?{ ????????????????q:?text, ????????????????from:?'auto', ????????????????to:?targetType, ????????????????appid:?config.get("translate.appId"), ????????????????salt:?salt, ????????????????sign:?getMD5(config.get("translate.appId")?+?text?+?salt?+?config.get("translate.appKey")) ??????????} ????????},?function?(err,?res,?body)?{ ????????????if?(err)?{ ????????????????vscode.window.showInformationMessage('翻譯出錯了:'?+?err.message) ????????????????return ????????????} ????????????try?{ ????????????????let?msg?=?JSON.parse(body); ????????????????if?(msg.error_code)?{ ????????????????????vscode.window.showInformationMessage('翻譯出錯了:'?+?msg.error_msg); ????????????????}?else?{ ????????????????????//?返回翻譯結果 ????????????????????resolve((msg.trans_result)[0].dst) ????????????????} ????????????}?catch?(e)?{ ???????????? vscode.window.showInformationMessage('翻譯出錯了:'?+?e.message); ????????????} ????????}) ????}) } //?文本替換函數,將當前選中的文本替換為傳進來的val const?insertText?=?(val)?=>?{ ????const?editor?=?vscode.window.activeTextEditor ????if?(!editor)?{ ????????vscode.window.showErrorMessage('no?open?text?editor') ????????return ????} ????const?selection?=?editor.selection ????const?range?=?new?vscode.Range(selection.start,?selection.end) ????editor.edit((editBuilder)?=>?{ ???? editBuilder.replace(range,?val) ????}) } /** ?*?@param?{vscode.ExtensionContext}?context ?*/ //?插件激活時的入口 function?activate(context)?{ ????//?注冊命令 ????//?翻譯成中文 ????var?transToZhDisposable?=?vscode.commands.registerCommand('extension.translateToZh',?function?()?{ ????????translate('zh').then(res?=>{ ????????????//?vscode窗口右下角顯示翻譯內容 ????????????vscode.window.showInformationMessage(decodeURIComponent(res)); ????????}) ????}) ????//?翻譯成英文 ????var?transToEnDisposable?=?vscode.commands.registerCommand('extension.translateToEn',?function?()?{ ????????translate('en').then(res?=>{ ???????? vscode.window.showInformationMessage(decodeURIComponent(res)); ????????}) ????}) ????//?將中文替換為英文 ????var?replaceWithEnDisposable?=?vscode.commands.registerCommand('extension.replaceWithEn',?function?()?{ ????????translate('en').then(res?=>{ ???????? //?將選中的中文替換成相應的英文 ???????? insertText(res) ????????}) ????}) ????//?vscode訂閱注冊的命令 ????context.subscriptions.push(transToZhDisposable); ????context.subscriptions.push(transToEnDisposable); ????context.subscriptions.push(replaceWithEnDisposable); } exports.activate?=?activate; //?插件釋放的時候觸發 function?deactivate()?{} module.exports?=?{ ????activate, ????deactivate }
至此開發完成,按F5即可運行項目。按下Ctrl+Shift+P打開vscode的命令面板,輸入插件中注冊的命令,即可執行。我們也添加了相應的快捷鍵和菜單,直接使用快捷鍵或者點擊鼠標右鍵出現的菜單都可以執行相應的命令。
四、插件發布
插件發布可參考文章《VSCode插件開發全攻略(十)打包、發布、升級》
https://www.cnblogs.com/liuxianan/p/vscode-plugin-publish.html
更多關于VSCode的相關知識,請訪問:vscode!!