vscode 简单插件玩一下(一)

1,820 阅读5分钟

前言

这几年前端开发,一直采用 vscode 来编写代码,用了很多的插件,但是这些插件是怎么开发的,脑瓜子还是嗡嗡的,所以趁着现在还感兴趣,就来玩一下。不要求开发一个多复杂,能简单了解下其中的原理就行。

如果你感兴趣的话,就继续往后看吧。

vscode 的组织架构

vscode 是基于 Electron 构建的,主要由 Monaco EditorExtension HostLanguage Server Protocol & Debug Adapter Protocol 几部分构成

Monaco Editor - 基于网页的编辑器代码位于 monaco-editor

Extension Host - VSCode 的主进程和插件进程是分开管理的。

用来确保插件:

  • 不影响启动速度
  • 不会减低 UI 响应速度
  • 不会改变 UI 样式

Language Server Protocol & Debug Adapter Protocol - 任现任何语言只要编写对应的语言服务即可

vscode 插件能做什么?

  • 修改主题 - 界面、文本主题色、图标的样式
  • 通用功能 - 添加命令、添加配置项、添加快捷键、添加菜单项、添加右键菜单、获取文本输入、存储数据(localStorage)
  • 程序语言 - 各种语言的高亮、各种语言的调试器、git 代码库管理等
  • 工作区域扩展 - 打开文件、显示网页、显示进度条、活动栏项目等

开发环境搭建

首先我们可以看下 visualstudio-our First Extension 官网第一个 demo。

我们需要安装 YeomanVS Code Extension generator.具体安装如下命令:

npm install -g yo generator-code

完成上面的安装后,我们就可以生成我们的基本代码

yo code

image.png

image.png

走完上述流程,就可以构建一个简单的 vscode 插件目录了。

目录解析

hello-vscode     // 项目根目录
├─.eslintrc.json // eslint 配置
├─.gitignore // git ignore
├─.vscodeignore // 配置不需要加入到最终发版的文件
├─CHANGELOG.md 
├─README.md
├─package-lock.json
├─package.json
├─tsconfig.json // ts 配置
├─vsc-extension-quickstart.md // 插件介绍
├─src   // 我们需要写插件代码的文件
|  ├─extension.ts 
|  ├─test
|  |  ├─runTest.ts
|  |  ├─suite
|  |  |   ├─extension.test.ts
|  |  |   └index.ts
├─.vscode
|    ├─extensions.json
|    ├─launch.json
|    ├─settings.json
|    └tasks.json
├─.git

简单运行

基于上面创建的目录,我们可以直接进行运行。运行方式如下: *第一种: 打开vscode 界面,把我们的hello-vscode 文件夹拖到 vscode 界面中,然后我们选择调试窗口,点击开始调试。

  • 第二种:直接通过 vscode 打开文件目录也行。

image.png

image.png 项目运行起来后,会打开一个新的 vscode 窗口,我们可以通过快捷键打开命令窗口。

image.png

image.png

image.png

官方动态视频如下: code.visualstudio.com/api/get-sta… 上述几张图,就是官方 demo 的运行效果。

简单修改 demo 代码

看了上面的 demo 运行,我们需要怎么进行修改呢?

我们先来认识两个文件extension.tspackage.json。我们做简单修改基本就是围绕这两个文件来进行修改,我们要新增命令行需要怎么修改呢?带着问题我们去进行解析。

package.json

package.json 中和插件有关的主要有 activationEventsmaincontributes 三个配置

activationEvents - 官方文档

在demo 中的extension.ts 中的 helloWorld 命令必须在这里面进行注册 hello-vscode.helloWorld , 如果忘记添加这个命令,插件执行命令就会失败。

Contribution Points - 官方文档
{
  "name": "hello-vscode", // 插件扩展名称,就是命令行创建定义的名字
  "displayName": "hello-vscode", 
  "description": "first vscode plugin", 
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.56.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [ // 这是很重要的,注册命令名称,在 extension.ts 中对应。
    "onCommand:hello-vscode.helloWorld"  // 命令触发名称
  ],
  "main": "./out/extension.js",
  "contributes": {
    "commands": [ // title 和 command是一个对应关系的
      {
        "command": "hello-vscode.helloWorld", //这个是对应上面那个命令触发的,在代码里面也要用到
        "title": "Hello World"  //这个是我们在vscode里面输入的命令
      }
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/glob": "^7.1.3",
    "@types/mocha": "^8.2.2",
    "@types/node": "14.x",
    "@types/vscode": "^1.56.0",
    "@typescript-eslint/eslint-plugin": "^4.26.0",
    "@typescript-eslint/parser": "^4.26.0",
    "eslint": "^7.27.0",
    "glob": "^7.1.7",
    "mocha": "^8.4.0",
    "typescript": "^4.3.2",
    "vscode-test": "^1.5.2"
  }
}

extension.ts

这个文件是插件的入口,一般包括两个函数 activate 和 deactivate。其中 activate 函数是插件激活时也就是在注册的 Activation Event 发生的时候就会执行。deactivate 中放的是插件关闭时执行的代码。

import * as vscode from 'vscode';

// 当插件被激活时,就会调用这个方法
export function activate(context: vscode.ExtensionContext) {
	
	// 控制台输出的console 信息,扩展被激活时,这行代码会被执行一次。
	console.log('Congratulations, your extension "hello-vscode" is now active!');

	// 命令是在 package.json 中进行定义
	// Now provide the implementation of the command with registerCommand
	// command 中的参数必须与 package.json 中定义的进行对应
	let disposable = vscode.commands.registerCommand('hello-vscode.helloWorld', () => {
            // 这里放置的代码每次执行命令都会弹出,如前面图中的文字。
		vscode.window.showInformationMessage('Hello World from hello-vscode!');
	});

	context.subscriptions.push(disposable);
}

// 停用扩展时将调用此方法
export function deactivate() {}

新增命令方式

修改 package.json 中的配置就行

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

然后再在 extension.ts 进行注册上述新增的命令事件。extension.sayHello

let sayHello = vscode.commands.registerCommand('extension.sayHello', () => {
    vscode.window.showInformationMessage('来呀,玩起来!!!')
  })

  context.subscriptions.push(sayHello)

最后我们继续运行,就可以看到我们的命令行。

image.png

image.png

打包与发布

我们编写完一个插件,总不能每次都要进行运行,再来使用,怎么样学插件市场里的插件一样,即装即用呢。这就需要我们发布到插件市场。

第一步先安装打包工具 vsce,将我们的代码进行打包。 vsce 是“Visual Studio Code Extensions”的缩写,是一个用于打包、发布和管理 VS Code 扩展的命令行工具。

npm install -g vsce

vsce publish

有关 vsce 的命令,可以运行 vsce --help

如果你遇到以下问题,是由于 package.json 中没有配置 publisher

image.png

发布成功后就可以去插件市场上查看

发布与扩展

上述这种发布很复杂,Visual Studio Code 将Azure DevOps用于其 Marketplace 服务。这意味着扩展的身份验证、托管和管理是通过 Azure DevOps 提供的。

vsce 只能使用 Personal Access Tokens 发布扩展。您需要至少创建一个才能发布扩展。

想继续研究这种方法,可以去官网继续研究

直接打包成 .vslx 文件

我们可以通过 vsce 来进行打包,然后上传到个人的 market 市场

vsce package

image.png 执行完以后,就可以看到我们的安装包了。

image.png

.vslx 直接上传到 marketplace

image.png

image.png 然后就可以在marketplace 上搜到刚发布的项目了,hello-vscode

image.png

image.png

总结

以上只是简单讲解了 demo 运行和发布流程,并且官方文档也讲解的很清晰,接下来我们将来扩展一个比较难点的项目。

推荐文章 VSCode插件开发入门