vscode插件介绍
vscode插件能做的事大家应该都不陌生,比如常用的ESLint
、Prettier
等,这些插件提高了我们的开发效率。我们通过学习也是能够开发出类似功能的插件,因为vscode是由Electron开发的,其插件的实现方式主要就是js+html
等前端技术实现。其插件发布方式也是类似于npm,只不过是具有一定的规范的vsix
文件。这些技术作为一名前端开发来说都是耳熟能详的技能,我们要做的就是学习vscode提供的api并将以实现。
搭建插件的工程、开发流程、发包流程都可以在网上找到,这里就不细说了。
附上我开发插件时参考的部分资料与博客: 官网、VSCode插件开发全攻略
插件开发背景
项目组内有不同的项目,依赖不同的node版本,使用了nvm来做版本管理。每次切换项目,运行项目都要执行nvm list
nvm use [version]
虽然就两行,但一天多的时候要输十几遍,属实麻烦。
想着能不能利用插件达到一键切换的功能。
那么插件要做的事就两步,一是通过nvm list
获取到安装的node各个版本、二是执行一下 nvm use [version]
最后实现的效果如下:
1.在某个文件右键选择切换Node
2.展示当前安装的Node版本和当前选择的Node版本
3.选择要切换的版本,成功后提示
代码实现
1、把功能入口加入右键菜单。
// package.json 部分代码
{
"contributes": {
// 注册指令
"commands": [
{
"command": "demo.changeNode",
"title": "切换Node"
}
],
"menus":{
// 设置指令在文件上右键出现
"explorer/context": [
{
"command": "demo.changeNode",
"group": "2_demo@1",
"when": "explorerResourceIsFolder"
}
]
}
}
}
2.编写指令代码,利用vscodeApi完成交互
// extension.js
const vscode = require('vscode')
const { getNodeAllVersion, switchNode } = require('./util/switchNodeVersionByNvm')
/**
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
context.subscriptions.push(
vscode.commands.registerCommand('demo.changeNode', async () => {
const list = await getNodeAllVersion()
// vscode api 展示快捷选项
const chosen = await vscode.window.showQuickPick(list, {
placeHolder: '选择需要切换的Node版本'
})
try {
const result = await switchNode(chosen.label)
// vscode api 展示Info提示
vscode.window.showInformationMessage(result)
} catch (e) {
// vscode api 展示Info提示
vscode.window.showErrorMessage(e)
}
})
)
}
// this method is called when your extension is deactivated
function deactivate() {}
module.exports = {
activate,
deactivate
}
3.完善getNodeAllVersion, switchNode代码逻辑。
const exec = require('child_process').exec //引入子线程模块
/**
* 获取node所有版本
*/
const getNodeAllVersion = () => {
return new Promise((resolve, reject) => {
exec(`nvm list`, (error, stdout) => {
if (!error) {
if (stdout) {
const version = stdout.match(/([1-9]\d|[1-9])(.([1-9]\d|\d)){2}/g)
const currentVersionIdx = stdout.split('\n').findIndex(i => i.includes('*')) - 1
if (version?.length > 0) {
resolve(
version.map((e, i) => {
return {
label: e,
description: i === currentVersionIdx ? '(当前选择)' : ''
}
})
)
} else {
reject('请安装nvm并使用nvm安装node!')
}
}
} else {
reject(error)
}
})
})
}
/**
* 切换Node版本
* @param {string} version node版本号
*/
const switchNode = version => {
return new Promise((resolve, reject) => {
exec(`nvm use ${version}`, (error, stdout) => {
if (!error) {
resolve(stdout)
} else {
reject(error)
}
})
})
}
module.exports = { getNodeAllVersion, switchNode }
node的子进程exec模块可以帮助我们在代码中执行命令行命令,核心就是利用这个功能对nvm list
nvm use
进行插件封装。
总结
vscode插件开发按照模板即可开发,重点是要识别插件的使用背景并开发其中核心功能。虽然只是一个简简单单的node切换
功能,但他也确实给我们团队带来了效率的提升。