🛠️搭建项目开发工具IDE——Chapter 1 如何编写 VSCode 插件

导语:有些项目会有这样的需求,为开发人员搭建一套开发环境IDE,包含调试窗口、编辑窗口、一系列其他操作;说的通俗一点就是做一个类似微信小程序的 微信web开发者工具 这样的产品。我仔细思考了一下,VSCode本身是一款开源产品,采用Electron和插件配置也能很容易对其界面和功能进行二次开发;于是有了这篇文章,根据时间来记录我的探索。(如果长时间停更了,说明我踩到了无法逾越的坑了_

  • 公司目前已有类似产品——weTerm,具体实现我不太清楚,就界面和配置文件来看应该是基于VSCode的二次开发;
  • 每个阶段的发现,记录在Github:https://github.com/git-yx/vscode
项目阶段(持续更新)
  • 第一阶段——介绍如何开发VSCode插件
  • 第二阶段——详细分析VSCode开源代码

一、开发环境介绍与安装

  1. 安装Visual Studio Code ,我们可以先到官网下载一最新版本的来进行安装,下载完后点击安装,然后一直下一步安装就可以;(注意:创建插件模板之后,会强制你更新VSCode至最新版本,否则运行插件会报error)
  2. 安装 NodeJs ,选择最近的LTS版本即可;
  3. 在安装完上面两个工具后,我们还需要一个生产插件代码的工具,也就是 YeomanVS Code Extension generator; Yeoman的介绍不在本文章中,具体信息可以访问 Yeoman
    ★ 具体命令为:npm install -g yo generator-code

二、生成插件基本结构

在环境配置完成以后,就能使用 yo 命令来生成项目基本结构了。

  • 使用 yo 命令来生成插件基本结构:yo code
    vscode-init.png

可以根据自己需要选择需要的模板类型,此处我选择第一项: > New Extension (TypeScript),如果对于 typescript 不太懂可以查看链接: TypeScript中文网

  • 选择创建项目后有四个输入和一个选择
  1. 输入你扩展的名称
  2. 输入一个标志(项目创建的文件名称用这个)
  3. 输入对这个扩展的描述
  4. 问你要不要创建一个git仓库用于版本管理
  5. 选择使用 NPM 还是 Yarn 来管理依赖
  • 依次回答列举的几个问题,然后就能得到一个崭新的模板了~


    vscode-init-yarn.png
  • 项目初始化之后会得到这样的目录结构:
├── .vscode                     // VS Code的整合
│   ├── launch.json
│   ├── settings.json
│   ├── extensions.json
│   └── tasks.json
├── .vscodeignore                //配置不需要加入最终发布到拓展中的文件
├── README.md
├── src                         // 源文件
│   └── extension.ts            // 如果我们使用js来开发拓展,则该文件的后缀为.js
│   └──  test                        // test文件夹
├── node_modules
├── out                         // 编译之后的输出文件夹(只有TypeScript需要,JS无需)
├── package.json                // 该拓展的资源配置文件
├── tsconfig.json               // ts配置
└── vsc-extension-quickstart.md 

三、插件运行和简单修改

  • 介绍完目录结构后,我们可以来运行一下看看效果如果。我们打开一个VSCode并把我们的插件目录自己拖到vscode的界面上;选择调试窗口,并点击开始调试或者直接按快捷键 F5
    vscode-debug.png
  • 然后我们能看到,VSCode 重新打开了一个窗口:按住 Ctrl + P 可以测试模板命令 > hello world
    vscode-run.gif

我们可以看到扩展插件已经正常的运行了,接下来我们可以来简单修改一下代码以实现不同的简单功能。在修改之前需要简单的认识两个文件

(★) package.json

{
    "name": "first-extension",
    "displayName": "first extension",
    "description": "the first step to create vscode extension",
    "version": "0.0.1",
    "engines": {
        "vscode": "^1.36.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [                                       // 这是我们要理解的地方,是触发插件执行一些代码的配置
        "onCommand:extension.helloWorld"             //这种是通过输入命令来触发执行的
    ],
    "main": "./out/extension.js",                           //这个是配置TypeScript编译成js的输出目录
    "contributes": {
        "commands": [{                                       //title 和 command是一个对应关系的
            "command": "extension.helloWorld",           //这个是对应上面那个命令触发的,在代码里面也要用到
            "title": "Hello World"                           //这个是我们在vscode里面输入的命令
        }]
    },
    "scripts": {                                                //是在发布打包,或者其他运行时候,要执行的一些脚本命令
        "vscode:prepublish": "yarn run compile",
        "compile": "tsc -p ./",
        "watch": "tsc -watch -p ./",
        "pretest": "yarn run compile",
        "test": "node ./out/test/runTest.js"
    },
    "devDependencies": {                                //这是开发的依赖包,如果有其他的依赖包,并要打包的话,需要把dev去掉
        "@types/glob": "^7.1.1",
        "@types/mocha": "^5.2.6",
        "@types/node": "^10.12.21",
        "@types/vscode": "^1.36.0",
        "glob": "^7.1.4",
        "mocha": "^6.1.4",
        "typescript": "^3.3.1",
        "tslint": "^5.12.1",
        "vscode-test": "^1.0.0-next.0"
    }
}

(★) extension.ts

  • 这个文件我简单梳理了一下,将英文去掉了,增加了一些简单描述。
// 导入 vscode 全局api
import * as vscode from 'vscode';                  
// 暴露 命令被激活执行函数
// 键盘组合键 ctrl + p 可以输入指令
export function activate(context: vscode.ExtensionContext) {
    
    // 当接收到指令 执行生命周期
    console.log('ext is now active!');
    
    // 命令定义在 package.json内,此处匹配命令执行函数
    let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {
        vscode.window.showInformationMessage('Hello World!');
    });
    // 挂载执行函数到 vscode上下文中
    context.subscriptions.push(disposable);
}
// 暴露 命令被冻结执行函数
export function deactivate() {
    console.log('ext is now deactive!');
}

这两个文件是很重要的,基本整个插件编写都是围绕着这两个文件来修改的,例如我们现在要增加多一个命令叫做 hello 那么我们先在 package.json 里面添加两个配置

...
"activationEvents": [
    "onCommand:extension.helloWorld",
    "onCommand:extension.hello"
],
"contributes": {
    "commands": [{
        "command": "extension.helloWorld",
        "title": "Hello World"
    },{         
        "command": "extension.hello",
        "title": "hello"
    }]
}
...

添加完这两个配置后,我们就需要在 extension.ts 里来注册这个命令事件

// 根据 package.json 来注册 extension.hello 命令
let hello = vscode.commands.registerCommand('extension.hello',()=>{
    // vscode 的提示接口
    vscode.window.showInformationMessage('hello ~');
});
// 挂载命令到上下文中
context.subscriptions.push(hello);
  • 修改之后再次运行,会发现多了一个 hello 的命令。

四、打包与发布

这里我只介绍将插件打包成本地插件文件,我们的目的是搭建自己的IDE环境,今后只需要搭建一个云存储来存放开发者开发的ext插件即可,不需要上传至微软的仓库中。 若有发布至vscode的需要,可以查看: VSCode插件发布

这里介绍 VSCode插件打包工具 vsce

  • 作用:将已经写好的 插件代码 打包成 vsix 文件,便于插件管理;
  • 安装:yarn add vsce 或者 npm install vsce

一、执行打包

  • cd 到项目目录下,执行命令 vsce package :顺利的话就能在项目根目录下找到 项目名-版本号.vsix 的文件。

  • 错误踩坑:


    vscode-err.png

    在 package.json 文件中增加字段 "publisher": "xxx" 即可;

二、使用插件

  • 按照下图找到 vsix 文件安装入口,选择已经打包好的 vsix 文件即可。


    vscode-ext-install.png
  • 安装完成后,即可在插件->已安装插件 找到自己刚刚安装的插件(如果没找到,请重启VSCode)。


    vscode-show.png

五、归纳整理

这里只介绍了 VSCode 的命令接口,其实VSCode还提供了各种类型的相当多的接口。我们可以根据自己需要来调用合适的接口满足自己的需求。以下,我列举几个常见的 IDE 需要的需求:

  1. 类似 微信web开发者工具 的代码编译、代码预览、代码压缩并提交至云端、用户登录功能;
  2. 针对不同类型文件的代码提示功能;

这里我简单介绍了 VSCode 插件开发的基本步骤,下一节我将会详细分析 VSCode 的开源代码。从布局开始,剖析code的运行机制,插件的插拔机制。

部分图片、文字摘取自:

  • cnblogs:《vscode编写插件详细过程》
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容