头图

从0到1开发一款自己的vscode插件

执鸢者
English

一、vscode插件是什么?

大家对vscode肯定都不陌生,其是微软推出的一款轻量级代码编辑器,在使用的时候总会时不时的安装一些插件去协助我们进行开发,这些插件就是利用vscode给我们开放的一些API的基础上进行扩展功能的开发,从而解决开发中的一些问题,提高生产效率。这种插件化思想一方面使该代码编辑器更轻量化;另一方面能够充分利用社区的力量,为其提供更加多元化的插件。(下图是我做的一个小插件的效果图)

vscodePlugin.gif

二、vscode插件能做什么?

vscode插件能做什么?其核心点在于vscode为其提供了哪些开放能力,只有其开放的能力才能为我们所用,就官网来看,利用vscode插件能够做以下事情(该部分来自于vscode官网扩展能力概述部分):
  1. 通用功能
可以在任何扩展中使用的核心功能,主要包括以下几点:

(1)能够添加命令、配置项、快捷键、菜单项、右键菜单;

(2)存储工作区或全局数据;

(3)展示通知信息;

(4)使用快速选择收集用户的输入;

(5)打开文件选择器让用户去选择文件或文件夹;

(6)使用Progress API去阐述长时间运行的操作;

  1. 主题化
控制vscode的外观,包括编辑器中源代码的颜色和vscode ui的颜色,其主要包含三种类型的主题:

(1)颜色主题:其允许将颜色应用于VS Code UI组件和编辑器中的文本;

(2)文件图标主题:文件图标显示在VS Code UI中的位置,例如文件资源管理器、快速打开列表和编辑器选项卡;

(3)产品图标主题:在整个UI中使用的一组图标

  1. 声明性语言特性
声明性语言功能为编程语言添加了基本的文本编辑支持,例如括号匹配、自动缩进和语法突出显示。
  1. 程序语言特性
编程语言功能添加了丰富的编程语言支持,例如悬停、转到定义、诊断错误、IntelliSense 和 CodeLens。
  1. 扩展工作台
工作台是指包含标题栏、活动栏、侧边栏、控制板、编辑组、状态栏等UI组件的整体Visual Studio Code UI。VS Code提供了各种API,允许将自己的组件添加到工作台。
  1. 调试
可以通过编写将 VS Code 的调试 UI 连接到特定调试器或运行时的调试器扩展来利用 VS Code 的调试功能。

三、vscode插件实战

vscode插件其实是vscode对外提供了一些能力,如果不是特别需要其实没有必要完整的学习整体内容,仅仅需要了解其大体开发思路、能够解决的问题,之所以这么说是因为(以上纯个人观点,不一定正确)学习该部分的内容需要一定精力,但学后并不一定能够在自己项目中得到使用,深入学习投入于产出并不成正比,所以本次我只会讲述入门级内容,具体的内容扔需要读者在需要这一部分能力的时候再深入研究。

3.1 项目初始化

官方为了方便开发人员进行vscode插件的开发,提供了对yo应的脚手架来生成对应的项目。
// 安装需要的包
npm install -g yo generator-code
// 运行
yo code

上述命令其实安装了两个包(yo和generator-code),这两个包用途如下:

  1. yo模块全局安装后就安装了Yeoman,Yeoman是通用型项目脚手架工具,可以根据一套模板,生成一个对应的项目结构
  2. generator-code模块是VS Code扩展生成器,与yo配合使用才能构建项目。

3.2 重要文件

在项目生成之后,目录结构如下所示,其中最重要的文件是package.json和extension.js,了解这两个文件基本上就可以入门开发一个vscode插件了。

image-20210920155043344.png

#### 3.2.1 package.json

该文件是vscode扩展的清单文件,里面有很多字段,官方对每个字段都进行了详细阐述,本次我们重点阐述以下初始化后期清单文件。
{
    "name": "demo", // 插件名
    "displayName": "插件", // 显示在应用市场的名字
    "description": "我的第一个插件测试", // 具体描述
    "version": "0.0.1", // 插件的版本号
    "engines": {
        "vscode": "^1.60.0" // 最低支持的vscode版本
    },
    "categories": [
        "Other" // 扩展类别
    ],
    // 激活事件组,在那些事件情况下被激活
    "activationEvents": [
        "onCommand:demo.helloWorld"
    ],
    // 插件的主入口文件
    "main": "./extension.js",
    // 贡献点
    "contributes": {
        // 命令
        "commands": [
            {
                "command": "demo.helloWorld",
                "title": "Hello World"
            }
        ]
    },
    "scripts": {
        "lint": "eslint .",
        "pretest": "npm run lint",
        "test": "node ./test/runTest.js"
    },
    // 开发依赖项
    "devDependencies": {
        "@types/vscode": "^1.60.0",
        "@types/glob": "^7.1.3",
        "@types/mocha": "^8.2.2",
        "@types/node": "14.x",
        "eslint": "^7.27.0",
        "glob": "^7.1.7",
        "mocha": "^8.4.0",
        "typescript": "^4.3.2",
        "vscode-test": "^1.5.2"
    }
}
在这份清单文件中,重点关注的主要有三部分内容:activationEvents、main以及contributes,其是整个文件中的重中之重。
  1. main
指明了该插件的主入口在哪,只有找到主入口整个项目才能正常的运转、
  1. activationEvents
指明该插件在何种情况下才会被激活,因为只有激活后插件才能被正常使用,官网已经指明了激活的时机,这样我们就可以按需设置对应时机。(具体每个时机用的时候详细查看即可)
  1. contributes
通过扩展注册contributes用来扩展Visual Studio Code中的各项技能,其有多个配置,如下所示:

3.2.2 extension.js文件

该文件时其入口文件,即package.json中main字段对应的文件(不一定叫extension.js这个名字),该文件中将导出两个方法:activate和deactivate,两个方法的执行时机如下所示:
  1. activate

这是插件被激活时执行的函数

  1. deactivate

这是插件被销毁时调用的方法,比如释放内存等。

3.3 实战

上述已经对vscode插件有了基础的认识,下面就进行一个简单的实战,打造属于自己的一个vscode插件,此插件的功能如下:
  1. 通过在文件编辑区域或文件名上右击弹出按钮,点击按钮获取文件的大小、创建时间和修改时间;
  2. 如果获取的是文件夹,则指明该文件是文件夹,不是文件,给予提示。

3.3.1 package.json修改项

{
    // ……
    // 在getFileState指令下激活
    "activationEvents": [
        "onCommand:getFileState"
    ],
    // 入口文件
    "main": "./extension.js",
    "contributes": {
        // 命令
        "commands": [
            {
                "command": "getFileState",
                "title": "File State"
            }
        ],
        // 菜单项
        "menus": {
            // 编辑上下文菜单
            "editor/context": [
                {
                    "when": "editorFocus",
                    "command": "getFileState",
                    "group": "navigation"
                }
            ],
            // 资源管理器上下文菜单
            "explorer/context": [
                {
                    "command": "getFileState",
                    "group": "navigation"
                }
            ]
        }
    },
    // ……
}

3.3.2 主函数内容

const vscode = require('vscode');
const fs = require('fs');

function activate(context) {
    console.log('插件已经被激活');

    // 注册命令
    let commandOfGetFileState = vscode.commands.registerCommand('getFileState', uri => {
        // 文件路径
        const filePath = uri.path.substring(1);
        fs.stat(filePath, (err, stats) => {
            if (err) {
                vscode.window.showErrorMessage(`获取文件时遇到错误了${err}!!!`)
            }

            if (stats.isDirectory()) {
                vscode.window.showWarningMessage(`检测的是文件夹,不是文件,请重新选择!!!`);
            }

            if (stats.isFile()) {
                const size = stats.size;
                const createTime = stats.birthtime.toLocaleString();
                const modifyTime = stats.mtime.toLocaleString();

                vscode.window.showInformationMessage(`
                    文件大小为:${size}字节;
                    文件创建时间为:${createTime};
                    文件修改时间为:${modifyTime}
                `, { modal: true });
            }
        });
        
        const stats = fs.statSync(filePath);
        console.log('stats', stats);
        console.log('isFile', stats.isFile());
    });

    // 将命令放入其上下文对象中,使其生效
    context.subscriptions.push(commandOfGetFileState);
}

function deactivate() {}

module.exports = {
    activate,
    deactivate
}

3.3.3 效果图

经过开发后,该插件调试效果如下所示:

vscodePlugin.gif

3. 4 发布

插件看法完毕之后就是需要分享出去供大家使用,目前有三种方式:
  1. 直接把文件夹发给别人,让别人找到vscode的插件存放目录并放进去,然后重启vscode,一般不推荐;
  2. 打包成vsix插件,然后发送给别人安装,如果你的插件涉及机密不方便发布到应用市场,可以尝试采用这种方式;
  3. 注册开发者账号,发布到官网应用市场,这个发布和npm一样是不需要审核的。
每一种方式都可行,并且网上也有很多教程讲述其发布方式,今天我重点讲述一下第二种,毕竟在插件这么多的情况下,很多人更乐于开发一款属于自己的专用插件或者特定自己领域使用的插件,完全没必要发布到应用市场。
  1. 安装对应的模块vsce
npm i vsce -g
  1. 利用vsce进行打包,生成对应的vsix文件
vsce package

image-20210921110023059.png

  1. 安装到vscode

image-20210921110123792.png

  1. 安装完成之后就可以正常的进行使用了

image-20210921110210450.png

四、总结

因为工作中目前还没有遇到这种需求,此次我只是对vscode插件的开发流程进行了一个简单的概述,并没有进一步深入探索,待工作中有这样的场景需要这样的能力去解决某些问题时,能够快速反应有这样的解决方案,再进一步学习也为时不晚,也希望爱学习的小伙伴们也对这一部分能够有一定了解,弥补自己知识上欠缺的一环,后续为己所用。

五、参考文献

vscode插件编写实战

vscode插件开发全攻略

官方文档

1.如果觉得这篇文章还不错,来个分享、点赞吧,让更多的人也看到

2.欢迎关注公众号前端点线面,开启前端救赎之路。

阅读 2.3k

摸摸头,编程使我快乐。

1.4k 声望
2.5k 粉丝
0 条评论
你知道吗?

摸摸头,编程使我快乐。

1.4k 声望
2.5k 粉丝
宣传栏